diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/RestTestsFromSnippetsTask.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/RestTestsFromSnippetsTask.groovy index c4201a01f26..1ce8adf1ba4 100644 --- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/RestTestsFromSnippetsTask.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/RestTestsFromSnippetsTask.groovy @@ -176,10 +176,8 @@ public class RestTestsFromSnippetsTask extends SnippetsTask { String body = matcher.group("body") String catchPart = last ? snippet.catchPart : null if (pathAndQuery.startsWith('/')) { - // Why not do some light linting while we're here? - throw new InvalidUserDataException( - "Path shouldn't start with a '/': $snippet\n" - + snippet.contents) + // Leading '/'s break the generated paths + pathAndQuery = pathAndQuery.substring(1) } emitDo(method, pathAndQuery, body, catchPart) } diff --git a/buildSrc/src/main/resources/checkstyle_suppressions.xml b/buildSrc/src/main/resources/checkstyle_suppressions.xml index 152405fcffc..bebe07612b0 100644 --- a/buildSrc/src/main/resources/checkstyle_suppressions.xml +++ b/buildSrc/src/main/resources/checkstyle_suppressions.xml @@ -21,7 +21,6 @@ - @@ -61,7 +60,6 @@ - @@ -178,21 +176,17 @@ - - - - @@ -201,10 +195,8 @@ - - @@ -216,13 +208,11 @@ - - @@ -251,7 +241,6 @@ - @@ -267,7 +256,6 @@ - @@ -375,8 +363,6 @@ - - @@ -392,21 +378,16 @@ - - - - - @@ -420,16 +401,13 @@ - - - @@ -481,9 +459,7 @@ - - @@ -500,7 +476,6 @@ - @@ -530,28 +505,21 @@ - - - - - - - @@ -569,13 +537,11 @@ - - @@ -596,20 +562,16 @@ - - - - @@ -626,7 +588,6 @@ - @@ -639,10 +600,8 @@ - - @@ -651,10 +610,7 @@ - - - @@ -665,15 +621,11 @@ - - - - @@ -691,37 +643,23 @@ - - - - - - - - - - - - - - @@ -736,10 +674,7 @@ - - - @@ -764,7 +699,6 @@ - @@ -778,7 +712,6 @@ - @@ -788,7 +721,6 @@ - @@ -805,14 +737,12 @@ - - @@ -844,7 +774,6 @@ - @@ -865,7 +794,6 @@ - @@ -932,7 +860,6 @@ - @@ -948,14 +875,11 @@ - - - @@ -1007,11 +931,8 @@ - - - @@ -1075,7 +996,6 @@ - @@ -1106,7 +1026,6 @@ - @@ -1139,7 +1058,6 @@ - @@ -1168,7 +1086,6 @@ - @@ -1280,13 +1197,11 @@ - - @@ -1326,15 +1241,12 @@ - - - @@ -1366,7 +1278,6 @@ - @@ -1399,7 +1310,6 @@ - @@ -1423,7 +1333,6 @@ - @@ -1452,7 +1361,6 @@ - diff --git a/buildSrc/version.properties b/buildSrc/version.properties index 0f6a09327d6..fee8404080a 100644 --- a/buildSrc/version.properties +++ b/buildSrc/version.properties @@ -1,4 +1,4 @@ -elasticsearch = 5.0.0-alpha2 +elasticsearch = 5.0.0 lucene = 6.0.0 # optional dependencies diff --git a/core/src/main/java/org/elasticsearch/ElasticsearchException.java b/core/src/main/java/org/elasticsearch/ElasticsearchException.java index 3332bfed0c3..b242811b7be 100644 --- a/core/src/main/java/org/elasticsearch/ElasticsearchException.java +++ b/core/src/main/java/org/elasticsearch/ElasticsearchException.java @@ -24,6 +24,7 @@ import org.elasticsearch.cluster.action.shard.ShardStateAction; import org.elasticsearch.common.Strings; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.logging.LoggerMessageFormat; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -47,7 +48,7 @@ import static org.elasticsearch.cluster.metadata.IndexMetaData.INDEX_UUID_NA_VAL /** * A base class for all elasticsearch exceptions. */ -public class ElasticsearchException extends RuntimeException implements ToXContent { +public class ElasticsearchException extends RuntimeException implements ToXContent, Writeable { public static final String REST_EXCEPTION_SKIP_CAUSE = "rest.exception.cause.skip"; public static final String REST_EXCEPTION_SKIP_STACK_TRACE = "rest.exception.stacktrace.skip"; @@ -235,6 +236,7 @@ public class ElasticsearchException extends RuntimeException implements ToXConte } } + @Override public void writeTo(StreamOutput out) throws IOException { out.writeOptionalString(this.getMessage()); out.writeThrowable(this.getCause()); diff --git a/core/src/main/java/org/elasticsearch/Version.java b/core/src/main/java/org/elasticsearch/Version.java index 56d245ddc51..0e869d06149 100644 --- a/core/src/main/java/org/elasticsearch/Version.java +++ b/core/src/main/java/org/elasticsearch/Version.java @@ -73,7 +73,9 @@ public class Version { public static final Version V_5_0_0_alpha1 = new Version(V_5_0_0_alpha1_ID, org.apache.lucene.util.Version.LUCENE_6_0_0); public static final int V_5_0_0_alpha2_ID = 5000002; public static final Version V_5_0_0_alpha2 = new Version(V_5_0_0_alpha2_ID, org.apache.lucene.util.Version.LUCENE_6_0_0); - public static final Version CURRENT = V_5_0_0_alpha2; + public static final int V_5_0_0_ID = 5000099; + public static final Version V_5_0_0 = new Version(V_5_0_0_ID, org.apache.lucene.util.Version.LUCENE_6_0_0); + public static final Version CURRENT = V_5_0_0; static { assert CURRENT.luceneVersion.equals(org.apache.lucene.util.Version.LATEST) : "Version must be upgraded to [" @@ -86,6 +88,8 @@ public class Version { public static Version fromId(int id) { switch (id) { + case V_5_0_0_ID: + return V_5_0_0; case V_5_0_0_alpha2_ID: return V_5_0_0_alpha2; case V_5_0_0_alpha1_ID: diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/node/hotthreads/NodesHotThreadsResponse.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/node/hotthreads/NodesHotThreadsResponse.java index 22d4795fc95..3136f2b6826 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/node/hotthreads/NodesHotThreadsResponse.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/node/hotthreads/NodesHotThreadsResponse.java @@ -19,12 +19,14 @@ package org.elasticsearch.action.admin.cluster.node.hotthreads; +import org.elasticsearch.action.FailedNodeException; import org.elasticsearch.action.support.nodes.BaseNodesResponse; import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import java.io.IOException; +import java.util.List; /** */ @@ -33,26 +35,18 @@ public class NodesHotThreadsResponse extends BaseNodesResponse { NodesHotThreadsResponse() { } - public NodesHotThreadsResponse(ClusterName clusterName, NodeHotThreads[] nodes) { - super(clusterName, nodes); + public NodesHotThreadsResponse(ClusterName clusterName, List nodes, List failures) { + super(clusterName, nodes, failures); } @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - nodes = new NodeHotThreads[in.readVInt()]; - for (int i = 0; i < nodes.length; i++) { - nodes[i] = NodeHotThreads.readNodeHotThreads(in); - } + protected List readNodesFrom(StreamInput in) throws IOException { + return in.readList(NodeHotThreads::readNodeHotThreads); } @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeVInt(nodes.length); - for (NodeHotThreads node : nodes) { - node.writeTo(out); - } + protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { + out.writeStreamableList(nodes); } } diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/node/hotthreads/TransportNodesHotThreadsAction.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/node/hotthreads/TransportNodesHotThreadsAction.java index d53f651da45..7198851fd28 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/node/hotthreads/TransportNodesHotThreadsAction.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/node/hotthreads/TransportNodesHotThreadsAction.java @@ -20,6 +20,7 @@ package org.elasticsearch.action.admin.cluster.node.hotthreads; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.action.FailedNodeException; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.nodes.BaseNodeRequest; import org.elasticsearch.action.support.nodes.TransportNodesAction; @@ -35,33 +36,28 @@ import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import java.io.IOException; -import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicReferenceArray; /** * */ -public class TransportNodesHotThreadsAction extends TransportNodesAction { +public class TransportNodesHotThreadsAction extends TransportNodesAction { @Inject public TransportNodesHotThreadsAction(Settings settings, ClusterName clusterName, ThreadPool threadPool, ClusterService clusterService, TransportService transportService, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) { super(settings, NodesHotThreadsAction.NAME, clusterName, threadPool, clusterService, transportService, actionFilters, - indexNameExpressionResolver, NodesHotThreadsRequest::new, NodeRequest::new, ThreadPool.Names.GENERIC); + indexNameExpressionResolver, NodesHotThreadsRequest::new, NodeRequest::new, ThreadPool.Names.GENERIC, NodeHotThreads.class); } @Override - protected NodesHotThreadsResponse newResponse(NodesHotThreadsRequest request, AtomicReferenceArray responses) { - final List nodes = new ArrayList<>(); - for (int i = 0; i < responses.length(); i++) { - Object resp = responses.get(i); - if (resp instanceof NodeHotThreads) { - nodes.add((NodeHotThreads) resp); - } - } - return new NodesHotThreadsResponse(clusterName, nodes.toArray(new NodeHotThreads[nodes.size()])); + protected NodesHotThreadsResponse newResponse(NodesHotThreadsRequest request, + List responses, List failures) { + return new NodesHotThreadsResponse(clusterName, responses, failures); } @Override diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/node/info/NodesInfoResponse.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/node/info/NodesInfoResponse.java index fdb15db8ffc..d5a43eb030e 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/node/info/NodesInfoResponse.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/node/info/NodesInfoResponse.java @@ -19,6 +19,7 @@ package org.elasticsearch.action.admin.cluster.node.info; +import org.elasticsearch.action.FailedNodeException; import org.elasticsearch.action.support.nodes.BaseNodesResponse; import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.node.DiscoveryNode; @@ -30,6 +31,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import java.io.IOException; +import java.util.List; import java.util.Map; /** @@ -40,34 +42,24 @@ public class NodesInfoResponse extends BaseNodesResponse implements To public NodesInfoResponse() { } - public NodesInfoResponse(ClusterName clusterName, NodeInfo[] nodes) { - super(clusterName, nodes); + public NodesInfoResponse(ClusterName clusterName, List nodes, List failures) { + super(clusterName, nodes, failures); } @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - nodes = new NodeInfo[in.readVInt()]; - for (int i = 0; i < nodes.length; i++) { - nodes[i] = NodeInfo.readNodeInfo(in); - } + protected List readNodesFrom(StreamInput in) throws IOException { + return in.readList(NodeInfo::readNodeInfo); } @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeVInt(nodes.length); - for (NodeInfo node : nodes) { - node.writeTo(out); - } + protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { + out.writeStreamableList(nodes); } @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.field("cluster_name", getClusterName().value()); - builder.startObject("nodes"); - for (NodeInfo nodeInfo : this) { + for (NodeInfo nodeInfo : getNodes()) { builder.startObject(nodeInfo.getNode().getId()); builder.field("name", nodeInfo.getNode().getName()); diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/node/info/TransportNodesInfoAction.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/node/info/TransportNodesInfoAction.java index f52729faa4f..f68e2d65903 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/node/info/TransportNodesInfoAction.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/node/info/TransportNodesInfoAction.java @@ -19,6 +19,7 @@ package org.elasticsearch.action.admin.cluster.node.info; +import org.elasticsearch.action.FailedNodeException; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.nodes.BaseNodeRequest; import org.elasticsearch.action.support.nodes.TransportNodesAction; @@ -34,36 +35,32 @@ import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import java.io.IOException; -import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicReferenceArray; /** * */ -public class TransportNodesInfoAction extends TransportNodesAction { +public class TransportNodesInfoAction extends TransportNodesAction { private final NodeService nodeService; @Inject public TransportNodesInfoAction(Settings settings, ClusterName clusterName, ThreadPool threadPool, ClusterService clusterService, TransportService transportService, - NodeService nodeService, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) { + NodeService nodeService, ActionFilters actionFilters, + IndexNameExpressionResolver indexNameExpressionResolver) { super(settings, NodesInfoAction.NAME, clusterName, threadPool, clusterService, transportService, actionFilters, - indexNameExpressionResolver, NodesInfoRequest::new, NodeInfoRequest::new, ThreadPool.Names.MANAGEMENT); + indexNameExpressionResolver, NodesInfoRequest::new, NodeInfoRequest::new, ThreadPool.Names.MANAGEMENT, NodeInfo.class); this.nodeService = nodeService; } @Override - protected NodesInfoResponse newResponse(NodesInfoRequest nodesInfoRequest, AtomicReferenceArray responses) { - final List nodesInfos = new ArrayList<>(); - for (int i = 0; i < responses.length(); i++) { - Object resp = responses.get(i); - if (resp instanceof NodeInfo) { - nodesInfos.add((NodeInfo) resp); - } - } - return new NodesInfoResponse(clusterName, nodesInfos.toArray(new NodeInfo[nodesInfos.size()])); + protected NodesInfoResponse newResponse(NodesInfoRequest nodesInfoRequest, + List responses, List failures) { + return new NodesInfoResponse(clusterName, responses, failures); } @Override diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/NodesStatsResponse.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/NodesStatsResponse.java index af28c1fb5d5..1a9023ab93c 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/NodesStatsResponse.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/NodesStatsResponse.java @@ -19,6 +19,7 @@ package org.elasticsearch.action.admin.cluster.node.stats; +import org.elasticsearch.action.FailedNodeException; import org.elasticsearch.action.support.nodes.BaseNodesResponse; import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.common.io.stream.StreamInput; @@ -28,6 +29,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import java.io.IOException; +import java.util.List; /** * @@ -37,34 +39,24 @@ public class NodesStatsResponse extends BaseNodesResponse implements NodesStatsResponse() { } - public NodesStatsResponse(ClusterName clusterName, NodeStats[] nodes) { - super(clusterName, nodes); + public NodesStatsResponse(ClusterName clusterName, List nodes, List failures) { + super(clusterName, nodes, failures); } @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - nodes = new NodeStats[in.readVInt()]; - for (int i = 0; i < nodes.length; i++) { - nodes[i] = NodeStats.readNodeStats(in); - } + protected List readNodesFrom(StreamInput in) throws IOException { + return in.readList(NodeStats::readNodeStats); } @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeVInt(nodes.length); - for (NodeStats node : nodes) { - node.writeTo(out); - } + protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { + out.writeStreamableList(nodes); } @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.field("cluster_name", getClusterName().value()); - builder.startObject("nodes"); - for (NodeStats nodeStats : this) { + for (NodeStats nodeStats : getNodes()) { builder.startObject(nodeStats.getNode().getId()); builder.field("timestamp", nodeStats.getTimestamp()); nodeStats.toXContent(builder, params); diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/TransportNodesStatsAction.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/TransportNodesStatsAction.java index 8ba3d00558b..d61e3f1acce 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/TransportNodesStatsAction.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/TransportNodesStatsAction.java @@ -19,6 +19,7 @@ package org.elasticsearch.action.admin.cluster.node.stats; +import org.elasticsearch.action.FailedNodeException; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.nodes.BaseNodeRequest; import org.elasticsearch.action.support.nodes.TransportNodesAction; @@ -34,36 +35,31 @@ import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import java.io.IOException; -import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicReferenceArray; /** * */ -public class TransportNodesStatsAction extends TransportNodesAction { +public class TransportNodesStatsAction extends TransportNodesAction { private final NodeService nodeService; @Inject public TransportNodesStatsAction(Settings settings, ClusterName clusterName, ThreadPool threadPool, ClusterService clusterService, TransportService transportService, - NodeService nodeService, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) { - super(settings, NodesStatsAction.NAME, clusterName, threadPool, clusterService, transportService, actionFilters, indexNameExpressionResolver, - NodesStatsRequest::new, NodeStatsRequest::new, ThreadPool.Names.MANAGEMENT); + NodeService nodeService, ActionFilters actionFilters, + IndexNameExpressionResolver indexNameExpressionResolver) { + super(settings, NodesStatsAction.NAME, clusterName, threadPool, clusterService, transportService, actionFilters, + indexNameExpressionResolver, NodesStatsRequest::new, NodeStatsRequest::new, ThreadPool.Names.MANAGEMENT, NodeStats.class); this.nodeService = nodeService; } @Override - protected NodesStatsResponse newResponse(NodesStatsRequest nodesInfoRequest, AtomicReferenceArray responses) { - final List nodeStats = new ArrayList<>(); - for (int i = 0; i < responses.length(); i++) { - Object resp = responses.get(i); - if (resp instanceof NodeStats) { - nodeStats.add((NodeStats) resp); - } - } - return new NodesStatsResponse(clusterName, nodeStats.toArray(new NodeStats[nodeStats.size()])); + protected NodesStatsResponse newResponse(NodesStatsRequest request, List responses, List failures) { + return new NodesStatsResponse(clusterName, responses, failures); } @Override diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java index 0be07c703f1..0a7a8a9ce80 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java @@ -57,13 +57,13 @@ public class CreateSnapshotResponse extends ActionResponse implements ToXContent @Override public void readFrom(StreamInput in) throws IOException { super.readFrom(in); - snapshotInfo = SnapshotInfo.readOptionalSnapshotInfo(in); + snapshotInfo = in.readOptionalWriteable(SnapshotInfo::new); } @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); - out.writeOptionalStreamable(snapshotInfo); + out.writeOptionalWriteable(snapshotInfo); } /** @@ -90,7 +90,7 @@ public class CreateSnapshotResponse extends ActionResponse implements ToXContent public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { if (snapshotInfo != null) { builder.field(Fields.SNAPSHOT); - snapshotInfo.toXContent(builder, params); + snapshotInfo.toExternalXContent(builder, params); } else { builder.field(Fields.ACCEPTED, true); } diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsResponse.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsResponse.java index 65b0e4faa4a..a5db19684b2 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsResponse.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsResponse.java @@ -60,7 +60,7 @@ public class GetSnapshotsResponse extends ActionResponse implements ToXContent { int size = in.readVInt(); List builder = new ArrayList<>(); for (int i = 0; i < size; i++) { - builder.add(SnapshotInfo.readSnapshotInfo(in)); + builder.add(new SnapshotInfo(in)); } snapshots = Collections.unmodifiableList(builder); } @@ -82,7 +82,7 @@ public class GetSnapshotsResponse extends ActionResponse implements ToXContent { public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException { builder.startArray(Fields.SNAPSHOTS); for (SnapshotInfo snapshotInfo : snapshots) { - snapshotInfo.toXContent(builder, params); + snapshotInfo.toExternalXContent(builder, params); } builder.endArray(); return builder; diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/TransportGetSnapshotsAction.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/TransportGetSnapshotsAction.java index 0198102a200..833b1a62289 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/TransportGetSnapshotsAction.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/TransportGetSnapshotsAction.java @@ -31,7 +31,6 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.snapshots.Snapshot; import org.elasticsearch.snapshots.SnapshotInfo; import org.elasticsearch.snapshots.SnapshotsService; import org.elasticsearch.threadpool.ThreadPool; @@ -77,18 +76,12 @@ public class TransportGetSnapshotsAction extends TransportMasterNodeAction snapshotInfoBuilder = new ArrayList<>(); if (isAllSnapshots(request.snapshots())) { - List snapshots = snapshotsService.snapshots(request.repository(), request.ignoreUnavailable()); - for (Snapshot snapshot : snapshots) { - snapshotInfoBuilder.add(new SnapshotInfo(snapshot)); - } + snapshotInfoBuilder.addAll(snapshotsService.snapshots(request.repository(), request.ignoreUnavailable())); } else if (isCurrentSnapshots(request.snapshots())) { - List snapshots = snapshotsService.currentSnapshots(request.repository()); - for (Snapshot snapshot : snapshots) { - snapshotInfoBuilder.add(new SnapshotInfo(snapshot)); - } + snapshotInfoBuilder.addAll(snapshotsService.currentSnapshots(request.repository())); } else { Set snapshotsToGet = new LinkedHashSet<>(); // to keep insertion order - List snapshots = null; + List snapshots = null; for (String snapshotOrPattern : request.snapshots()) { if (Regex.isSimpleMatchPattern(snapshotOrPattern) == false) { snapshotsToGet.add(snapshotOrPattern); @@ -96,7 +89,7 @@ public class TransportGetSnapshotsAction extends TransportMasterNodeAction { +public class TransportNodesSnapshotsStatus extends TransportNodesAction { public static final String ACTION_NAME = SnapshotsStatusAction.NAME + "[nodes]"; @@ -66,7 +68,7 @@ public class TransportNodesSnapshotsStatus extends TransportNodesAction nodesList = new ArrayList<>(); - final List failures = new ArrayList<>(); - for (int i = 0; i < responses.length(); i++) { - Object resp = responses.get(i); - if (resp instanceof NodeSnapshotStatus) { // will also filter out null response for unallocated ones - nodesList.add((NodeSnapshotStatus) resp); - } else if (resp instanceof FailedNodeException) { - failures.add((FailedNodeException) resp); - } else { - logger.warn("unknown response type [{}], expected NodeSnapshotStatus or FailedNodeException", resp); - } - } - return new NodesSnapshotStatus(clusterName, nodesList.toArray(new NodeSnapshotStatus[nodesList.size()]), - failures.toArray(new FailedNodeException[failures.size()])); + protected NodesSnapshotStatus newResponse(Request request, List responses, List failures) { + return new NodesSnapshotStatus(clusterName, responses, failures); } @Override @@ -169,75 +158,47 @@ public class TransportNodesSnapshotsStatus extends TransportNodesAction { - private FailedNodeException[] failures; - NodesSnapshotStatus() { } - public NodesSnapshotStatus(ClusterName clusterName, NodeSnapshotStatus[] nodes, FailedNodeException[] failures) { - super(clusterName, nodes); - this.failures = failures; + public NodesSnapshotStatus(ClusterName clusterName, List nodes, List failures) { + super(clusterName, nodes, failures); } @Override - public FailedNodeException[] failures() { - return failures; + protected List readNodesFrom(StreamInput in) throws IOException { + return in.readStreamableList(NodeSnapshotStatus::new); } @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - nodes = new NodeSnapshotStatus[in.readVInt()]; - for (int i = 0; i < nodes.length; i++) { - nodes[i] = new NodeSnapshotStatus(); - nodes[i].readFrom(in); - } - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeVInt(nodes.length); - for (NodeSnapshotStatus response : nodes) { - response.writeTo(out); - } + protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { + out.writeStreamableList(nodes); } } public static class NodeRequest extends BaseNodeRequest { - private SnapshotId[] snapshotIds; + private List snapshotIds; public NodeRequest() { } NodeRequest(String nodeId, TransportNodesSnapshotsStatus.Request request) { super(nodeId); - snapshotIds = request.snapshotIds; + snapshotIds = Arrays.asList(request.snapshotIds); } @Override public void readFrom(StreamInput in) throws IOException { super.readFrom(in); - int n = in.readVInt(); - snapshotIds = new SnapshotId[n]; - for (int i = 0; i < n; i++) { - snapshotIds[i] = SnapshotId.readSnapshotId(in); - } + snapshotIds = in.readList(SnapshotId::readSnapshotId); } @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); - if (snapshotIds != null) { - out.writeVInt(snapshotIds.length); - for (int i = 0; i < snapshotIds.length; i++) { - snapshotIds[i].writeTo(out); - } - } else { - out.writeVInt(0); - } + out.writeStreamableList(snapshotIds); } } diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/status/TransportSnapshotsStatusAction.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/status/TransportSnapshotsStatusAction.java index efa156eaa0c..ee60a919da6 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/status/TransportSnapshotsStatusAction.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/status/TransportSnapshotsStatusAction.java @@ -36,7 +36,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.index.snapshots.IndexShardSnapshotStatus; -import org.elasticsearch.snapshots.Snapshot; +import org.elasticsearch.snapshots.SnapshotInfo; import org.elasticsearch.snapshots.SnapshotsService; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; @@ -202,7 +202,7 @@ public class TransportSnapshotsStatusAction extends TransportMasterNodeAction shardStatusBuilder = new ArrayList<>(); if (snapshot.state().completed()) { Map shardStatues = snapshotsService.snapshotShards(snapshotId); diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsIndices.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsIndices.java index b23b6467288..8c0c427beea 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsIndices.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsIndices.java @@ -22,9 +22,6 @@ package org.elasticsearch.action.admin.cluster.stats; import com.carrotsearch.hppc.ObjectObjectHashMap; import com.carrotsearch.hppc.cursors.ObjectObjectCursor; import org.elasticsearch.action.admin.indices.stats.CommonStats; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Streamable; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.index.cache.query.QueryCacheStats; @@ -36,8 +33,9 @@ import org.elasticsearch.index.store.StoreStats; import org.elasticsearch.search.suggest.completion.CompletionStats; import java.io.IOException; +import java.util.List; -public class ClusterStatsIndices implements ToXContent, Streamable { +public class ClusterStatsIndices implements ToXContent { private int indexCount; private ShardStats shards; @@ -49,10 +47,7 @@ public class ClusterStatsIndices implements ToXContent, Streamable { private SegmentsStats segments; private PercolatorQueryCacheStats percolatorCache; - private ClusterStatsIndices() { - } - - public ClusterStatsIndices(ClusterStatsNodeResponse[] nodeResponses) { + public ClusterStatsIndices(List nodeResponses) { ObjectObjectHashMap countsPerIndex = new ObjectObjectHashMap<>(); this.docs = new DocsStats(); @@ -131,38 +126,6 @@ public class ClusterStatsIndices implements ToXContent, Streamable { return percolatorCache; } - @Override - public void readFrom(StreamInput in) throws IOException { - indexCount = in.readVInt(); - shards = ShardStats.readShardStats(in); - docs = DocsStats.readDocStats(in); - store = StoreStats.readStoreStats(in); - fieldData = FieldDataStats.readFieldDataStats(in); - queryCache = QueryCacheStats.readQueryCacheStats(in); - completion = CompletionStats.readCompletionStats(in); - segments = SegmentsStats.readSegmentsStats(in); - percolatorCache = PercolatorQueryCacheStats.readPercolateStats(in); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeVInt(indexCount); - shards.writeTo(out); - docs.writeTo(out); - store.writeTo(out); - fieldData.writeTo(out); - queryCache.writeTo(out); - completion.writeTo(out); - segments.writeTo(out); - percolatorCache.writeTo(out); - } - - public static ClusterStatsIndices readIndicesStats(StreamInput in) throws IOException { - ClusterStatsIndices indicesStats = new ClusterStatsIndices(); - indicesStats.readFrom(in); - return indicesStats; - } - static final class Fields { static final String COUNT = "count"; } @@ -181,7 +144,7 @@ public class ClusterStatsIndices implements ToXContent, Streamable { return builder; } - public static class ShardStats implements ToXContent, Streamable { + public static class ShardStats implements ToXContent { int indices; int total; @@ -326,40 +289,6 @@ public class ClusterStatsIndices implements ToXContent, Streamable { } } - public static ShardStats readShardStats(StreamInput in) throws IOException { - ShardStats c = new ShardStats(); - c.readFrom(in); - return c; - } - - @Override - public void readFrom(StreamInput in) throws IOException { - indices = in.readVInt(); - total = in.readVInt(); - primaries = in.readVInt(); - minIndexShards = in.readVInt(); - maxIndexShards = in.readVInt(); - minIndexPrimaryShards = in.readVInt(); - maxIndexPrimaryShards = in.readVInt(); - minIndexReplication = in.readDouble(); - totalIndexReplication = in.readDouble(); - maxIndexReplication = in.readDouble(); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeVInt(indices); - out.writeVInt(total); - out.writeVInt(primaries); - out.writeVInt(minIndexShards); - out.writeVInt(maxIndexShards); - out.writeVInt(minIndexPrimaryShards); - out.writeVInt(maxIndexPrimaryShards); - out.writeDouble(minIndexReplication); - out.writeDouble(totalIndexReplication); - out.writeDouble(maxIndexReplication); - } - static final class Fields { static final String SHARDS = "shards"; static final String TOTAL = "total"; diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsNodes.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsNodes.java index 05b7753ef3a..017b4481240 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsNodes.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsNodes.java @@ -26,9 +26,6 @@ import org.elasticsearch.Version; import org.elasticsearch.action.admin.cluster.node.info.NodeInfo; import org.elasticsearch.action.admin.cluster.node.stats.NodeStats; import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.common.unit.ByteSizeValue; @@ -48,7 +45,7 @@ import java.util.List; import java.util.Map; import java.util.Set; -public class ClusterStatsNodes implements ToXContent, Writeable { +public class ClusterStatsNodes implements ToXContent { private final Counts counts; private final Set versions; @@ -58,33 +55,12 @@ public class ClusterStatsNodes implements ToXContent, Writeable { private final FsInfo.Path fs; private final Set plugins; - ClusterStatsNodes(StreamInput in) throws IOException { - this.counts = new Counts(in); - - int size = in.readVInt(); - this.versions = new HashSet<>(size); - for (int i = 0; i < size; i++) { - this.versions.add(Version.readVersion(in)); - } - - this.os = new OsStats(in); - this.process = new ProcessStats(in); - this.jvm = new JvmStats(in); - this.fs = new FsInfo.Path(in); - - size = in.readVInt(); - this.plugins = new HashSet<>(size); - for (int i = 0; i < size; i++) { - this.plugins.add(PluginInfo.readFromStream(in)); - } - } - - ClusterStatsNodes(ClusterStatsNodeResponse[] nodeResponses) { + ClusterStatsNodes(List nodeResponses) { this.versions = new HashSet<>(); this.fs = new FsInfo.Path(); this.plugins = new HashSet<>(); - Set seenAddresses = new HashSet<>(nodeResponses.length); + Set seenAddresses = new HashSet<>(nodeResponses.size()); List nodeInfos = new ArrayList<>(); List nodeStats = new ArrayList<>(); for (ClusterStatsNodeResponse nodeResponse : nodeResponses) { @@ -140,21 +116,6 @@ public class ClusterStatsNodes implements ToXContent, Writeable { return plugins; } - @Override - public void writeTo(StreamOutput out) throws IOException { - counts.writeTo(out); - out.writeVInt(versions.size()); - for (Version v : versions) Version.writeVersion(v, out); - os.writeTo(out); - process.writeTo(out); - jvm.writeTo(out); - fs.writeTo(out); - out.writeVInt(plugins.size()); - for (PluginInfo p : plugins) { - p.writeTo(out); - } - } - static final class Fields { static final String COUNT = "count"; static final String VERSIONS = "versions"; @@ -200,18 +161,12 @@ public class ClusterStatsNodes implements ToXContent, Writeable { return builder; } - public static class Counts implements Writeable, ToXContent { + public static class Counts implements ToXContent { static final String COORDINATING_ONLY = "coordinating_only"; private final int total; private final Map roles; - @SuppressWarnings("unchecked") - private Counts(StreamInput in) throws IOException { - this.total = in.readVInt(); - this.roles = (Map)in.readGenericValue(); - } - private Counts(List nodeInfos) { this.roles = new HashMap<>(); for (DiscoveryNode.Role role : DiscoveryNode.Role.values()) { @@ -243,12 +198,6 @@ public class ClusterStatsNodes implements ToXContent, Writeable { return roles; } - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeVInt(total); - out.writeGenericValue(roles); - } - static final class Fields { static final String TOTAL = "total"; } @@ -263,7 +212,7 @@ public class ClusterStatsNodes implements ToXContent, Writeable { } } - public static class OsStats implements ToXContent, Writeable { + public static class OsStats implements ToXContent { final int availableProcessors; final int allocatedProcessors; final ObjectIntHashMap names; @@ -287,30 +236,6 @@ public class ClusterStatsNodes implements ToXContent, Writeable { this.allocatedProcessors = allocatedProcessors; } - /** - * Read from a stream. - */ - private OsStats(StreamInput in) throws IOException { - this.availableProcessors = in.readVInt(); - this.allocatedProcessors = in.readVInt(); - int size = in.readVInt(); - this.names = new ObjectIntHashMap<>(); - for (int i = 0; i < size; i++) { - names.addTo(in.readString(), in.readVInt()); - } - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeVInt(availableProcessors); - out.writeVInt(allocatedProcessors); - out.writeVInt(names.size()); - for (ObjectIntCursor name : names) { - out.writeString(name.key); - out.writeVInt(name.value); - } - } - public int getAvailableProcessors() { return availableProcessors; } @@ -343,7 +268,7 @@ public class ClusterStatsNodes implements ToXContent, Writeable { } } - public static class ProcessStats implements ToXContent, Writeable { + public static class ProcessStats implements ToXContent { final int count; final int cpuPercent; @@ -384,27 +309,6 @@ public class ClusterStatsNodes implements ToXContent, Writeable { this.maxOpenFileDescriptors = maxOpenFileDescriptors; } - /** - * Read from a stream. - */ - private ProcessStats(StreamInput in) throws IOException { - this.count = in.readVInt(); - this.cpuPercent = in.readVInt(); - this.totalOpenFileDescriptors = in.readVLong(); - this.minOpenFileDescriptors = in.readLong(); - this.maxOpenFileDescriptors = in.readLong(); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeVInt(count); - out.writeVInt(cpuPercent); - out.writeVLong(totalOpenFileDescriptors); - out.writeLong(minOpenFileDescriptors); - out.writeLong(maxOpenFileDescriptors); - } - - /** * Cpu usage in percentages - 100 is 1 core. */ @@ -456,7 +360,7 @@ public class ClusterStatsNodes implements ToXContent, Writeable { } } - public static class JvmStats implements Writeable, ToXContent { + public static class JvmStats implements ToXContent { private final ObjectIntHashMap versions; private final long threads; @@ -497,34 +401,6 @@ public class ClusterStatsNodes implements ToXContent, Writeable { this.heapMax = heapMax; } - /** - * Read from a stream. - */ - private JvmStats(StreamInput in) throws IOException { - int size = in.readVInt(); - this.versions = new ObjectIntHashMap<>(size); - for (int i = 0; i < size; i++) { - this.versions.addTo(new JvmVersion(in), in.readVInt()); - } - this.threads = in.readVLong(); - this.maxUptime = in.readVLong(); - this.heapUsed = in.readVLong(); - this.heapMax = in.readVLong(); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeVInt(versions.size()); - for (ObjectIntCursor v : versions) { - v.key.writeTo(out); - out.writeVInt(v.value); - } - out.writeVLong(threads); - out.writeVLong(maxUptime); - out.writeVLong(heapUsed); - out.writeVLong(heapMax); - } - public ObjectIntHashMap getVersions() { return versions; } @@ -598,7 +474,7 @@ public class ClusterStatsNodes implements ToXContent, Writeable { } } - public static class JvmVersion implements Writeable { + public static class JvmVersion { String version; String vmName; String vmVersion; @@ -611,27 +487,6 @@ public class ClusterStatsNodes implements ToXContent, Writeable { vmVendor = jvmInfo.getVmVendor(); } - /** - * Read from a stream. - */ - JvmVersion(StreamInput in) throws IOException { - version = in.readString(); - vmName = in.readString(); - vmVersion = in.readString(); - vmVendor = in.readString(); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeString(version); - out.writeString(vmName); - out.writeString(vmVersion); - out.writeString(vmVendor); - } - - JvmVersion() { - } - @Override public boolean equals(Object o) { if (this == o) { diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsResponse.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsResponse.java index c272e6d6fbe..efc72d104f8 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsResponse.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsResponse.java @@ -19,6 +19,7 @@ package org.elasticsearch.action.admin.cluster.stats; +import org.elasticsearch.action.FailedNodeException; import org.elasticsearch.action.support.nodes.BaseNodesResponse; import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.health.ClusterHealthStatus; @@ -29,9 +30,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import java.io.IOException; -import java.util.Iterator; +import java.util.List; import java.util.Locale; -import java.util.Map; /** * @@ -48,8 +48,9 @@ public class ClusterStatsResponse extends BaseNodesResponse nodes, List failures) { + super(clusterName, nodes, failures); this.timestamp = timestamp; this.clusterUUID = clusterUUID; nodesStats = new ClusterStatsNodes(nodes); @@ -79,77 +80,53 @@ public class ClusterStatsResponse extends BaseNodesResponse getNodesMap() { - throw new UnsupportedOperationException(); - } - - @Override - public ClusterStatsNodeResponse getAt(int position) { - throw new UnsupportedOperationException(); - } - - @Override - public Iterator iterator() { - throw new UnsupportedOperationException(); - } - @Override public void readFrom(StreamInput in) throws IOException { super.readFrom(in); timestamp = in.readVLong(); - status = null; - if (in.readBoolean()) { - // it may be that the master switched on us while doing the operation. In this case the status may be null. - status = ClusterHealthStatus.fromValue(in.readByte()); - } clusterUUID = in.readString(); - nodesStats = new ClusterStatsNodes(in); - indicesStats = ClusterStatsIndices.readIndicesStats(in); + // it may be that the master switched on us while doing the operation. In this case the status may be null. + status = in.readOptionalWriteable(ClusterHealthStatus::readFrom); } @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); out.writeVLong(timestamp); - if (status == null) { - out.writeBoolean(false); - } else { - out.writeBoolean(true); - out.writeByte(status.value()); - } out.writeString(clusterUUID); - nodesStats.writeTo(out); - indicesStats.writeTo(out); + out.writeOptionalWriteable(status); } - static final class Fields { - static final String NODES = "nodes"; - static final String INDICES = "indices"; - static final String UUID = "uuid"; - static final String CLUSTER_NAME = "cluster_name"; - static final String STATUS = "status"; + @Override + protected List readNodesFrom(StreamInput in) throws IOException { + List nodes = in.readList(ClusterStatsNodeResponse::readNodeResponse); + + // built from nodes rather than from the stream directly + nodesStats = new ClusterStatsNodes(nodes); + indicesStats = new ClusterStatsIndices(nodes); + + return nodes; + } + + @Override + protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { + // nodeStats and indicesStats are rebuilt from nodes + out.writeStreamableList(nodes); } @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.field("timestamp", getTimestamp()); - builder.field(Fields.CLUSTER_NAME, getClusterName().value()); if (params.paramAsBoolean("output_uuid", false)) { - builder.field(Fields.UUID, clusterUUID); + builder.field("uuid", clusterUUID); } if (status != null) { - builder.field(Fields.STATUS, status.name().toLowerCase(Locale.ROOT)); + builder.field("status", status.name().toLowerCase(Locale.ROOT)); } - builder.startObject(Fields.INDICES); + builder.startObject("indices"); indicesStats.toXContent(builder, params); builder.endObject(); - builder.startObject(Fields.NODES); + builder.startObject("nodes"); nodesStats.toXContent(builder, params); builder.endObject(); return builder; diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/TransportClusterStatsAction.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/TransportClusterStatsAction.java index 4a0eb33c0b5..bae7b20694d 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/TransportClusterStatsAction.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/TransportClusterStatsAction.java @@ -19,6 +19,7 @@ package org.elasticsearch.action.admin.cluster.stats; +import org.elasticsearch.action.FailedNodeException; import org.elasticsearch.action.admin.cluster.node.info.NodeInfo; import org.elasticsearch.action.admin.cluster.node.stats.NodeStats; import org.elasticsearch.action.admin.indices.stats.CommonStats; @@ -46,7 +47,6 @@ import org.elasticsearch.transport.TransportService; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicReferenceArray; /** * @@ -68,22 +68,17 @@ public class TransportClusterStatsAction extends TransportNodesAction nodeStats = new ArrayList<>(responses.length()); - for (int i = 0; i < responses.length(); i++) { - Object resp = responses.get(i); - if (resp instanceof ClusterStatsNodeResponse) { - nodeStats.add((ClusterStatsNodeResponse) resp); - } - } - return new ClusterStatsResponse(System.currentTimeMillis(), clusterName, - clusterService.state().metaData().clusterUUID(), nodeStats.toArray(new ClusterStatsNodeResponse[nodeStats.size()])); + protected ClusterStatsResponse newResponse(ClusterStatsRequest request, + List responses, List failures) { + return new ClusterStatsResponse(System.currentTimeMillis(), clusterName, clusterService.state().metaData().clusterUUID(), + responses, failures); } @Override diff --git a/core/src/main/java/org/elasticsearch/action/admin/indices/shards/TransportIndicesShardStoresAction.java b/core/src/main/java/org/elasticsearch/action/admin/indices/shards/TransportIndicesShardStoresAction.java index 5dbac12f694..250e4123bba 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/indices/shards/TransportIndicesShardStoresAction.java +++ b/core/src/main/java/org/elasticsearch/action/admin/indices/shards/TransportIndicesShardStoresAction.java @@ -53,6 +53,7 @@ import org.elasticsearch.transport.TransportService; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Queue; import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; @@ -152,7 +153,7 @@ public class TransportIndicesShardStoresAction extends TransportMasterNodeReadAc } @Override - protected synchronized void processAsyncFetch(ShardId shardId, NodeGatewayStartedShards[] responses, FailedNodeException[] failures) { + protected synchronized void processAsyncFetch(ShardId shardId, List responses, List failures) { fetchResponses.add(new Response(shardId, responses, failures)); if (expectedOps.countDown()) { finish(); @@ -220,10 +221,10 @@ public class TransportIndicesShardStoresAction extends TransportMasterNodeReadAc public class Response { private final ShardId shardId; - private final NodeGatewayStartedShards[] responses; - private final FailedNodeException[] failures; + private final List responses; + private final List failures; - public Response(ShardId shardId, NodeGatewayStartedShards[] responses, FailedNodeException[] failures) { + public Response(ShardId shardId, List responses, List failures) { this.shardId = shardId; this.responses = responses; this.failures = failures; diff --git a/core/src/main/java/org/elasticsearch/action/admin/indices/validate/query/ShardValidateQueryRequest.java b/core/src/main/java/org/elasticsearch/action/admin/indices/validate/query/ShardValidateQueryRequest.java index 0aec5777974..831ef6e1060 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/indices/validate/query/ShardValidateQueryRequest.java +++ b/core/src/main/java/org/elasticsearch/action/admin/indices/validate/query/ShardValidateQueryRequest.java @@ -34,7 +34,7 @@ import java.io.IOException; */ public class ShardValidateQueryRequest extends BroadcastShardRequest { - private QueryBuilder query; + private QueryBuilder query; private String[] types = Strings.EMPTY_ARRAY; private boolean explain; private boolean rewrite; @@ -57,7 +57,7 @@ public class ShardValidateQueryRequest extends BroadcastShardRequest { this.nowInMillis = request.nowInMillis; } - public QueryBuilder query() { + public QueryBuilder query() { return query; } diff --git a/core/src/main/java/org/elasticsearch/action/admin/indices/validate/query/ValidateQueryRequest.java b/core/src/main/java/org/elasticsearch/action/admin/indices/validate/query/ValidateQueryRequest.java index 603da6bfe9d..41ef37ad621 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/indices/validate/query/ValidateQueryRequest.java +++ b/core/src/main/java/org/elasticsearch/action/admin/indices/validate/query/ValidateQueryRequest.java @@ -39,7 +39,7 @@ import java.util.Arrays; */ public class ValidateQueryRequest extends BroadcastRequest { - private QueryBuilder query = new MatchAllQueryBuilder(); + private QueryBuilder query = new MatchAllQueryBuilder(); private boolean explain; private boolean rewrite; @@ -73,11 +73,11 @@ public class ValidateQueryRequest extends BroadcastRequest /** * The query to validate. */ - public QueryBuilder query() { + public QueryBuilder query() { return query; } - public ValidateQueryRequest query(QueryBuilder query) { + public ValidateQueryRequest query(QueryBuilder query) { this.query = query; return this; } diff --git a/core/src/main/java/org/elasticsearch/action/explain/ExplainRequest.java b/core/src/main/java/org/elasticsearch/action/explain/ExplainRequest.java index 6e1b6e82730..611d57345ba 100644 --- a/core/src/main/java/org/elasticsearch/action/explain/ExplainRequest.java +++ b/core/src/main/java/org/elasticsearch/action/explain/ExplainRequest.java @@ -39,7 +39,7 @@ public class ExplainRequest extends SingleShardRequest { private String id; private String routing; private String preference; - private QueryBuilder query; + private QueryBuilder query; private String[] fields; private FetchSourceContext fetchSourceContext; @@ -100,11 +100,11 @@ public class ExplainRequest extends SingleShardRequest { return this; } - public QueryBuilder query() { + public QueryBuilder query() { return query; } - public ExplainRequest query(QueryBuilder query) { + public ExplainRequest query(QueryBuilder query) { this.query = query; return this; } diff --git a/core/src/main/java/org/elasticsearch/action/ingest/PutPipelineTransportAction.java b/core/src/main/java/org/elasticsearch/action/ingest/PutPipelineTransportAction.java index e1a34413e2c..bea5a2c8bc3 100644 --- a/core/src/main/java/org/elasticsearch/action/ingest/PutPipelineTransportAction.java +++ b/core/src/main/java/org/elasticsearch/action/ingest/PutPipelineTransportAction.java @@ -80,7 +80,7 @@ public class PutPipelineTransportAction extends TransportMasterNodeAction ingestInfos = new HashMap<>(); - for (NodeInfo nodeInfo : nodeInfos) { + for (NodeInfo nodeInfo : nodeInfos.getNodes()) { ingestInfos.put(nodeInfo.getNode(), nodeInfo.getIngest()); } pipelineStore.put(clusterService, ingestInfos, request, listener); diff --git a/core/src/main/java/org/elasticsearch/action/percolate/PercolateSourceBuilder.java b/core/src/main/java/org/elasticsearch/action/percolate/PercolateSourceBuilder.java index 5a5924f7883..a6ee99a476c 100644 --- a/core/src/main/java/org/elasticsearch/action/percolate/PercolateSourceBuilder.java +++ b/core/src/main/java/org/elasticsearch/action/percolate/PercolateSourceBuilder.java @@ -48,7 +48,7 @@ import java.util.Map; public class PercolateSourceBuilder extends ToXContentToBytes { private DocBuilder docBuilder; - private QueryBuilder queryBuilder; + private QueryBuilder queryBuilder; private Integer size; private List> sorts; private Boolean trackScores; @@ -68,7 +68,7 @@ public class PercolateSourceBuilder extends ToXContentToBytes { * Sets a query to reduce the number of percolate queries to be evaluated and score the queries that match based * on this query. */ - public PercolateSourceBuilder setQueryBuilder(QueryBuilder queryBuilder) { + public PercolateSourceBuilder setQueryBuilder(QueryBuilder queryBuilder) { this.queryBuilder = queryBuilder; return this; } diff --git a/core/src/main/java/org/elasticsearch/action/percolate/TransportPercolateAction.java b/core/src/main/java/org/elasticsearch/action/percolate/TransportPercolateAction.java index 5c8b20b1f92..b80589df936 100644 --- a/core/src/main/java/org/elasticsearch/action/percolate/TransportPercolateAction.java +++ b/core/src/main/java/org/elasticsearch/action/percolate/TransportPercolateAction.java @@ -203,7 +203,7 @@ public class TransportPercolateAction extends HandledTransportAction queryBuilder = queryParseContext.parseInnerQueryBuilder(); + QueryBuilder queryBuilder = queryParseContext.parseInnerQueryBuilder(); BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.must(queryBuilder); boolQueryBuilder.filter(percolateQueryBuilder); diff --git a/core/src/main/java/org/elasticsearch/action/search/SearchRequestBuilder.java b/core/src/main/java/org/elasticsearch/action/search/SearchRequestBuilder.java index fc28addc111..9830f7be203 100644 --- a/core/src/main/java/org/elasticsearch/action/search/SearchRequestBuilder.java +++ b/core/src/main/java/org/elasticsearch/action/search/SearchRequestBuilder.java @@ -166,7 +166,7 @@ public class SearchRequestBuilder extends ActionRequestBuilder queryBuilder) { + public SearchRequestBuilder setQuery(QueryBuilder queryBuilder) { sourceBuilder().query(queryBuilder); return this; } @@ -175,7 +175,7 @@ public class SearchRequestBuilder extends ActionRequestBuilder postFilter) { + public SearchRequestBuilder setPostFilter(QueryBuilder postFilter) { sourceBuilder().postFilter(postFilter); return this; } diff --git a/core/src/main/java/org/elasticsearch/action/support/nodes/BaseNodesResponse.java b/core/src/main/java/org/elasticsearch/action/support/nodes/BaseNodesResponse.java index 01401bc7c6e..a49864154db 100644 --- a/core/src/main/java/org/elasticsearch/action/support/nodes/BaseNodesResponse.java +++ b/core/src/main/java/org/elasticsearch/action/support/nodes/BaseNodesResponse.java @@ -22,61 +22,77 @@ package org.elasticsearch.action.support.nodes; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.FailedNodeException; import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.Nullable; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import java.io.IOException; import java.util.HashMap; -import java.util.Iterator; +import java.util.List; import java.util.Map; +import java.util.Objects; /** * */ -public abstract class BaseNodesResponse extends ActionResponse implements Iterable { +public abstract class BaseNodesResponse extends ActionResponse { private ClusterName clusterName; - protected TNodeResponse[] nodes; + private List failures; + private List nodes; private Map nodesMap; protected BaseNodesResponse() { } - protected BaseNodesResponse(ClusterName clusterName, TNodeResponse[] nodes) { - this.clusterName = clusterName; - this.nodes = nodes; + protected BaseNodesResponse(ClusterName clusterName, List nodes, List failures) { + this.clusterName = Objects.requireNonNull(clusterName); + this.failures = Objects.requireNonNull(failures); + this.nodes = Objects.requireNonNull(nodes); } /** - * The failed nodes, if set to be captured. + * Get the {@link ClusterName} associated with all of the nodes. + * + * @return Never {@code null}. */ - @Nullable - public FailedNodeException[] failures() { - return null; - } - public ClusterName getClusterName() { - return this.clusterName; + return clusterName; } - public String getClusterNameAsString() { - return this.clusterName.value(); + /** + * Get the failed node exceptions. + * + * @return Never {@code null}. Can be empty. + */ + public List failures() { + return failures; } - public TNodeResponse[] getNodes() { + /** + * Determine if there are any node failures in {@link #failures}. + * + * @return {@code true} if {@link #failures} contains at least 1 {@link FailedNodeException}. + */ + public boolean hasFailures() { + return failures.isEmpty() == false; + } + + /** + * Get the successful node responses. + * + * @return Never {@code null}. Can be empty. + * @see #hasFailures() + */ + public List getNodes() { return nodes; } - public TNodeResponse getAt(int position) { - return nodes[position]; - } - - @Override - public Iterator iterator() { - return getNodesMap().values().iterator(); - } - + /** + * Lazily build and get a map of Node ID to node response. + * + * @return Never {@code null}. Can be empty. + * @see #getNodes() + */ public Map getNodesMap() { if (nodesMap == null) { nodesMap = new HashMap<>(); @@ -91,11 +107,28 @@ public abstract class BaseNodesResponse public void readFrom(StreamInput in) throws IOException { super.readFrom(in); clusterName = ClusterName.readClusterName(in); + nodes = readNodesFrom(in); + failures = in.readList(FailedNodeException::new); } @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); clusterName.writeTo(out); + writeNodesTo(out, nodes); + out.writeList(failures); } + + /** + * Read the {@link #nodes} from the stream. + * + * @return Never {@code null}. + */ + protected abstract List readNodesFrom(StreamInput in) throws IOException; + + /** + * Write the {@link #nodes} to the stream. + */ + protected abstract void writeNodesTo(StreamOutput out, List nodes) throws IOException; + } diff --git a/core/src/main/java/org/elasticsearch/action/support/nodes/TransportNodesAction.java b/core/src/main/java/org/elasticsearch/action/support/nodes/TransportNodesAction.java index c996d530dce..2767bc80bf3 100644 --- a/core/src/main/java/org/elasticsearch/action/support/nodes/TransportNodesAction.java +++ b/core/src/main/java/org/elasticsearch/action/support/nodes/TransportNodesAction.java @@ -43,6 +43,9 @@ import org.elasticsearch.transport.TransportRequestHandler; import org.elasticsearch.transport.TransportRequestOptions; import org.elasticsearch.transport.TransportService; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.function.Supplier; @@ -50,22 +53,30 @@ import java.util.function.Supplier; /** * */ -public abstract class TransportNodesAction, NodesResponse extends BaseNodesResponse, NodeRequest extends BaseNodeRequest, NodeResponse extends BaseNodeResponse> extends HandledTransportAction { +public abstract class TransportNodesAction, + NodesResponse extends BaseNodesResponse, + NodeRequest extends BaseNodeRequest, + NodeResponse extends BaseNodeResponse> + extends HandledTransportAction { protected final ClusterName clusterName; protected final ClusterService clusterService; protected final TransportService transportService; + protected final Class nodeResponseClass; final String transportNodeAction; protected TransportNodesAction(Settings settings, String actionName, ClusterName clusterName, ThreadPool threadPool, ClusterService clusterService, TransportService transportService, ActionFilters actionFilters, - IndexNameExpressionResolver indexNameExpressionResolver, Supplier request, Supplier nodeRequest, - String nodeExecutor) { + IndexNameExpressionResolver indexNameExpressionResolver, + Supplier request, Supplier nodeRequest, + String nodeExecutor, + Class nodeResponseClass) { super(settings, actionName, threadPool, transportService, actionFilters, indexNameExpressionResolver, request); - this.clusterName = clusterName; - this.clusterService = clusterService; - this.transportService = transportService; + this.clusterName = Objects.requireNonNull(clusterName); + this.clusterService = Objects.requireNonNull(clusterService); + this.transportService = Objects.requireNonNull(transportService); + this.nodeResponseClass = Objects.requireNonNull(nodeResponseClass); this.transportNodeAction = actionName + "[n]"; @@ -87,7 +98,46 @@ public abstract class TransportNodesAction responses = new ArrayList<>(); + final List failures = new ArrayList<>(); + + for (int i = 0; i < nodesResponses.length(); ++i) { + Object response = nodesResponses.get(i); + + if (nodeResponseClass.isInstance(response)) { + responses.add(nodeResponseClass.cast(response)); + } else if (response instanceof FailedNodeException) { + failures.add((FailedNodeException)response); + } else { + logger.warn("ignoring unexpected response [{}] of type [{}], expected [{}] or [{}]", + response, response != null ? response.getClass().getName() : null, + nodeResponseClass.getSimpleName(), FailedNodeException.class.getSimpleName()); + } + } + + return newResponse(request, responses, failures); + } + + /** + * Create a new {@link NodesResponse} (multi-node response). + * + * @param request The associated request. + * @param responses All successful node-level responses. + * @param failures All node-level failures. + * @return Never {@code null}. + * @throws NullPointerException if any parameter is {@code null}. + */ + protected abstract NodesResponse newResponse(NodesRequest request, List responses, List failures); protected abstract NodeRequest newNodeRequest(String nodeId, NodesRequest request); @@ -165,7 +215,8 @@ public abstract class TransportNodesAction() { + transportService.sendRequest(node, transportNodeAction, nodeRequest, builder.build(), + new BaseTransportResponseHandler() { @Override public NodeResponse newInstance() { return newNodeResponse(); @@ -238,4 +289,5 @@ public abstract class TransportNodesAction nodeStatsArray, ImmutableOpenMap.Builder newLeastAvaiableUsages, ImmutableOpenMap.Builder newMostAvaiableUsages) { for (NodeStats nodeStats : nodeStatsArray) { diff --git a/core/src/main/java/org/elasticsearch/cluster/health/ClusterHealthStatus.java b/core/src/main/java/org/elasticsearch/cluster/health/ClusterHealthStatus.java index 6d3e136eb1a..a261d28f537 100644 --- a/core/src/main/java/org/elasticsearch/cluster/health/ClusterHealthStatus.java +++ b/core/src/main/java/org/elasticsearch/cluster/health/ClusterHealthStatus.java @@ -20,10 +20,16 @@ package org.elasticsearch.cluster.health; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.io.stream.Writeable; + +import java.io.IOException; + /** * */ -public enum ClusterHealthStatus { +public enum ClusterHealthStatus implements Writeable { GREEN((byte) 0), YELLOW((byte) 1), RED((byte) 2); @@ -38,7 +44,21 @@ public enum ClusterHealthStatus { return value; } - public static ClusterHealthStatus fromValue(byte value) { + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeByte(value); + } + + /** + * Read from a stream. + * + * @throws IllegalArgumentException if the value is unrecognized + */ + public static ClusterHealthStatus readFrom(StreamInput in) throws IOException { + return fromValue(in.readByte()); + } + + public static ClusterHealthStatus fromValue(byte value) throws IOException { switch (value) { case 0: return GREEN; diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java b/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java index 64da04e6511..735916504da 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java @@ -141,7 +141,7 @@ public class AliasValidator extends AbstractComponent { private static void validateAliasFilter(XContentParser parser, QueryShardContext queryShardContext) throws IOException { QueryParseContext queryParseContext = queryShardContext.newParseContext(parser); - QueryBuilder queryBuilder = QueryBuilder.rewriteQuery(queryParseContext.parseInnerQueryBuilder(), queryShardContext); + QueryBuilder queryBuilder = QueryBuilder.rewriteQuery(queryParseContext.parseInnerQueryBuilder(), queryShardContext); queryBuilder.toFilter(queryShardContext); } } diff --git a/core/src/main/java/org/elasticsearch/common/geo/GeoPoint.java b/core/src/main/java/org/elasticsearch/common/geo/GeoPoint.java index 7713157422e..5d1250a5148 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/GeoPoint.java +++ b/core/src/main/java/org/elasticsearch/common/geo/GeoPoint.java @@ -38,7 +38,7 @@ public final class GeoPoint { } /** - * Create a new Geopointform a string. This String must either be a geohash + * Create a new Geopoint from a string. This String must either be a geohash * or a lat-lon tuple. * * @param value String to create the point from diff --git a/core/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java b/core/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java index 8df43f687f6..ec56103e7a0 100644 --- a/core/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java +++ b/core/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java @@ -736,6 +736,29 @@ public abstract class StreamInput extends InputStream { return null; } + /** + * Read a {@link List} of {@link Streamable} objects, using the {@code constructor} to instantiate each instance. + *

+ * This is expected to take the form: + * + * List<MyStreamableClass> list = in.readStreamList(MyStreamableClass::new); + * + * + * @param constructor Streamable instance creator + * @return Never {@code null}. + * @throws IOException if any step fails + */ + public List readStreamableList(Supplier constructor) throws IOException { + int count = readVInt(); + List builder = new ArrayList<>(count); + for (int i=0; i list) throws IOException { + writeVInt(list.size()); + for (Streamable obj: list) { + obj.writeTo(this); + } + } + /** * Writes a list of {@link Writeable} objects */ - public void writeList(List list) throws IOException { + public void writeList(List list) throws IOException { writeVInt(list.size()); - for (T obj: list) { + for (Writeable obj: list) { obj.writeTo(this); } } diff --git a/core/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java b/core/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java index 4367b15fd52..3fa182e3727 100644 --- a/core/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java @@ -113,6 +113,10 @@ public final class XContentBuilder implements BytesStream, Releasable { return this; } + public boolean isPrettyPrint() { + return generator.isPrettyPrint(); + } + public XContentBuilder lfAtEnd() { generator.usePrintLineFeedAtEnd(); return this; diff --git a/core/src/main/java/org/elasticsearch/common/xcontent/XContentGenerator.java b/core/src/main/java/org/elasticsearch/common/xcontent/XContentGenerator.java index f23ae441989..a2cceae8367 100644 --- a/core/src/main/java/org/elasticsearch/common/xcontent/XContentGenerator.java +++ b/core/src/main/java/org/elasticsearch/common/xcontent/XContentGenerator.java @@ -20,7 +20,6 @@ package org.elasticsearch.common.xcontent; import org.elasticsearch.common.bytes.BytesReference; - import java.io.Closeable; import java.io.IOException; import java.io.InputStream; @@ -34,6 +33,8 @@ public interface XContentGenerator extends Closeable { void usePrettyPrint(); + boolean isPrettyPrint(); + void usePrintLineFeedAtEnd(); void writeStartArray() throws IOException; diff --git a/core/src/main/java/org/elasticsearch/common/xcontent/json/JsonXContentGenerator.java b/core/src/main/java/org/elasticsearch/common/xcontent/json/JsonXContentGenerator.java index 4148148e507..e74ab01bd6a 100644 --- a/core/src/main/java/org/elasticsearch/common/xcontent/json/JsonXContentGenerator.java +++ b/core/src/main/java/org/elasticsearch/common/xcontent/json/JsonXContentGenerator.java @@ -104,6 +104,11 @@ public class JsonXContentGenerator implements XContentGenerator { prettyPrint = true; } + @Override + public boolean isPrettyPrint() { + return this.prettyPrint; + } + @Override public void usePrintLineFeedAtEnd() { writeLineFeedAtEnd = true; diff --git a/core/src/main/java/org/elasticsearch/discovery/zen/ping/unicast/UnicastZenPing.java b/core/src/main/java/org/elasticsearch/discovery/zen/ping/unicast/UnicastZenPing.java index cc37504360c..d200ca5b07b 100644 --- a/core/src/main/java/org/elasticsearch/discovery/zen/ping/unicast/UnicastZenPing.java +++ b/core/src/main/java/org/elasticsearch/discovery/zen/ping/unicast/UnicastZenPing.java @@ -402,7 +402,7 @@ public class UnicastZenPing extends AbstractLifecycleComponent implemen // connect to the node, see if we manage to do it, if not, bail if (!nodeFoundByAddress) { logger.trace("[{}] connecting (light) to {}", sendPingsHandler.id(), finalNodeToSend); - transportService.connectToNodeLight(finalNodeToSend, timeout.getMillis()); + transportService.connectToNodeLightAndHandshake(finalNodeToSend, timeout.getMillis()); } else { logger.trace("[{}] connecting to {}", sendPingsHandler.id(), finalNodeToSend); transportService.connectToNode(finalNodeToSend); diff --git a/core/src/main/java/org/elasticsearch/gateway/AsyncShardFetch.java b/core/src/main/java/org/elasticsearch/gateway/AsyncShardFetch.java index cd6268d04ec..b74507a4acc 100644 --- a/core/src/main/java/org/elasticsearch/gateway/AsyncShardFetch.java +++ b/core/src/main/java/org/elasticsearch/gateway/AsyncShardFetch.java @@ -35,9 +35,11 @@ import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException; import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.transport.ReceiveTimeoutTransportException; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Set; @@ -57,24 +59,24 @@ public abstract class AsyncShardFetch implements Rel /** * An action that lists the relevant shard data that needs to be fetched. */ - public interface List, NodeResponse extends BaseNodeResponse> { + public interface Lister, NodeResponse extends BaseNodeResponse> { void list(ShardId shardId, String[] nodesIds, ActionListener listener); } protected final ESLogger logger; protected final String type; private final ShardId shardId; - private final List, T> action; + private final Lister, T> action; private final Map> cache = new HashMap<>(); private final Set nodesToIgnore = new HashSet<>(); private boolean closed; @SuppressWarnings("unchecked") - protected AsyncShardFetch(ESLogger logger, String type, ShardId shardId, List, T> action) { + protected AsyncShardFetch(ESLogger logger, String type, ShardId shardId, Lister, T> action) { this.logger = logger; this.type = type; this.shardId = shardId; - this.action = (List, T>) action; + this.action = (Lister, T>) action; } @Override @@ -167,7 +169,7 @@ public abstract class AsyncShardFetch implements Rel * the shard (response + failures), issuing a reroute at the end of it to make sure there will be another round * of allocations taking this new data into account. */ - protected synchronized void processAsyncFetch(ShardId shardId, T[] responses, FailedNodeException[] failures) { + protected synchronized void processAsyncFetch(ShardId shardId, List responses, List failures) { if (closed) { // we are closed, no need to process this async fetch at all logger.trace("{} ignoring fetched [{}] results, already closed", shardId, type); @@ -276,9 +278,9 @@ public abstract class AsyncShardFetch implements Rel @Override public void onFailure(Throwable e) { - FailedNodeException[] failures = new FailedNodeException[nodesIds.length]; - for (int i = 0; i < failures.length; i++) { - failures[i] = new FailedNodeException(nodesIds[i], "total failure in fetching", e); + List failures = new ArrayList<>(nodesIds.length); + for (String nodeId : nodesIds) { + failures.add(new FailedNodeException(nodeId, "total failure in fetching", e)); } processAsyncFetch(shardId, null, failures); } diff --git a/core/src/main/java/org/elasticsearch/gateway/Gateway.java b/core/src/main/java/org/elasticsearch/gateway/Gateway.java index 4da789b43fc..0e6b1959279 100644 --- a/core/src/main/java/org/elasticsearch/gateway/Gateway.java +++ b/core/src/main/java/org/elasticsearch/gateway/Gateway.java @@ -82,7 +82,7 @@ public class Gateway extends AbstractComponent implements ClusterStateListener { int requiredAllocation = Math.max(1, minimumMasterNodesProvider.get()); - if (nodesState.failures().length > 0) { + if (nodesState.hasFailures()) { for (FailedNodeException failedNodeException : nodesState.failures()) { logger.warn("failed to fetch state from node", failedNodeException); } @@ -91,7 +91,7 @@ public class Gateway extends AbstractComponent implements ClusterStateListener { ObjectFloatHashMap indices = new ObjectFloatHashMap<>(); MetaData electedGlobalState = null; int found = 0; - for (TransportNodesListGatewayMetaState.NodeGatewayMetaState nodeState : nodesState) { + for (TransportNodesListGatewayMetaState.NodeGatewayMetaState nodeState : nodesState.getNodes()) { if (nodeState.metaData() == null) { continue; } @@ -119,7 +119,7 @@ public class Gateway extends AbstractComponent implements ClusterStateListener { Index index = (Index) keys[i]; IndexMetaData electedIndexMetaData = null; int indexMetaDataCount = 0; - for (TransportNodesListGatewayMetaState.NodeGatewayMetaState nodeState : nodesState) { + for (TransportNodesListGatewayMetaState.NodeGatewayMetaState nodeState : nodesState.getNodes()) { if (nodeState.metaData() == null) { continue; } diff --git a/core/src/main/java/org/elasticsearch/gateway/GatewayAllocator.java b/core/src/main/java/org/elasticsearch/gateway/GatewayAllocator.java index e76e8085e86..15cd0e2bf63 100644 --- a/core/src/main/java/org/elasticsearch/gateway/GatewayAllocator.java +++ b/core/src/main/java/org/elasticsearch/gateway/GatewayAllocator.java @@ -125,7 +125,7 @@ public class GatewayAllocator extends AbstractComponent { class InternalAsyncFetch extends AsyncShardFetch { - public InternalAsyncFetch(ESLogger logger, String type, ShardId shardId, List, T> action) { + public InternalAsyncFetch(ESLogger logger, String type, ShardId shardId, Lister, T> action) { super(logger, type, shardId, action); } diff --git a/core/src/main/java/org/elasticsearch/gateway/TransportNodesListGatewayMetaState.java b/core/src/main/java/org/elasticsearch/gateway/TransportNodesListGatewayMetaState.java index 0fd1fd35809..2d0b894939d 100644 --- a/core/src/main/java/org/elasticsearch/gateway/TransportNodesListGatewayMetaState.java +++ b/core/src/main/java/org/elasticsearch/gateway/TransportNodesListGatewayMetaState.java @@ -43,14 +43,15 @@ import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import java.io.IOException; -import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicReferenceArray; /** * */ -public class TransportNodesListGatewayMetaState extends TransportNodesAction { +public class TransportNodesListGatewayMetaState extends TransportNodesAction { public static final String ACTION_NAME = "internal:gateway/local/meta_state"; @@ -61,7 +62,7 @@ public class TransportNodesListGatewayMetaState extends TransportNodesAction nodesList = new ArrayList<>(); - final List failures = new ArrayList<>(); - for (int i = 0; i < responses.length(); i++) { - Object resp = responses.get(i); - if (resp instanceof NodeGatewayMetaState) { // will also filter out null response for unallocated ones - nodesList.add((NodeGatewayMetaState) resp); - } else if (resp instanceof FailedNodeException) { - failures.add((FailedNodeException) resp); - } else { - logger.warn("unknown response type [{}], expected NodeLocalGatewayMetaState or FailedNodeException", resp); - } - } - return new NodesGatewayMetaState(clusterName, nodesList.toArray(new NodeGatewayMetaState[nodesList.size()]), - failures.toArray(new FailedNodeException[failures.size()])); + protected NodesGatewayMetaState newResponse(Request request, List responses, List failures) { + return new NodesGatewayMetaState(clusterName, responses, failures); } @Override @@ -142,47 +130,30 @@ public class TransportNodesListGatewayMetaState extends TransportNodesAction { - private FailedNodeException[] failures; - NodesGatewayMetaState() { } - public NodesGatewayMetaState(ClusterName clusterName, NodeGatewayMetaState[] nodes, FailedNodeException[] failures) { - super(clusterName, nodes); - this.failures = failures; - } - - public FailedNodeException[] failures() { - return failures; + public NodesGatewayMetaState(ClusterName clusterName, List nodes, List failures) { + super(clusterName, nodes, failures); } @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - nodes = new NodeGatewayMetaState[in.readVInt()]; - for (int i = 0; i < nodes.length; i++) { - nodes[i] = new NodeGatewayMetaState(); - nodes[i].readFrom(in); - } + protected List readNodesFrom(StreamInput in) throws IOException { + return in.readStreamableList(NodeGatewayMetaState::new); } @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeVInt(nodes.length); - for (NodeGatewayMetaState response : nodes) { - response.writeTo(out); - } + protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { + out.writeStreamableList(nodes); } } - public static class NodeRequest extends BaseNodeRequest { public NodeRequest() { } - NodeRequest(String nodeId, TransportNodesListGatewayMetaState.Request request) { + NodeRequest(String nodeId) { super(nodeId); } diff --git a/core/src/main/java/org/elasticsearch/gateway/TransportNodesListGatewayStartedShards.java b/core/src/main/java/org/elasticsearch/gateway/TransportNodesListGatewayStartedShards.java index bdeb6d1660f..675c0088082 100644 --- a/core/src/main/java/org/elasticsearch/gateway/TransportNodesListGatewayStartedShards.java +++ b/core/src/main/java/org/elasticsearch/gateway/TransportNodesListGatewayStartedShards.java @@ -48,9 +48,7 @@ import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import java.io.IOException; -import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicReferenceArray; /** * This transport action is used to fetch the shard version from each node during primary allocation in {@link GatewayAllocator}. @@ -63,7 +61,7 @@ public class TransportNodesListGatewayStartedShards extends TransportNodesListGatewayStartedShards.NodeRequest, TransportNodesListGatewayStartedShards.NodeGatewayStartedShards> implements - AsyncShardFetch.List { public static final String ACTION_NAME = "internal:gateway/local/started_shards"; @@ -77,7 +75,8 @@ public class TransportNodesListGatewayStartedShards extends IndexNameExpressionResolver indexNameExpressionResolver, NodeEnvironment env) { super(settings, ACTION_NAME, clusterName, threadPool, clusterService, transportService, actionFilters, - indexNameExpressionResolver, Request::new, NodeRequest::new, ThreadPool.Names.FETCH_SHARD_STARTED); + indexNameExpressionResolver, Request::new, NodeRequest::new, ThreadPool.Names.FETCH_SHARD_STARTED, + NodeGatewayStartedShards.class); this.nodeEnv = env; } @@ -110,23 +109,9 @@ public class TransportNodesListGatewayStartedShards extends } @Override - protected NodesGatewayStartedShards newResponse(Request request, AtomicReferenceArray responses) { - final List nodesList = new ArrayList<>(); - final List failures = new ArrayList<>(); - for (int i = 0; i < responses.length(); i++) { - Object resp = responses.get(i); - if (resp instanceof NodeGatewayStartedShards) { // will also filter out null response for unallocated ones - nodesList.add((NodeGatewayStartedShards) resp); - } else if (resp instanceof FailedNodeException) { - failures.add((FailedNodeException) resp); - } else { - logger.warn("unknown response type [{}], expected NodeLocalGatewayStartedShards or FailedNodeException", - resp); - } - } - return new NodesGatewayStartedShards(clusterName, - nodesList.toArray(new NodeGatewayStartedShards[nodesList.size()]), - failures.toArray(new FailedNodeException[failures.size()])); + protected NodesGatewayStartedShards newResponse(Request request, + List responses, List failures) { + return new NodesGatewayStartedShards(clusterName, responses, failures); } @Override @@ -217,36 +202,19 @@ public class TransportNodesListGatewayStartedShards extends public static class NodesGatewayStartedShards extends BaseNodesResponse { - private FailedNodeException[] failures; - - public NodesGatewayStartedShards(ClusterName clusterName, NodeGatewayStartedShards[] nodes, - FailedNodeException[] failures) { - super(clusterName, nodes); - this.failures = failures; + public NodesGatewayStartedShards(ClusterName clusterName, List nodes, + List failures) { + super(clusterName, nodes, failures); } @Override - public FailedNodeException[] failures() { - return failures; + protected List readNodesFrom(StreamInput in) throws IOException { + return in.readStreamableList(NodeGatewayStartedShards::new); } @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - nodes = new NodeGatewayStartedShards[in.readVInt()]; - for (int i = 0; i < nodes.length; i++) { - nodes[i] = new NodeGatewayStartedShards(); - nodes[i].readFrom(in); - } - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeVInt(nodes.length); - for (NodeGatewayStartedShards response : nodes) { - response.writeTo(out); - } + protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { + out.writeStreamableList(nodes); } } @@ -258,7 +226,7 @@ public class TransportNodesListGatewayStartedShards extends public NodeRequest() { } - NodeRequest(String nodeId, Request request) { + public NodeRequest(String nodeId, Request request) { super(nodeId); this.shardId = request.shardId(); } diff --git a/core/src/main/java/org/elasticsearch/index/mapper/ParseContext.java b/core/src/main/java/org/elasticsearch/index/mapper/ParseContext.java index 931fbebede2..33476b48cc3 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/ParseContext.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/ParseContext.java @@ -326,11 +326,6 @@ public abstract class ParseContext { return in.externalValue(); } - @Override - public StringBuilder stringBuilder() { - return in.stringBuilder(); - } - @Override public void addDynamicMapper(Mapper update) { in.addDynamicMapper(update); @@ -366,8 +361,6 @@ public abstract class ParseContext { private Field uid, version; - private StringBuilder stringBuilder = new StringBuilder(); - private AllEntries allEntries = new AllEntries(); private List dynamicMappers = new ArrayList<>(); @@ -526,16 +519,6 @@ public abstract class ParseContext { return this.allEntries; } - /** - * A string builder that can be used to construct complex names for example. - * Its better to reuse the. - */ - @Override - public StringBuilder stringBuilder() { - stringBuilder.setLength(0); - return this.stringBuilder; - } - @Override public void addDynamicMapper(Mapper mapper) { dynamicMappers.add(mapper); @@ -736,12 +719,6 @@ public abstract class ParseContext { return clazz.cast(externalValue()); } - /** - * A string builder that can be used to construct complex names for example. - * Its better to reuse the. - */ - public abstract StringBuilder stringBuilder(); - /** * Add a new mapper dynamically created while parsing. */ diff --git a/core/src/main/java/org/elasticsearch/index/mapper/Uid.java b/core/src/main/java/org/elasticsearch/index/mapper/Uid.java index 414a00d8eed..70acbcd82c3 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/Uid.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/Uid.java @@ -123,13 +123,6 @@ public final class Uid { return ref; } - public static BytesRef createUidAsBytes(BytesRef type, BytesRef id, BytesRefBuilder spare) { - spare.copyBytes(type); - spare.append(DELIMITER_BYTES); - spare.append(id); - return spare.get(); - } - public static BytesRef[] createUidsForTypesAndId(Collection types, Object id) { return createUidsForTypesAndIds(types, Collections.singletonList(id)); } @@ -149,11 +142,7 @@ public final class Uid { } public static String createUid(String type, String id) { - return createUid(new StringBuilder(), type, id); - } - - public static String createUid(StringBuilder sb, String type, String id) { - return sb.append(type).append(DELIMITER).append(id).toString(); + return type + DELIMITER + id; } public static boolean hasDelimiter(BytesRef uid) { diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java index 81977fe6caf..89e2d8409d5 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java @@ -36,7 +36,6 @@ import org.elasticsearch.common.Nullable; import org.elasticsearch.common.joda.DateMathParser; import org.elasticsearch.common.joda.FormatDateTimeFormatter; import org.elasticsearch.common.joda.Joda; -import org.elasticsearch.common.network.InetAddresses; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.Fuzziness; import org.elasticsearch.common.util.LocaleUtils; @@ -152,7 +151,7 @@ public class DateFieldMapper extends FieldMapper implements AllFieldMapper.Inclu if (propNode == null) { throw new MapperParsingException("Property [null_value] cannot be null."); } - builder.nullValue(InetAddresses.forString(propNode.toString())); + builder.nullValue(propNode.toString()); iterator.remove(); } else if (propName.equals("ignore_malformed")) { builder.ignoreMalformed(TypeParsers.nodeBooleanValue("ignore_malformed", propNode, parserContext)); @@ -561,7 +560,7 @@ public class DateFieldMapper extends FieldMapper implements AllFieldMapper.Inclu dateAsString = dateAsObject.toString(); } } else { - dateAsString = context.parser().text(); + dateAsString = context.parser().textOrNull(); } if (dateAsString == null) { @@ -615,6 +614,11 @@ public class DateFieldMapper extends FieldMapper implements AllFieldMapper.Inclu if (includeDefaults || ignoreMalformed.explicit()) { builder.field("ignore_malformed", ignoreMalformed.value()); } + + if (includeDefaults || fieldType().nullValue() != null) { + builder.field("null_value", fieldType().nullValueAsString()); + } + if (includeInAll != null) { builder.field("include_in_all", includeInAll); } else if (includeDefaults) { diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java index 2c3a9a5c83e..f1088652988 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java @@ -366,8 +366,15 @@ public class NumberFieldMapper extends FieldMapper implements AllFieldMapper.Inc BYTE("byte", NumericType.BYTE) { @Override Byte parse(Object value) { - if (value instanceof Byte) { - return (Byte) value; + if (value instanceof Number) { + double doubleValue = ((Number) value).doubleValue(); + if (doubleValue < Byte.MIN_VALUE || doubleValue > Byte.MAX_VALUE) { + throw new IllegalArgumentException("Value [" + value + "] is out of range for a byte"); + } + if (doubleValue % 1 != 0) { + throw new IllegalArgumentException("Value [" + value + "] has a decimal part"); + } + return ((Number) value).byteValue(); } if (value instanceof BytesRef) { value = ((BytesRef) value).utf8ToString(); @@ -426,6 +433,13 @@ public class NumberFieldMapper extends FieldMapper implements AllFieldMapper.Inc @Override Short parse(Object value) { if (value instanceof Number) { + double doubleValue = ((Number) value).doubleValue(); + if (doubleValue < Short.MIN_VALUE || doubleValue > Short.MAX_VALUE) { + throw new IllegalArgumentException("Value [" + value + "] is out of range for a short"); + } + if (doubleValue % 1 != 0) { + throw new IllegalArgumentException("Value [" + value + "] has a decimal part"); + } return ((Number) value).shortValue(); } if (value instanceof BytesRef) { @@ -485,6 +499,13 @@ public class NumberFieldMapper extends FieldMapper implements AllFieldMapper.Inc @Override Integer parse(Object value) { if (value instanceof Number) { + double doubleValue = ((Number) value).doubleValue(); + if (doubleValue < Integer.MIN_VALUE || doubleValue > Integer.MAX_VALUE) { + throw new IllegalArgumentException("Value [" + value + "] is out of range for an integer"); + } + if (doubleValue % 1 != 0) { + throw new IllegalArgumentException("Value [" + value + "] has a decimal part"); + } return ((Number) value).intValue(); } if (value instanceof BytesRef) { @@ -581,6 +602,13 @@ public class NumberFieldMapper extends FieldMapper implements AllFieldMapper.Inc @Override Long parse(Object value) { if (value instanceof Number) { + double doubleValue = ((Number) value).doubleValue(); + if (doubleValue < Long.MIN_VALUE || doubleValue > Long.MAX_VALUE) { + throw new IllegalArgumentException("Value [" + value + "] is out of range for a long"); + } + if (doubleValue % 1 != 0) { + throw new IllegalArgumentException("Value [" + value + "] has a decimal part"); + } return ((Number) value).longValue(); } if (value instanceof BytesRef) { @@ -944,6 +972,11 @@ public class NumberFieldMapper extends FieldMapper implements AllFieldMapper.Inc if (includeDefaults || coerce.explicit()) { builder.field("coerce", coerce.value()); } + + if (includeDefaults || fieldType().nullValue() != null) { + builder.field("null_value", fieldType().nullValue()); + } + if (includeInAll != null) { builder.field("include_in_all", includeInAll); } else if (includeDefaults) { diff --git a/core/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java index 9473297de6f..2bf4f75f417 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java @@ -31,7 +31,6 @@ import org.apache.lucene.search.TermQuery; import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.loader.SettingsLoader; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -264,7 +263,7 @@ public class ParentFieldMapper extends MetadataFieldMapper { } // we did not add it in the parsing phase, add it now fields.add(new SortedDocValuesField(fieldType.name(), new BytesRef(parentId))); - } else if (parentId != null && !parsedParentId.equals(Uid.createUid(context.stringBuilder(), parentType, parentId))) { + } else if (parentId != null && !parsedParentId.equals(Uid.createUid(parentType, parentId))) { throw new MapperParsingException("Parent id mismatch, document value is [" + Uid.createUid(parsedParentId).id() + "], while external value is [" + parentId + "]"); } } diff --git a/core/src/main/java/org/elasticsearch/index/mapper/internal/UidFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/internal/UidFieldMapper.java index e150a8cd10f..b22369ef812 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/internal/UidFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/internal/UidFieldMapper.java @@ -23,7 +23,6 @@ import org.apache.lucene.document.BinaryDocValuesField; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexableField; -import org.apache.lucene.index.Term; import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.settings.Settings; @@ -177,7 +176,7 @@ public class UidFieldMapper extends MetadataFieldMapper { @Override protected void parseCreateField(ParseContext context, List fields) throws IOException { - Field uid = new Field(NAME, Uid.createUid(context.stringBuilder(), context.type(), context.id()), Defaults.FIELD_TYPE); + Field uid = new Field(NAME, Uid.createUid(context.type(), context.id()), Defaults.FIELD_TYPE); context.uid(uid); fields.add(uid); if (fieldType().hasDocValues()) { diff --git a/core/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java index 6cb3cbe46c8..5f5a3d85fe1 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java @@ -339,7 +339,7 @@ public class IpFieldMapper extends FieldMapper implements AllFieldMapper.Include if (context.externalValueSet()) { addressAsObject = context.externalValue(); } else { - addressAsObject = context.parser().text(); + addressAsObject = context.parser().textOrNull(); } if (addressAsObject == null) { @@ -395,6 +395,10 @@ public class IpFieldMapper extends FieldMapper implements AllFieldMapper.Include protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException { super.doXContentBody(builder, includeDefaults, params); + if (includeDefaults || fieldType().nullValue() != null) { + builder.field("null_value", InetAddresses.toAddrString((InetAddress) fieldType().nullValue())); + } + if (includeDefaults || ignoreMalformed.explicit()) { builder.field("ignore_malformed", ignoreMalformed.value()); } diff --git a/core/src/main/java/org/elasticsearch/index/percolator/PercolatorFieldMapper.java b/core/src/main/java/org/elasticsearch/index/percolator/PercolatorFieldMapper.java index 10c7e46e353..58f9f6c695c 100644 --- a/core/src/main/java/org/elasticsearch/index/percolator/PercolatorFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/percolator/PercolatorFieldMapper.java @@ -186,7 +186,7 @@ public class PercolatorFieldMapper extends FieldMapper { } XContentParser parser = context.parser(); - QueryBuilder queryBuilder = parseQueryBuilder(queryShardContext.newParseContext(parser), parser.getTokenLocation()); + QueryBuilder queryBuilder = parseQueryBuilder(queryShardContext.newParseContext(parser), parser.getTokenLocation()); // Fetching of terms, shapes and indexed scripts happen during this rewrite: queryBuilder = queryBuilder.rewrite(queryShardContext); @@ -206,7 +206,7 @@ public class PercolatorFieldMapper extends FieldMapper { return toQuery(context, mapUnmappedFieldsAsString, parseQueryBuilder(context.newParseContext(parser), parser.getTokenLocation())); } - static Query toQuery(QueryShardContext context, boolean mapUnmappedFieldsAsString, QueryBuilder queryBuilder) throws IOException { + static Query toQuery(QueryShardContext context, boolean mapUnmappedFieldsAsString, QueryBuilder queryBuilder) throws IOException { // This means that fields in the query need to exist in the mapping prior to registering this query // The reason that this is required, is that if a field doesn't exist then the query assumes defaults, which may be undesired. // diff --git a/core/src/main/java/org/elasticsearch/index/query/AbstractQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/AbstractQueryBuilder.java index 6e82e7059d8..e883166f900 100644 --- a/core/src/main/java/org/elasticsearch/index/query/AbstractQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/AbstractQueryBuilder.java @@ -43,7 +43,7 @@ import java.util.Objects; * Base class for all classes producing lucene queries. * Supports conversion to BytesReference and creation of lucene Query objects. */ -public abstract class AbstractQueryBuilder> extends ToXContentToBytes implements QueryBuilder { +public abstract class AbstractQueryBuilder> extends ToXContentToBytes implements QueryBuilder { /** Default for boost to apply to resulting Lucene query. Defaults to 1.0*/ public static final float DEFAULT_BOOST = 1.0f; @@ -221,10 +221,10 @@ public abstract class AbstractQueryBuilder> * their {@link QueryBuilder#toQuery(QueryShardContext)} method are not added to the * resulting collection. */ - protected static Collection toQueries(Collection> queryBuilders, QueryShardContext context) throws QueryShardException, + protected static Collection toQueries(Collection queryBuilders, QueryShardContext context) throws QueryShardException, IOException { List queries = new ArrayList<>(queryBuilders.size()); - for (QueryBuilder queryBuilder : queryBuilders) { + for (QueryBuilder queryBuilder : queryBuilders) { Query query = queryBuilder.toQuery(context); if (query != null) { queries.add(query); @@ -241,13 +241,13 @@ public abstract class AbstractQueryBuilder> protected final static void writeQueries(StreamOutput out, List queries) throws IOException { out.writeVInt(queries.size()); - for (QueryBuilder query : queries) { + for (QueryBuilder query : queries) { out.writeNamedWriteable(query); } } - protected final static List> readQueries(StreamInput in) throws IOException { - List> queries = new ArrayList<>(); + protected final static List readQueries(StreamInput in) throws IOException { + List queries = new ArrayList<>(); int size = in.readVInt(); for (int i = 0; i < size; i++) { queries.add(in.readNamedWriteable(QueryBuilder.class)); @@ -256,8 +256,8 @@ public abstract class AbstractQueryBuilder> } @Override - public final QueryBuilder rewrite(QueryRewriteContext queryShardContext) throws IOException { - QueryBuilder rewritten = doRewrite(queryShardContext); + public final QueryBuilder rewrite(QueryRewriteContext queryShardContext) throws IOException { + QueryBuilder rewritten = doRewrite(queryShardContext); if (rewritten == this) { return rewritten; } @@ -270,7 +270,7 @@ public abstract class AbstractQueryBuilder> return rewritten; } - protected QueryBuilder doRewrite(QueryRewriteContext queryShardContext) throws IOException { + protected QueryBuilder doRewrite(QueryRewriteContext queryShardContext) throws IOException { return this; } diff --git a/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java index c6de1213a8d..e5aa774addc 100644 --- a/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java @@ -62,13 +62,13 @@ public class BoolQueryBuilder extends AbstractQueryBuilder { private static final ParseField MINIMUM_NUMBER_SHOULD_MATCH = new ParseField("minimum_number_should_match"); private static final ParseField ADJUST_PURE_NEGATIVE = new ParseField("adjust_pure_negative"); - private final List> mustClauses = new ArrayList<>(); + private final List mustClauses = new ArrayList<>(); - private final List> mustNotClauses = new ArrayList<>(); + private final List mustNotClauses = new ArrayList<>(); - private final List> filterClauses = new ArrayList<>(); + private final List filterClauses = new ArrayList<>(); - private final List> shouldClauses = new ArrayList<>(); + private final List shouldClauses = new ArrayList<>(); private boolean disableCoord = DISABLE_COORD_DEFAULT; @@ -111,7 +111,7 @@ public class BoolQueryBuilder extends AbstractQueryBuilder { * Adds a query that must appear in the matching documents and will * contribute to scoring. No null value allowed. */ - public BoolQueryBuilder must(QueryBuilder queryBuilder) { + public BoolQueryBuilder must(QueryBuilder queryBuilder) { if (queryBuilder == null) { throw new IllegalArgumentException("inner bool query clause cannot be null"); } @@ -122,7 +122,7 @@ public class BoolQueryBuilder extends AbstractQueryBuilder { /** * Gets the queries that must appear in the matching documents. */ - public List> must() { + public List must() { return this.mustClauses; } @@ -130,7 +130,7 @@ public class BoolQueryBuilder extends AbstractQueryBuilder { * Adds a query that must appear in the matching documents but will * not contribute to scoring. No null value allowed. */ - public BoolQueryBuilder filter(QueryBuilder queryBuilder) { + public BoolQueryBuilder filter(QueryBuilder queryBuilder) { if (queryBuilder == null) { throw new IllegalArgumentException("inner bool query clause cannot be null"); } @@ -141,7 +141,7 @@ public class BoolQueryBuilder extends AbstractQueryBuilder { /** * Gets the queries that must appear in the matching documents but don't contribute to scoring */ - public List> filter() { + public List filter() { return this.filterClauses; } @@ -149,7 +149,7 @@ public class BoolQueryBuilder extends AbstractQueryBuilder { * Adds a query that must not appear in the matching documents. * No null value allowed. */ - public BoolQueryBuilder mustNot(QueryBuilder queryBuilder) { + public BoolQueryBuilder mustNot(QueryBuilder queryBuilder) { if (queryBuilder == null) { throw new IllegalArgumentException("inner bool query clause cannot be null"); } @@ -160,7 +160,7 @@ public class BoolQueryBuilder extends AbstractQueryBuilder { /** * Gets the queries that must not appear in the matching documents. */ - public List> mustNot() { + public List mustNot() { return this.mustNotClauses; } @@ -171,7 +171,7 @@ public class BoolQueryBuilder extends AbstractQueryBuilder { * * @see #minimumNumberShouldMatch(int) */ - public BoolQueryBuilder should(QueryBuilder queryBuilder) { + public BoolQueryBuilder should(QueryBuilder queryBuilder) { if (queryBuilder == null) { throw new IllegalArgumentException("inner bool query clause cannot be null"); } @@ -185,7 +185,7 @@ public class BoolQueryBuilder extends AbstractQueryBuilder { * @see #should(QueryBuilder) * @see #minimumNumberShouldMatch(int) */ - public List> should() { + public List should() { return this.shouldClauses; } @@ -288,13 +288,13 @@ public class BoolQueryBuilder extends AbstractQueryBuilder { builder.endObject(); } - private static void doXArrayContent(String field, List> clauses, XContentBuilder builder, Params params) + private static void doXArrayContent(String field, List clauses, XContentBuilder builder, Params params) throws IOException { if (clauses.isEmpty()) { return; } builder.startArray(field); - for (QueryBuilder clause : clauses) { + for (QueryBuilder clause : clauses) { clause.toXContent(builder, params); } builder.endArray(); @@ -308,15 +308,15 @@ public class BoolQueryBuilder extends AbstractQueryBuilder { float boost = AbstractQueryBuilder.DEFAULT_BOOST; String minimumShouldMatch = null; - final List> mustClauses = new ArrayList<>(); - final List> mustNotClauses = new ArrayList<>(); - final List> shouldClauses = new ArrayList<>(); - final List> filterClauses = new ArrayList<>(); + final List mustClauses = new ArrayList<>(); + final List mustNotClauses = new ArrayList<>(); + final List shouldClauses = new ArrayList<>(); + final List filterClauses = new ArrayList<>(); String queryName = null; String currentFieldName = null; XContentParser.Token token; - QueryBuilder query; + QueryBuilder query; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); @@ -387,16 +387,16 @@ public class BoolQueryBuilder extends AbstractQueryBuilder { } } BoolQueryBuilder boolQuery = new BoolQueryBuilder(); - for (QueryBuilder queryBuilder : mustClauses) { + for (QueryBuilder queryBuilder : mustClauses) { boolQuery.must(queryBuilder); } - for (QueryBuilder queryBuilder : mustNotClauses) { + for (QueryBuilder queryBuilder : mustNotClauses) { boolQuery.mustNot(queryBuilder); } - for (QueryBuilder queryBuilder : shouldClauses) { + for (QueryBuilder queryBuilder : shouldClauses) { boolQuery.should(queryBuilder); } - for (QueryBuilder queryBuilder : filterClauses) { + for (QueryBuilder queryBuilder : filterClauses) { boolQuery.filter(queryBuilder); } boolQuery.boost(boost); @@ -436,8 +436,8 @@ public class BoolQueryBuilder extends AbstractQueryBuilder { } private static void addBooleanClauses(QueryShardContext context, BooleanQuery.Builder booleanQueryBuilder, - List> clauses, Occur occurs) throws IOException { - for (QueryBuilder query : clauses) { + List clauses, Occur occurs) throws IOException { + for (QueryBuilder query : clauses) { Query luceneQuery = null; switch (occurs) { case MUST: @@ -473,7 +473,7 @@ public class BoolQueryBuilder extends AbstractQueryBuilder { } @Override - protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { + protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { BoolQueryBuilder newBuilder = new BoolQueryBuilder(); boolean changed = false; final int clauses = mustClauses.size() + mustNotClauses.size() + filterClauses.size() + shouldClauses.size(); @@ -498,20 +498,20 @@ public class BoolQueryBuilder extends AbstractQueryBuilder { @Override protected void extractInnerHitBuilders(Map innerHits) { - List> clauses = new ArrayList<>(filter()); + List clauses = new ArrayList<>(filter()); clauses.addAll(must()); clauses.addAll(should()); // no need to include must_not (since there will be no hits for it) - for (QueryBuilder clause : clauses) { + for (QueryBuilder clause : clauses) { InnerHitBuilder.extractInnerHits(clause, innerHits); } } - private static boolean rewriteClauses(QueryRewriteContext queryRewriteContext, List> builders, - Consumer> consumer) throws IOException { + private static boolean rewriteClauses(QueryRewriteContext queryRewriteContext, List builders, + Consumer consumer) throws IOException { boolean changed = false; - for (QueryBuilder builder : builders) { - QueryBuilder result = builder.rewrite(queryRewriteContext); + for (QueryBuilder builder : builders) { + QueryBuilder result = builder.rewrite(queryRewriteContext); if (result != builder) { changed = true; } diff --git a/core/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java index fa439bc71d8..496cb7ec8a7 100644 --- a/core/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java @@ -53,9 +53,9 @@ public class BoostingQueryBuilder extends AbstractQueryBuilder positiveQuery; + private final QueryBuilder positiveQuery; - private final QueryBuilder negativeQuery; + private final QueryBuilder negativeQuery; private float negativeBoost = -1; @@ -66,7 +66,7 @@ public class BoostingQueryBuilder extends AbstractQueryBuilder positiveQuery, QueryBuilder negativeQuery) { + public BoostingQueryBuilder(QueryBuilder positiveQuery, QueryBuilder negativeQuery) { if (positiveQuery == null) { throw new IllegalArgumentException("inner clause [positive] cannot be null."); } @@ -226,7 +226,7 @@ public class BoostingQueryBuilder extends AbstractQueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { + protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { QueryBuilder positiveQuery = this.positiveQuery.rewrite(queryRewriteContext); QueryBuilder negativeQuery = this.negativeQuery.rewrite(queryRewriteContext); if (positiveQuery != this.positiveQuery || negativeQuery != this.negativeQuery) { diff --git a/core/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java index 8ae2a088f2f..306a4568576 100644 --- a/core/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/ConstantScoreQueryBuilder.java @@ -43,7 +43,7 @@ public class ConstantScoreQueryBuilder extends AbstractQueryBuilder filterBuilder; + private final QueryBuilder filterBuilder; /** * A query that wraps another query and simply returns a constant score equal to the @@ -51,7 +51,7 @@ public class ConstantScoreQueryBuilder extends AbstractQueryBuilder filterBuilder) { + public ConstantScoreQueryBuilder(QueryBuilder filterBuilder) { if (filterBuilder == null) { throw new IllegalArgumentException("inner clause [filter] cannot be null."); } @@ -74,7 +74,7 @@ public class ConstantScoreQueryBuilder extends AbstractQueryBuilder innerQuery() { + public QueryBuilder innerQuery() { return this.filterBuilder; } @@ -90,7 +90,7 @@ public class ConstantScoreQueryBuilder extends AbstractQueryBuilder query = null; + QueryBuilder query = null; boolean queryFound = false; String queryName = null; float boost = AbstractQueryBuilder.DEFAULT_BOOST; @@ -163,8 +163,8 @@ public class ConstantScoreQueryBuilder extends AbstractQueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { - QueryBuilder rewrite = filterBuilder.rewrite(queryRewriteContext); + protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { + QueryBuilder rewrite = filterBuilder.rewrite(queryRewriteContext); if (rewrite != filterBuilder) { return new ConstantScoreQueryBuilder(rewrite); } diff --git a/core/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java index 04662fbe863..f38b2c09b16 100644 --- a/core/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/DisMaxQueryBuilder.java @@ -50,7 +50,7 @@ public class DisMaxQueryBuilder extends AbstractQueryBuilder private static final ParseField TIE_BREAKER_FIELD = new ParseField("tie_breaker"); private static final ParseField QUERIES_FIELD = new ParseField("queries"); - private final List> queries = new ArrayList<>(); + private final List queries = new ArrayList<>(); private float tieBreaker = DEFAULT_TIE_BREAKER; @@ -75,7 +75,7 @@ public class DisMaxQueryBuilder extends AbstractQueryBuilder /** * Add a sub-query to this disjunction. */ - public DisMaxQueryBuilder add(QueryBuilder queryBuilder) { + public DisMaxQueryBuilder add(QueryBuilder queryBuilder) { if (queryBuilder == null) { throw new IllegalArgumentException("inner dismax query clause cannot be null"); } @@ -86,7 +86,7 @@ public class DisMaxQueryBuilder extends AbstractQueryBuilder /** * @return an immutable list copy of the current sub-queries of this disjunction */ - public List> innerQueries() { + public List innerQueries() { return this.queries; } @@ -114,7 +114,7 @@ public class DisMaxQueryBuilder extends AbstractQueryBuilder builder.startObject(NAME); builder.field(TIE_BREAKER_FIELD.getPreferredName(), tieBreaker); builder.startArray(QUERIES_FIELD.getPreferredName()); - for (QueryBuilder queryBuilder : queries) { + for (QueryBuilder queryBuilder : queries) { queryBuilder.toXContent(builder, params); } builder.endArray(); @@ -128,7 +128,7 @@ public class DisMaxQueryBuilder extends AbstractQueryBuilder float boost = AbstractQueryBuilder.DEFAULT_BOOST; float tieBreaker = DisMaxQueryBuilder.DEFAULT_TIE_BREAKER; - final List> queries = new ArrayList<>(); + final List queries = new ArrayList<>(); boolean queriesFound = false; String queryName = null; @@ -140,7 +140,7 @@ public class DisMaxQueryBuilder extends AbstractQueryBuilder } else if (token == XContentParser.Token.START_OBJECT) { if (parseContext.getParseFieldMatcher().match(currentFieldName, QUERIES_FIELD)) { queriesFound = true; - QueryBuilder query = parseContext.parseInnerQueryBuilder(); + QueryBuilder query = parseContext.parseInnerQueryBuilder(); queries.add(query); } else { throw new ParsingException(parser.getTokenLocation(), "[dis_max] query does not support [" + currentFieldName + "]"); @@ -149,7 +149,7 @@ public class DisMaxQueryBuilder extends AbstractQueryBuilder if (parseContext.getParseFieldMatcher().match(currentFieldName, QUERIES_FIELD)) { queriesFound = true; while (token != XContentParser.Token.END_ARRAY) { - QueryBuilder query = parseContext.parseInnerQueryBuilder(); + QueryBuilder query = parseContext.parseInnerQueryBuilder(); queries.add(query); token = parser.nextToken(); } @@ -177,7 +177,7 @@ public class DisMaxQueryBuilder extends AbstractQueryBuilder disMaxQuery.tieBreaker(tieBreaker); disMaxQuery.queryName(queryName); disMaxQuery.boost(boost); - for (QueryBuilder query : queries) { + for (QueryBuilder query : queries) { disMaxQuery.add(query); } return disMaxQuery; diff --git a/core/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java index e44f2868040..0382f353cb3 100644 --- a/core/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/FieldMaskingSpanQueryBuilder.java @@ -35,7 +35,7 @@ import java.io.IOException; import java.util.Objects; public class FieldMaskingSpanQueryBuilder extends AbstractQueryBuilder - implements SpanQueryBuilder{ + implements SpanQueryBuilder { public static final String NAME = "field_masking_span"; public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME); @@ -43,7 +43,7 @@ public class FieldMaskingSpanQueryBuilder extends AbstractQueryBuilder queryBuilder; + private final SpanQueryBuilder queryBuilder; private final String fieldName; @@ -53,7 +53,7 @@ public class FieldMaskingSpanQueryBuilder extends AbstractQueryBuilder queryBuilder, String fieldName) { + public FieldMaskingSpanQueryBuilder(SpanQueryBuilder queryBuilder, String fieldName) { if (Strings.isEmpty(fieldName)) { throw new IllegalArgumentException("field name is null or empty"); } @@ -69,7 +69,7 @@ public class FieldMaskingSpanQueryBuilder extends AbstractQueryBuilder) in.readNamedWriteable(QueryBuilder.class); + queryBuilder = (SpanQueryBuilder) in.readNamedWriteable(QueryBuilder.class); fieldName = in.readString(); } diff --git a/core/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java index 7604ef94eb6..70b4f5eb7f5 100644 --- a/core/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/FuzzyQueryBuilder.java @@ -45,7 +45,7 @@ import java.util.Objects; * a match query with the fuzziness parameter for strings or range queries for numeric and date fields. */ @Deprecated -public class FuzzyQueryBuilder extends AbstractQueryBuilder implements MultiTermQueryBuilder { +public class FuzzyQueryBuilder extends AbstractQueryBuilder implements MultiTermQueryBuilder { public static final String NAME = "fuzzy"; public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME); diff --git a/core/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java index d3c47d5bc70..8b3c8a62486 100644 --- a/core/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/GeoShapeQueryBuilder.java @@ -587,7 +587,7 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder doRewrite(QueryRewriteContext queryShardContext) throws IOException { + protected QueryBuilder doRewrite(QueryRewriteContext queryShardContext) throws IOException { if (this.shape == null) { GetRequest getRequest = new GetRequest(indexedShapeIndex, indexedShapeType, indexedShapeId); ShapeBuilder shape = fetch(queryShardContext.getClient(), getRequest, indexedShapePath); diff --git a/core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java index 61466ab5ea5..990b5a35fd9 100644 --- a/core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java @@ -77,7 +77,7 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder query; + private final QueryBuilder query; private final String type; private final ScoreMode scoreMode; private InnerHitBuilder innerHitBuilder; @@ -85,11 +85,11 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder query, ScoreMode scoreMode) { + public HasChildQueryBuilder(String type, QueryBuilder query, ScoreMode scoreMode) { this(type, query, DEFAULT_MIN_CHILDREN, DEFAULT_MAX_CHILDREN, scoreMode, null); } - private HasChildQueryBuilder(String type, QueryBuilder query, int minChildren, int maxChildren, ScoreMode scoreMode, + private HasChildQueryBuilder(String type, QueryBuilder query, int minChildren, int maxChildren, ScoreMode scoreMode, InnerHitBuilder innerHitBuilder) { this.type = requireValue(type, "[" + NAME + "] requires 'type' field"); this.query = requireValue(query, "[" + NAME + "] requires 'query' field"); @@ -158,7 +158,7 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder query() { + public QueryBuilder query() { return query; } @@ -238,7 +238,7 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder iqb = null; + QueryBuilder iqb = null; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); @@ -467,8 +467,8 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { - QueryBuilder rewrite = query.rewrite(queryRewriteContext); + protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { + QueryBuilder rewrite = query.rewrite(queryRewriteContext); if (rewrite != query) { return new HasChildQueryBuilder(type, rewrite, minChildren, minChildren, scoreMode, innerHitBuilder); } diff --git a/core/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java index dc3b4d9c66a..96356c276e7 100644 --- a/core/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/HasParentQueryBuilder.java @@ -60,17 +60,17 @@ public class HasParentQueryBuilder extends AbstractQueryBuilder query; + private final QueryBuilder query; private final String type; private final boolean score; private InnerHitBuilder innerHit; private boolean ignoreUnmapped = false; - public HasParentQueryBuilder(String type, QueryBuilder query, boolean score) { + public HasParentQueryBuilder(String type, QueryBuilder query, boolean score) { this(type, query, score, null); } - private HasParentQueryBuilder(String type, QueryBuilder query, boolean score, InnerHitBuilder innerHit) { + private HasParentQueryBuilder(String type, QueryBuilder query, boolean score, InnerHitBuilder innerHit) { this.type = requireValue(type, "[" + NAME + "] requires 'type' field"); this.query = requireValue(query, "[" + NAME + "] requires 'query' field"); this.score = score; @@ -101,7 +101,7 @@ public class HasParentQueryBuilder extends AbstractQueryBuilder query() { + public QueryBuilder query() { return query; } @@ -238,7 +238,7 @@ public class HasParentQueryBuilder extends AbstractQueryBuilder iqb = null; + QueryBuilder iqb = null; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); @@ -306,8 +306,8 @@ public class HasParentQueryBuilder extends AbstractQueryBuilder doRewrite(QueryRewriteContext queryShardContext) throws IOException { - QueryBuilder rewrite = query.rewrite(queryShardContext); + protected QueryBuilder doRewrite(QueryRewriteContext queryShardContext) throws IOException { + QueryBuilder rewrite = query.rewrite(queryShardContext); if (rewrite != query) { return new HasParentQueryBuilder(type, rewrite, score, innerHit); } diff --git a/core/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java index 56fdeb779fa..7cfdf1baa1e 100644 --- a/core/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/IndicesQueryBuilder.java @@ -55,17 +55,17 @@ public class IndicesQueryBuilder extends AbstractQueryBuilder innerQuery; + private final QueryBuilder innerQuery; private final String[] indices; - private QueryBuilder noMatchQuery = defaultNoMatchQuery(); + private QueryBuilder noMatchQuery = defaultNoMatchQuery(); /** * @deprecated instead search on the `_index` field */ @Deprecated - public IndicesQueryBuilder(QueryBuilder innerQuery, String... indices) { + public IndicesQueryBuilder(QueryBuilder innerQuery, String... indices) { DEPRECATION_LOGGER.deprecated("{} query is deprecated. Instead search on the '_index' field", NAME); if (innerQuery == null) { throw new IllegalArgumentException("inner query cannot be null"); @@ -94,7 +94,7 @@ public class IndicesQueryBuilder extends AbstractQueryBuilder innerQuery() { + public QueryBuilder innerQuery() { return this.innerQuery; } @@ -105,7 +105,7 @@ public class IndicesQueryBuilder extends AbstractQueryBuilder noMatchQuery) { + public IndicesQueryBuilder noMatchQuery(QueryBuilder noMatchQuery) { if (noMatchQuery == null) { throw new IllegalArgumentException("noMatch query cannot be null"); } @@ -121,11 +121,11 @@ public class IndicesQueryBuilder extends AbstractQueryBuilder noMatchQuery() { + public QueryBuilder noMatchQuery() { return this.noMatchQuery; } - private static QueryBuilder defaultNoMatchQuery() { + private static QueryBuilder defaultNoMatchQuery() { return QueryBuilders.matchAllQuery(); } @@ -144,9 +144,9 @@ public class IndicesQueryBuilder extends AbstractQueryBuilder innerQuery = null; + QueryBuilder innerQuery = null; Collection indices = new ArrayList<>(); - QueryBuilder noMatchQuery = defaultNoMatchQuery(); + QueryBuilder noMatchQuery = defaultNoMatchQuery(); String queryName = null; float boost = AbstractQueryBuilder.DEFAULT_BOOST; @@ -209,7 +209,7 @@ public class IndicesQueryBuilder extends AbstractQueryBuilder parseNoMatchQuery(String type) { + static QueryBuilder parseNoMatchQuery(String type) { if ("all".equals(type)) { return QueryBuilders.matchAllQuery(); } else if ("none".equals(type)) { @@ -244,9 +244,9 @@ public class IndicesQueryBuilder extends AbstractQueryBuilder doRewrite(QueryRewriteContext queryShardContext) throws IOException { - QueryBuilder newInnnerQuery = innerQuery.rewrite(queryShardContext); - QueryBuilder newNoMatchQuery = noMatchQuery.rewrite(queryShardContext); + protected QueryBuilder doRewrite(QueryRewriteContext queryShardContext) throws IOException { + QueryBuilder newInnnerQuery = innerQuery.rewrite(queryShardContext); + QueryBuilder newNoMatchQuery = noMatchQuery.rewrite(queryShardContext); if (newInnnerQuery != innerQuery || newNoMatchQuery != noMatchQuery) { return new IndicesQueryBuilder(innerQuery, indices).noMatchQuery(noMatchQuery); } diff --git a/core/src/main/java/org/elasticsearch/index/query/InnerHitBuilder.java b/core/src/main/java/org/elasticsearch/index/query/InnerHitBuilder.java index 61663713c8e..b62b5a18a1d 100644 --- a/core/src/main/java/org/elasticsearch/index/query/InnerHitBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/InnerHitBuilder.java @@ -18,7 +18,6 @@ */ package org.elasticsearch.index.query; -import org.apache.lucene.search.Sort; import org.elasticsearch.action.support.ToXContentToBytes; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.ParsingException; @@ -41,6 +40,7 @@ import org.elasticsearch.search.fetch.innerhits.InnerHitsContext; import org.elasticsearch.search.fetch.source.FetchSourceContext; import org.elasticsearch.search.highlight.HighlightBuilder; import org.elasticsearch.search.internal.SearchContext; +import org.elasticsearch.search.sort.SortAndFormats; import org.elasticsearch.search.sort.SortBuilder; import java.io.IOException; @@ -131,7 +131,7 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl private boolean trackScores; private List fieldNames; - private QueryBuilder query = new MatchAllQueryBuilder(); + private QueryBuilder query = new MatchAllQueryBuilder(); private List> sorts; private List fieldDataFields; private Set scriptFields; @@ -411,7 +411,7 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl return this; } - QueryBuilder getQuery() { + QueryBuilder getQuery() { return query; } @@ -512,7 +512,7 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl innerHitsContext.fetchSourceContext(fetchSourceContext); } if (sorts != null) { - Optional optionalSort = SortBuilder.buildSort(sorts, context); + Optional optionalSort = SortBuilder.buildSort(sorts, context); if (optionalSort.isPresent()) { innerHitsContext.sort(optionalSort.get()); } @@ -632,7 +632,7 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl return PARSER.parse(context.parser(), new InnerHitBuilder(), context); } - public static void extractInnerHits(QueryBuilder query, Map innerHitBuilders) { + public static void extractInnerHits(QueryBuilder query, Map innerHitBuilders) { if (query instanceof AbstractQueryBuilder) { ((AbstractQueryBuilder) query).extractInnerHitBuilders(innerHitBuilders); } else { diff --git a/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java index c71db8c22a5..66f623cbbb3 100644 --- a/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java @@ -57,7 +57,6 @@ import org.elasticsearch.index.mapper.core.KeywordFieldMapper.KeywordFieldType; import org.elasticsearch.index.mapper.core.StringFieldMapper.StringFieldType; import org.elasticsearch.index.mapper.core.TextFieldMapper.TextFieldType; import org.elasticsearch.index.mapper.internal.UidFieldMapper; -import org.elasticsearch.search.internal.SearchContext; import java.io.IOException; import java.util.ArrayList; @@ -1197,7 +1196,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { + protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { // TODO this needs heavy cleanups before we can rewrite it return this; } diff --git a/core/src/main/java/org/elasticsearch/index/query/MultiTermQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/MultiTermQueryBuilder.java index 0e946d628a1..be9abfc5e44 100644 --- a/core/src/main/java/org/elasticsearch/index/query/MultiTermQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/MultiTermQueryBuilder.java @@ -18,6 +18,6 @@ */ package org.elasticsearch.index.query; -public interface MultiTermQueryBuilder> extends QueryBuilder { +public interface MultiTermQueryBuilder extends QueryBuilder { } diff --git a/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java index bba0365d0ae..5d74b540116 100644 --- a/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java @@ -57,7 +57,7 @@ public class NestedQueryBuilder extends AbstractQueryBuilder private final String path; private final ScoreMode scoreMode; - private final QueryBuilder query; + private final QueryBuilder query; private InnerHitBuilder innerHitBuilder; private boolean ignoreUnmapped = DEFAULT_IGNORE_UNMAPPED; @@ -161,7 +161,7 @@ public class NestedQueryBuilder extends AbstractQueryBuilder float boost = AbstractQueryBuilder.DEFAULT_BOOST; ScoreMode scoreMode = ScoreMode.Avg; String queryName = null; - QueryBuilder query = null; + QueryBuilder query = null; String path = null; String currentFieldName = null; InnerHitBuilder innerHitBuilder = null; @@ -259,7 +259,7 @@ public class NestedQueryBuilder extends AbstractQueryBuilder } @Override - protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { + protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { QueryBuilder rewrite = query.rewrite(queryRewriteContext); if (rewrite != query) { return new NestedQueryBuilder(path, rewrite, scoreMode, innerHitBuilder); diff --git a/core/src/main/java/org/elasticsearch/index/query/PercolateQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/PercolateQueryBuilder.java index 257460964d3..0e4b999dc33 100644 --- a/core/src/main/java/org/elasticsearch/index/query/PercolateQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/PercolateQueryBuilder.java @@ -327,7 +327,7 @@ public class PercolateQueryBuilder extends AbstractQueryBuilder doRewrite(QueryRewriteContext queryShardContext) throws IOException { + protected QueryBuilder doRewrite(QueryRewriteContext queryShardContext) throws IOException { if (document != null) { return this; } diff --git a/core/src/main/java/org/elasticsearch/index/query/PrefixQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/PrefixQueryBuilder.java index ffb4179aa3f..44677d1840d 100644 --- a/core/src/main/java/org/elasticsearch/index/query/PrefixQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/PrefixQueryBuilder.java @@ -40,7 +40,7 @@ import java.util.Objects; /** * A Query that matches documents containing terms with a specified prefix. */ -public class PrefixQueryBuilder extends AbstractQueryBuilder implements MultiTermQueryBuilder { +public class PrefixQueryBuilder extends AbstractQueryBuilder implements MultiTermQueryBuilder { public static final String NAME = "prefix"; public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME); diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/QueryBuilder.java index dcedd0f1d5e..197af655d54 100644 --- a/core/src/main/java/org/elasticsearch/index/query/QueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/QueryBuilder.java @@ -25,7 +25,7 @@ import org.elasticsearch.common.xcontent.ToXContent; import java.io.IOException; -public interface QueryBuilder> extends NamedWriteable, ToXContent { +public interface QueryBuilder extends NamedWriteable, ToXContent { /** * Converts this QueryBuilder to a lucene {@link Query}. @@ -49,8 +49,11 @@ public interface QueryBuilder> extends NamedWriteabl /** * Sets the arbitrary name to be assigned to the query (see named queries). + * Implementers should return the concrete type of the + * {@link QueryBuilder} so that calls can be chained. This is done + * automatically when extending {@link AbstractQueryBuilder}. */ - QB queryName(String queryName); + QueryBuilder queryName(String queryName); /** * Returns the arbitrary name assigned to the query (see named queries). @@ -65,8 +68,11 @@ public interface QueryBuilder> extends NamedWriteabl /** * Sets the boost for this query. Documents matching this query will (in addition to the normal * weightings) have their score multiplied by the boost provided. + * Implementers should return the concrete type of the + * {@link QueryBuilder} so that calls can be chained. This is done + * automatically when extending {@link AbstractQueryBuilder}. */ - QB boost(float boost); + QueryBuilder boost(float boost); /** * Returns the name that identifies uniquely the query @@ -77,7 +83,7 @@ public interface QueryBuilder> extends NamedWriteabl * Rewrites this query builder into its primitive form. By default this method return the builder itself. If the builder * did not change the identity reference must be returned otherwise the builder will be rewritten infinitely. */ - default QueryBuilder rewrite(QueryRewriteContext queryShardContext) throws IOException { + default QueryBuilder rewrite(QueryRewriteContext queryShardContext) throws IOException { return this; } @@ -87,7 +93,7 @@ public interface QueryBuilder> extends NamedWriteabl * rewrites the query until it doesn't change anymore. * @throws IOException if an {@link IOException} occurs */ - static QueryBuilder rewriteQuery(QueryBuilder original, QueryRewriteContext context) throws IOException { + static QueryBuilder rewriteQuery(QueryBuilder original, QueryRewriteContext context) throws IOException { QueryBuilder builder = original; for (QueryBuilder rewrittenBuilder = builder.rewrite(context); rewrittenBuilder != builder; rewrittenBuilder = builder.rewrite(context)) { diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java b/core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java index 1199330ee4f..62662914fd8 100644 --- a/core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java +++ b/core/src/main/java/org/elasticsearch/index/query/QueryParseContext.java @@ -55,9 +55,9 @@ public class QueryParseContext implements ParseFieldMatcherSupplier { /** * Parses a top level query including the query element that wraps it */ - public QueryBuilder parseTopLevelQueryBuilder() { + public QueryBuilder parseTopLevelQueryBuilder() { try { - QueryBuilder queryBuilder = null; + QueryBuilder queryBuilder = null; for (XContentParser.Token token = parser.nextToken(); token != XContentParser.Token.END_OBJECT; token = parser.nextToken()) { if (token == XContentParser.Token.FIELD_NAME) { String fieldName = parser.currentName(); @@ -82,7 +82,7 @@ public class QueryParseContext implements ParseFieldMatcherSupplier { /** * Parses a query excluding the query element that wraps it */ - public QueryBuilder parseInnerQueryBuilder() throws IOException { + public QueryBuilder parseInnerQueryBuilder() throws IOException { // move to START object XContentParser.Token token; if (parser.currentToken() != XContentParser.Token.START_OBJECT) { @@ -105,7 +105,7 @@ public class QueryParseContext implements ParseFieldMatcherSupplier { if (token != XContentParser.Token.START_OBJECT && token != XContentParser.Token.START_ARRAY) { throw new ParsingException(parser.getTokenLocation(), "[_na] query malformed, no field after start_object"); } - QueryBuilder result = indicesQueriesRegistry.lookup(queryName, parseFieldMatcher, parser.getTokenLocation()).fromXContent(this); + QueryBuilder result = indicesQueriesRegistry.lookup(queryName, parseFieldMatcher, parser.getTokenLocation()).fromXContent(this); if (parser.currentToken() == XContentParser.Token.END_OBJECT || parser.currentToken() == XContentParser.Token.END_ARRAY) { // if we are at END_OBJECT, move to the next one... parser.nextToken(); diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryParser.java b/core/src/main/java/org/elasticsearch/index/query/QueryParser.java index 6f27b8e0647..069dc86cf8a 100644 --- a/core/src/main/java/org/elasticsearch/index/query/QueryParser.java +++ b/core/src/main/java/org/elasticsearch/index/query/QueryParser.java @@ -25,7 +25,7 @@ import java.io.IOException; * Defines a query parser that is able to parse {@link QueryBuilder}s from {@link org.elasticsearch.common.xcontent.XContent}. */ @FunctionalInterface -public interface QueryParser> { +public interface QueryParser { /** * Creates a new {@link QueryBuilder} from the query held by the {@link QueryParseContext} * in {@link org.elasticsearch.common.xcontent.XContent} format diff --git a/core/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java index 5890e2bdffe..241c38475ab 100644 --- a/core/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/RangeQueryBuilder.java @@ -46,7 +46,7 @@ import java.util.Objects; /** * A Query that matches documents within an range of terms. */ -public class RangeQueryBuilder extends AbstractQueryBuilder implements MultiTermQueryBuilder { +public class RangeQueryBuilder extends AbstractQueryBuilder implements MultiTermQueryBuilder { public static final String NAME = "range"; public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME); @@ -410,7 +410,7 @@ public class RangeQueryBuilder extends AbstractQueryBuilder i } @Override - protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { + protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { final MappedFieldType.Relation relation = getRelation(queryRewriteContext); switch (relation) { case DISJOINT: diff --git a/core/src/main/java/org/elasticsearch/index/query/RegexpQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/RegexpQueryBuilder.java index c895830d5a5..703b2463b11 100644 --- a/core/src/main/java/org/elasticsearch/index/query/RegexpQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/RegexpQueryBuilder.java @@ -41,7 +41,7 @@ import java.util.Objects; /** * A Query that does fuzzy matching for a specific value. */ -public class RegexpQueryBuilder extends AbstractQueryBuilder implements MultiTermQueryBuilder { +public class RegexpQueryBuilder extends AbstractQueryBuilder implements MultiTermQueryBuilder { public static final String NAME = "regexp"; public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME); diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanContainingQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanContainingQueryBuilder.java index d923b219897..ae4297e431d 100644 --- a/core/src/main/java/org/elasticsearch/index/query/SpanContainingQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/SpanContainingQueryBuilder.java @@ -36,7 +36,7 @@ import java.util.Objects; * Builder for {@link org.apache.lucene.search.spans.SpanContainingQuery}. */ public class SpanContainingQueryBuilder extends AbstractQueryBuilder - implements SpanQueryBuilder { + implements SpanQueryBuilder { public static final String NAME = "span_containing"; public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME); @@ -44,14 +44,14 @@ public class SpanContainingQueryBuilder extends AbstractQueryBuilder big; - private final SpanQueryBuilder little; + private final SpanQueryBuilder big; + private final SpanQueryBuilder little; /** * @param big the big clause, it must enclose {@code little} for a match. * @param little the little clause, it must be contained within {@code big} for a match. */ - public SpanContainingQueryBuilder(SpanQueryBuilder big, SpanQueryBuilder little) { + public SpanContainingQueryBuilder(SpanQueryBuilder big, SpanQueryBuilder little) { if (big == null) { throw new IllegalArgumentException("inner clause [big] cannot be null."); } @@ -67,8 +67,8 @@ public class SpanContainingQueryBuilder extends AbstractQueryBuilder) in.readNamedWriteable(QueryBuilder.class); - little = (SpanQueryBuilder) in.readNamedWriteable(QueryBuilder.class); + big = (SpanQueryBuilder) in.readNamedWriteable(QueryBuilder.class); + little = (SpanQueryBuilder) in.readNamedWriteable(QueryBuilder.class); } @Override @@ -106,8 +106,8 @@ public class SpanContainingQueryBuilder extends AbstractQueryBuilder big = null; - SpanQueryBuilder little = null; + SpanQueryBuilder big = null; + SpanQueryBuilder little = null; String currentFieldName = null; XContentParser.Token token; @@ -117,16 +117,16 @@ public class SpanContainingQueryBuilder extends AbstractQueryBuilder)) { + if (!(query instanceof SpanQueryBuilder)) { throw new ParsingException(parser.getTokenLocation(), "span_containing [big] must be of type span query"); } - big = (SpanQueryBuilder) query; + big = (SpanQueryBuilder) query; } else if (parseContext.getParseFieldMatcher().match(currentFieldName, LITTLE_FIELD)) { QueryBuilder query = parseContext.parseInnerQueryBuilder(); - if (!(query instanceof SpanQueryBuilder)) { + if (!(query instanceof SpanQueryBuilder)) { throw new ParsingException(parser.getTokenLocation(), "span_containing [little] must be of type span query"); } - little = (SpanQueryBuilder) query; + little = (SpanQueryBuilder) query; } else { throw new ParsingException(parser.getTokenLocation(), "[span_containing] query does not support [" + currentFieldName + "]"); diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanFirstQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanFirstQueryBuilder.java index 58e80af977f..009f8a39652 100644 --- a/core/src/main/java/org/elasticsearch/index/query/SpanFirstQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/SpanFirstQueryBuilder.java @@ -32,7 +32,7 @@ import org.elasticsearch.common.xcontent.XContentParser; import java.io.IOException; import java.util.Objects; -public class SpanFirstQueryBuilder extends AbstractQueryBuilder implements SpanQueryBuilder{ +public class SpanFirstQueryBuilder extends AbstractQueryBuilder implements SpanQueryBuilder { public static final String NAME = "span_first"; public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME); @@ -40,7 +40,7 @@ public class SpanFirstQueryBuilder extends AbstractQueryBuilder matchBuilder; + private final SpanQueryBuilder matchBuilder; private final int end; @@ -51,7 +51,7 @@ public class SpanFirstQueryBuilder extends AbstractQueryBuilderend positions */ - public SpanFirstQueryBuilder(SpanQueryBuilder matchBuilder, int end) { + public SpanFirstQueryBuilder(SpanQueryBuilder matchBuilder, int end) { if (matchBuilder == null) { throw new IllegalArgumentException("inner span query cannot be null"); } @@ -67,7 +67,7 @@ public class SpanFirstQueryBuilder extends AbstractQueryBuilder) in.readNamedWriteable(QueryBuilder.class); + matchBuilder = (SpanQueryBuilder) in.readNamedWriteable(QueryBuilder.class); end = in.readInt(); } @@ -80,7 +80,7 @@ public class SpanFirstQueryBuilder extends AbstractQueryBuilder innerQuery() { + public SpanQueryBuilder innerQuery() { return this.matchBuilder; } diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanMultiTermQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanMultiTermQueryBuilder.java index 46f639f5f70..86418903f70 100644 --- a/core/src/main/java/org/elasticsearch/index/query/SpanMultiTermQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/SpanMultiTermQueryBuilder.java @@ -39,16 +39,16 @@ import java.util.Objects; * as a {@link SpanQueryBuilder} so it can be nested. */ public class SpanMultiTermQueryBuilder extends AbstractQueryBuilder - implements SpanQueryBuilder { + implements SpanQueryBuilder { public static final String NAME = "span_multi"; public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME); private static final ParseField MATCH_FIELD = new ParseField("match"); - private final MultiTermQueryBuilder multiTermQueryBuilder; + private final MultiTermQueryBuilder multiTermQueryBuilder; - public SpanMultiTermQueryBuilder(MultiTermQueryBuilder multiTermQueryBuilder) { + public SpanMultiTermQueryBuilder(MultiTermQueryBuilder multiTermQueryBuilder) { if (multiTermQueryBuilder == null) { throw new IllegalArgumentException("inner multi term query cannot be null"); } @@ -60,7 +60,7 @@ public class SpanMultiTermQueryBuilder extends AbstractQueryBuilder) in.readNamedWriteable(QueryBuilder.class); + multiTermQueryBuilder = (MultiTermQueryBuilder) in.readNamedWriteable(QueryBuilder.class); } @Override @@ -68,7 +68,7 @@ public class SpanMultiTermQueryBuilder extends AbstractQueryBuilder innerQuery() { + public MultiTermQueryBuilder innerQuery() { return this.multiTermQueryBuilder; } diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java index 1bd8e85b902..a503b708633 100644 --- a/core/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java @@ -39,7 +39,7 @@ import java.util.Objects; * of intervening unmatched positions, as well as whether matches are required to be in-order. * The span near query maps to Lucene {@link SpanNearQuery}. */ -public class SpanNearQueryBuilder extends AbstractQueryBuilder implements SpanQueryBuilder { +public class SpanNearQueryBuilder extends AbstractQueryBuilder implements SpanQueryBuilder { public static final String NAME = "span_near"; public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME); @@ -52,7 +52,7 @@ public class SpanNearQueryBuilder extends AbstractQueryBuilder> clauses = new ArrayList<>(); + private final List clauses = new ArrayList<>(); private final int slop; @@ -62,7 +62,7 @@ public class SpanNearQueryBuilder extends AbstractQueryBuilder initialClause, int slop) { + public SpanNearQueryBuilder(SpanQueryBuilder initialClause, int slop) { if (initialClause == null) { throw new IllegalArgumentException("query must include at least one clause"); } @@ -75,8 +75,8 @@ public class SpanNearQueryBuilder extends AbstractQueryBuilder clause : readQueries(in)) { - this.clauses.add((SpanQueryBuilder) clause); + for (QueryBuilder clause : readQueries(in)) { + this.clauses.add((SpanQueryBuilder) clause); } slop = in.readVInt(); inOrder = in.readBoolean(); @@ -96,7 +96,7 @@ public class SpanNearQueryBuilder extends AbstractQueryBuilder clause) { + public SpanNearQueryBuilder clause(SpanQueryBuilder clause) { if (clause == null) { throw new IllegalArgumentException("query clauses cannot be null"); } @@ -107,7 +107,7 @@ public class SpanNearQueryBuilder extends AbstractQueryBuilder> clauses() { + public List clauses() { return this.clauses; } @@ -132,7 +132,7 @@ public class SpanNearQueryBuilder extends AbstractQueryBuilder clause : clauses) { + for (SpanQueryBuilder clause : clauses) { clause.toXContent(builder, params); } builder.endArray(); diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanNotQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanNotQueryBuilder.java index aa2388dd89a..02ce431de1e 100644 --- a/core/src/main/java/org/elasticsearch/index/query/SpanNotQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/SpanNotQueryBuilder.java @@ -32,7 +32,7 @@ import org.elasticsearch.common.xcontent.XContentParser; import java.io.IOException; import java.util.Objects; -public class SpanNotQueryBuilder extends AbstractQueryBuilder implements SpanQueryBuilder { +public class SpanNotQueryBuilder extends AbstractQueryBuilder implements SpanQueryBuilder { public static final String NAME = "span_not"; public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME); @@ -48,9 +48,9 @@ public class SpanNotQueryBuilder extends AbstractQueryBuilder include; + private final SpanQueryBuilder include; - private final SpanQueryBuilder exclude; + private final SpanQueryBuilder exclude; private int pre = DEFAULT_PRE; @@ -62,7 +62,7 @@ public class SpanNotQueryBuilder extends AbstractQueryBuilder include, SpanQueryBuilder exclude) { + public SpanNotQueryBuilder(SpanQueryBuilder include, SpanQueryBuilder exclude) { if (include == null) { throw new IllegalArgumentException("inner clause [include] cannot be null."); } @@ -78,8 +78,8 @@ public class SpanNotQueryBuilder extends AbstractQueryBuilder) in.readNamedWriteable(QueryBuilder.class); - exclude = (SpanQueryBuilder) in.readNamedWriteable(QueryBuilder.class); + include = (SpanQueryBuilder) in.readNamedWriteable(QueryBuilder.class); + exclude = (SpanQueryBuilder) in.readNamedWriteable(QueryBuilder.class); pre = in.readVInt(); post = in.readVInt(); } diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanOrQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanOrQueryBuilder.java index 71b6b74b828..2a67a84be81 100644 --- a/core/src/main/java/org/elasticsearch/index/query/SpanOrQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/SpanOrQueryBuilder.java @@ -37,16 +37,16 @@ import java.util.Objects; /** * Span query that matches the union of its clauses. Maps to {@link SpanOrQuery}. */ -public class SpanOrQueryBuilder extends AbstractQueryBuilder implements SpanQueryBuilder { +public class SpanOrQueryBuilder extends AbstractQueryBuilder implements SpanQueryBuilder { public static final String NAME = "span_or"; public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME); private static final ParseField CLAUSES_FIELD = new ParseField("clauses"); - private final List> clauses = new ArrayList<>(); + private final List clauses = new ArrayList<>(); - public SpanOrQueryBuilder(SpanQueryBuilder initialClause) { + public SpanOrQueryBuilder(SpanQueryBuilder initialClause) { if (initialClause == null) { throw new IllegalArgumentException("query must include at least one clause"); } @@ -58,8 +58,8 @@ public class SpanOrQueryBuilder extends AbstractQueryBuilder */ public SpanOrQueryBuilder(StreamInput in) throws IOException { super(in); - for (QueryBuilder clause: readQueries(in)) { - clauses.add((SpanQueryBuilder) clause); + for (QueryBuilder clause: readQueries(in)) { + clauses.add((SpanQueryBuilder) clause); } } @@ -68,7 +68,7 @@ public class SpanOrQueryBuilder extends AbstractQueryBuilder writeQueries(out, clauses); } - public SpanOrQueryBuilder clause(SpanQueryBuilder clause) { + public SpanOrQueryBuilder clause(SpanQueryBuilder clause) { if (clause == null) { throw new IllegalArgumentException("inner bool query clause cannot be null"); } @@ -79,7 +79,7 @@ public class SpanOrQueryBuilder extends AbstractQueryBuilder /** * @return the {@link SpanQueryBuilder} clauses that were set for this query */ - public List> clauses() { + public List clauses() { return this.clauses; } @@ -87,7 +87,7 @@ public class SpanOrQueryBuilder extends AbstractQueryBuilder protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(NAME); builder.startArray(CLAUSES_FIELD.getPreferredName()); - for (SpanQueryBuilder clause : clauses) { + for (SpanQueryBuilder clause : clauses) { clause.toXContent(builder, params); } builder.endArray(); diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanQueryBuilder.java index 90a75a5af1b..fec1cac2696 100644 --- a/core/src/main/java/org/elasticsearch/index/query/SpanQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/SpanQueryBuilder.java @@ -22,6 +22,6 @@ package org.elasticsearch.index.query; /** * Marker interface for a specific type of {@link QueryBuilder} that allows to build span queries */ -public interface SpanQueryBuilder> extends QueryBuilder { +public interface SpanQueryBuilder extends QueryBuilder { } diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanTermQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanTermQueryBuilder.java index a4bafc5001c..3bb374ff276 100644 --- a/core/src/main/java/org/elasticsearch/index/query/SpanTermQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/SpanTermQueryBuilder.java @@ -36,7 +36,7 @@ import java.io.IOException; * A Span Query that matches documents containing a term. * @see SpanTermQuery */ -public class SpanTermQueryBuilder extends BaseTermQueryBuilder implements SpanQueryBuilder { +public class SpanTermQueryBuilder extends BaseTermQueryBuilder implements SpanQueryBuilder { public static final String NAME = "span_term"; public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME); diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanWithinQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanWithinQueryBuilder.java index cf430881ab9..eaedc80bab4 100644 --- a/core/src/main/java/org/elasticsearch/index/query/SpanWithinQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/SpanWithinQueryBuilder.java @@ -36,7 +36,7 @@ import java.util.Objects; * Builder for {@link org.apache.lucene.search.spans.SpanWithinQuery}. */ public class SpanWithinQueryBuilder extends AbstractQueryBuilder - implements SpanQueryBuilder { + implements SpanQueryBuilder { public static final String NAME = "span_within"; public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME); @@ -44,15 +44,15 @@ public class SpanWithinQueryBuilder extends AbstractQueryBuilder big; - private final SpanQueryBuilder little; + private final SpanQueryBuilder big; + private final SpanQueryBuilder little; /** * Query that returns spans from little that are contained in a spans from big. * @param big clause that must enclose {@code little} for a match. * @param little the little clause, it must be contained within {@code big} for a match. */ - public SpanWithinQueryBuilder(SpanQueryBuilder big, SpanQueryBuilder little) { + public SpanWithinQueryBuilder(SpanQueryBuilder big, SpanQueryBuilder little) { if (big == null) { throw new IllegalArgumentException("inner clause [big] cannot be null."); } @@ -68,8 +68,8 @@ public class SpanWithinQueryBuilder extends AbstractQueryBuilder) in.readNamedWriteable(QueryBuilder.class); - little = (SpanQueryBuilder) in.readNamedWriteable(QueryBuilder.class); + big = (SpanQueryBuilder) in.readNamedWriteable(QueryBuilder.class); + little = (SpanQueryBuilder) in.readNamedWriteable(QueryBuilder.class); } @Override diff --git a/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java index 80b3f2b1404..1a4d05374b3 100644 --- a/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/TemplateQueryBuilder.java @@ -173,13 +173,13 @@ public class TemplateQueryBuilder extends AbstractQueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { + protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { ExecutableScript executable = queryRewriteContext.getScriptService().executable(template, ScriptContext.Standard.SEARCH, Collections.emptyMap(), queryRewriteContext.getClusterState()); BytesReference querySource = (BytesReference) executable.run(); try (XContentParser qSourceParser = XContentFactory.xContent(querySource).createParser(querySource)) { final QueryParseContext queryParseContext = queryRewriteContext.newParseContext(qSourceParser); - final QueryBuilder queryBuilder = queryParseContext.parseInnerQueryBuilder(); + final QueryBuilder queryBuilder = queryParseContext.parseInnerQueryBuilder(); if (boost() != DEFAULT_BOOST || queryName() != null) { final BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); boolQueryBuilder.must(queryBuilder); diff --git a/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java index 084f2e766d4..5b0650eb7e4 100644 --- a/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java @@ -381,7 +381,7 @@ public class TermsQueryBuilder extends AbstractQueryBuilder { } @Override - protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { + protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { if (this.termsLookup != null) { TermsLookup termsLookup = new TermsLookup(this.termsLookup); if (termsLookup.index() == null) { // TODO this should go away? diff --git a/core/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java index bf6921e9452..ef49472b8cc 100644 --- a/core/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java @@ -46,7 +46,7 @@ import java.util.Objects; * ?. */ public class WildcardQueryBuilder extends AbstractQueryBuilder - implements MultiTermQueryBuilder { + implements MultiTermQueryBuilder { public static final String NAME = "wildcard"; public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME); diff --git a/core/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java index 4af7081f308..4037666393d 100644 --- a/core/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/WrapperQueryBuilder.java @@ -160,11 +160,11 @@ public class WrapperQueryBuilder extends AbstractQueryBuilder doRewrite(QueryRewriteContext context) throws IOException { + protected QueryBuilder doRewrite(QueryRewriteContext context) throws IOException { try (XContentParser qSourceParser = XContentFactory.xContent(source).createParser(source)) { QueryParseContext parseContext = context.newParseContext(qSourceParser); - final QueryBuilder queryBuilder = parseContext.parseInnerQueryBuilder(); + final QueryBuilder queryBuilder = parseContext.parseInnerQueryBuilder(); if (boost() != DEFAULT_BOOST || queryName() != null) { final BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); boolQueryBuilder.must(queryBuilder); diff --git a/core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java index 0dffa6d714a..98f878d1c2e 100644 --- a/core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilder.java @@ -75,7 +75,7 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder query; + private final QueryBuilder query; private float maxBoost = FunctionScoreQuery.DEFAULT_MAX_BOOST; @@ -92,7 +92,7 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder query) { + public FunctionScoreQueryBuilder(QueryBuilder query) { this(query, new FilterFunctionBuilder[0]); } @@ -120,7 +120,7 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder query, ScoreFunctionBuilder scoreFunctionBuilder) { + public FunctionScoreQueryBuilder(QueryBuilder query, ScoreFunctionBuilder scoreFunctionBuilder) { this(query, new FilterFunctionBuilder[]{new FilterFunctionBuilder(scoreFunctionBuilder)}); } @@ -130,7 +130,7 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder query, FilterFunctionBuilder[] filterFunctionBuilders) { + public FunctionScoreQueryBuilder(QueryBuilder query, FilterFunctionBuilder[] filterFunctionBuilders) { if (query == null) { throw new IllegalArgumentException("function_score: query must not be null"); } @@ -172,7 +172,7 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder query() { + public QueryBuilder query() { return this.query; } @@ -334,14 +334,14 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder filter; + private final QueryBuilder filter; private final ScoreFunctionBuilder scoreFunction; public FilterFunctionBuilder(ScoreFunctionBuilder scoreFunctionBuilder) { this(new MatchAllQueryBuilder(), scoreFunctionBuilder); } - public FilterFunctionBuilder(QueryBuilder filter, ScoreFunctionBuilder scoreFunction) { + public FilterFunctionBuilder(QueryBuilder filter, ScoreFunctionBuilder scoreFunction) { if (filter == null) { throw new IllegalArgumentException("function_score: filter must not be null"); } @@ -366,7 +366,7 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder getFilter() { + public QueryBuilder getFilter() { return filter; } @@ -403,7 +403,7 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder rewrite = filter.rewrite(context); + QueryBuilder rewrite = filter.rewrite(context); if (rewrite != filter) { return new FilterFunctionBuilder(rewrite, scoreFunction); } @@ -412,8 +412,8 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { - QueryBuilder queryBuilder = this.query.rewrite(queryRewriteContext); + protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { + QueryBuilder queryBuilder = this.query.rewrite(queryRewriteContext); FilterFunctionBuilder[] rewrittenBuilders = new FilterFunctionBuilder[this.filterFunctionBuilders.length]; boolean rewritten = false; for (int i = 0; i < rewrittenBuilders.length; i++) { @@ -442,7 +442,7 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder query = null; + QueryBuilder query = null; float boost = AbstractQueryBuilder.DEFAULT_BOOST; String queryName = null; @@ -571,7 +571,7 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder filter = null; + QueryBuilder filter = null; ScoreFunctionBuilder scoreFunction = null; Float functionWeight = null; if (token != XContentParser.Token.START_OBJECT) { diff --git a/core/src/main/java/org/elasticsearch/indices/store/TransportNodesListShardStoreMetaData.java b/core/src/main/java/org/elasticsearch/indices/store/TransportNodesListShardStoreMetaData.java index e4a1709db55..92c9bd3b575 100644 --- a/core/src/main/java/org/elasticsearch/indices/store/TransportNodesListShardStoreMetaData.java +++ b/core/src/main/java/org/elasticsearch/indices/store/TransportNodesListShardStoreMetaData.java @@ -54,18 +54,20 @@ import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import java.io.IOException; -import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReferenceArray; /** * */ -public class TransportNodesListShardStoreMetaData extends TransportNodesAction - implements AsyncShardFetch.List { +public class TransportNodesListShardStoreMetaData extends TransportNodesAction + implements AsyncShardFetch.Lister { public static final String ACTION_NAME = "internal:cluster/nodes/indices/shard/store"; @@ -74,11 +76,12 @@ public class TransportNodesListShardStoreMetaData extends TransportNodesAction nodeStoreFilesMetaDatas = new ArrayList<>(); - final List failures = new ArrayList<>(); - for (int i = 0; i < responses.length(); i++) { - Object resp = responses.get(i); - if (resp instanceof NodeStoreFilesMetaData) { // will also filter out null response for unallocated ones - nodeStoreFilesMetaDatas.add((NodeStoreFilesMetaData) resp); - } else if (resp instanceof FailedNodeException) { - failures.add((FailedNodeException) resp); - } else { - logger.warn("unknown response type [{}], expected NodeStoreFilesMetaData or FailedNodeException", resp); - } - } - return new NodesStoreFilesMetaData(clusterName, nodeStoreFilesMetaDatas.toArray(new NodeStoreFilesMetaData[nodeStoreFilesMetaDatas.size()]), - failures.toArray(new FailedNodeException[failures.size()])); + protected NodesStoreFilesMetaData newResponse(Request request, + List responses, List failures) { + return new NodesStoreFilesMetaData(clusterName, responses, failures); } @Override @@ -293,37 +284,21 @@ public class TransportNodesListShardStoreMetaData extends TransportNodesAction { - private FailedNodeException[] failures; - NodesStoreFilesMetaData() { } - public NodesStoreFilesMetaData(ClusterName clusterName, NodeStoreFilesMetaData[] nodes, FailedNodeException[] failures) { - super(clusterName, nodes); - this.failures = failures; + public NodesStoreFilesMetaData(ClusterName clusterName, List nodes, List failures) { + super(clusterName, nodes, failures); } @Override - public FailedNodeException[] failures() { - return failures; + protected List readNodesFrom(StreamInput in) throws IOException { + return in.readList(NodeStoreFilesMetaData::readListShardStoreNodeOperationResponse); } @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - nodes = new NodeStoreFilesMetaData[in.readVInt()]; - for (int i = 0; i < nodes.length; i++) { - nodes[i] = NodeStoreFilesMetaData.readListShardStoreNodeOperationResponse(in); - } - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeVInt(nodes.length); - for (NodeStoreFilesMetaData response : nodes) { - response.writeTo(out); - } + protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { + out.writeStreamableList(nodes); } } diff --git a/core/src/main/java/org/elasticsearch/ingest/PipelineExecutionService.java b/core/src/main/java/org/elasticsearch/ingest/PipelineExecutionService.java index 94c79db30a0..8674e805974 100644 --- a/core/src/main/java/org/elasticsearch/ingest/PipelineExecutionService.java +++ b/core/src/main/java/org/elasticsearch/ingest/PipelineExecutionService.java @@ -35,6 +35,7 @@ import org.elasticsearch.threadpool.ThreadPool; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import java.util.Optional; import java.util.concurrent.TimeUnit; @@ -124,9 +125,11 @@ public class PipelineExecutionService implements ClusterStateListener { void updatePipelineStats(IngestMetadata ingestMetadata) { boolean changed = false; Map newStatsPerPipeline = new HashMap<>(statsHolderPerPipeline); - for (String pipeline : newStatsPerPipeline.keySet()) { + Iterator iterator = newStatsPerPipeline.keySet().iterator(); + while (iterator.hasNext()) { + String pipeline = iterator.next(); if (ingestMetadata.getPipelines().containsKey(pipeline) == false) { - newStatsPerPipeline.remove(pipeline); + iterator.remove(); changed = true; } } diff --git a/core/src/main/java/org/elasticsearch/repositories/Repository.java b/core/src/main/java/org/elasticsearch/repositories/Repository.java index 294b36df491..f3c44f29226 100644 --- a/core/src/main/java/org/elasticsearch/repositories/Repository.java +++ b/core/src/main/java/org/elasticsearch/repositories/Repository.java @@ -24,7 +24,7 @@ import org.elasticsearch.cluster.metadata.SnapshotId; import org.elasticsearch.common.component.LifecycleComponent; import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.index.snapshots.IndexShardSnapshotStatus; -import org.elasticsearch.snapshots.Snapshot; +import org.elasticsearch.snapshots.SnapshotInfo; import org.elasticsearch.snapshots.SnapshotShardFailure; import java.io.IOException; @@ -54,7 +54,7 @@ public interface Repository extends LifecycleComponent { * @param snapshotId snapshot ID * @return information about snapshot */ - Snapshot readSnapshot(SnapshotId snapshotId); + SnapshotInfo readSnapshot(SnapshotId snapshotId); /** * Returns global metadata associate with the snapshot. @@ -65,7 +65,7 @@ public interface Repository extends LifecycleComponent { * @param indices list of indices * @return information about snapshot */ - MetaData readSnapshotMetaData(SnapshotId snapshotId, Snapshot snapshot, List indices) throws IOException; + MetaData readSnapshotMetaData(SnapshotId snapshotId, SnapshotInfo snapshot, List indices) throws IOException; /** * Returns the list of snapshots currently stored in the repository @@ -94,7 +94,7 @@ public interface Repository extends LifecycleComponent { * @param shardFailures list of shard failures * @return snapshot description */ - Snapshot finalizeSnapshot(SnapshotId snapshotId, List indices, long startTime, String failure, int totalShards, List shardFailures); + SnapshotInfo finalizeSnapshot(SnapshotId snapshotId, List indices, long startTime, String failure, int totalShards, List shardFailures); /** * Deletes snapshot diff --git a/core/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java b/core/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java index ef0cab5c156..121df3e5832 100644 --- a/core/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java +++ b/core/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java @@ -57,9 +57,9 @@ import org.elasticsearch.repositories.RepositoryException; import org.elasticsearch.repositories.RepositorySettings; import org.elasticsearch.repositories.RepositoryVerificationException; import org.elasticsearch.snapshots.InvalidSnapshotNameException; -import org.elasticsearch.snapshots.Snapshot; import org.elasticsearch.snapshots.SnapshotCreationException; import org.elasticsearch.snapshots.SnapshotException; +import org.elasticsearch.snapshots.SnapshotInfo; import org.elasticsearch.snapshots.SnapshotMissingException; import org.elasticsearch.snapshots.SnapshotShardFailure; @@ -165,9 +165,9 @@ public abstract class BlobStoreRepository extends AbstractLifecycleComponent indexMetaDataLegacyFormat; - private ChecksumBlobStoreFormat snapshotFormat; + private ChecksumBlobStoreFormat snapshotFormat; - private LegacyBlobStoreFormat snapshotLegacyFormat; + private LegacyBlobStoreFormat snapshotLegacyFormat; private final boolean readOnly; @@ -202,8 +202,8 @@ public abstract class BlobStoreRepository extends AbstractLifecycleComponent(INDEX_METADATA_CODEC, METADATA_NAME_FORMAT, IndexMetaData.PROTO, parseFieldMatcher, isCompress()); indexMetaDataLegacyFormat = new LegacyBlobStoreFormat<>(LEGACY_SNAPSHOT_NAME_FORMAT, IndexMetaData.PROTO, parseFieldMatcher); - snapshotFormat = new ChecksumBlobStoreFormat<>(SNAPSHOT_CODEC, SNAPSHOT_NAME_FORMAT, Snapshot.PROTO, parseFieldMatcher, isCompress()); - snapshotLegacyFormat = new LegacyBlobStoreFormat<>(LEGACY_SNAPSHOT_NAME_FORMAT, Snapshot.PROTO, parseFieldMatcher); + snapshotFormat = new ChecksumBlobStoreFormat<>(SNAPSHOT_CODEC, SNAPSHOT_NAME_FORMAT, SnapshotInfo.PROTO, parseFieldMatcher, isCompress()); + snapshotLegacyFormat = new LegacyBlobStoreFormat<>(LEGACY_SNAPSHOT_NAME_FORMAT, SnapshotInfo.PROTO, parseFieldMatcher); } /** @@ -294,7 +294,7 @@ public abstract class BlobStoreRepository extends AbstractLifecycleComponent indices = Collections.emptyList(); - Snapshot snapshot = null; + SnapshotInfo snapshot = null; try { snapshot = readSnapshot(snapshotId); indices = snapshot.indices(); @@ -368,9 +368,9 @@ public abstract class BlobStoreRepository extends AbstractLifecycleComponent indices, long startTime, String failure, int totalShards, List shardFailures) { + public SnapshotInfo finalizeSnapshot(SnapshotId snapshotId, List indices, long startTime, String failure, int totalShards, List shardFailures) { try { - Snapshot blobStoreSnapshot = new Snapshot(snapshotId.getSnapshot(), indices, startTime, failure, System.currentTimeMillis(), totalShards, shardFailures); + SnapshotInfo blobStoreSnapshot = new SnapshotInfo(snapshotId.getSnapshot(), indices, startTime, failure, System.currentTimeMillis(), totalShards, shardFailures); snapshotFormat.write(blobStoreSnapshot, snapshotsBlobContainer, snapshotId.getSnapshot()); List snapshotIds = snapshots(); if (!snapshotIds.contains(snapshotId)) { @@ -425,7 +425,7 @@ public abstract class BlobStoreRepository extends AbstractLifecycleComponent indices) throws IOException { + public MetaData readSnapshotMetaData(SnapshotId snapshotId, SnapshotInfo snapshot, List indices) throws IOException { return readSnapshotMetaData(snapshotId, snapshot.version(), indices, false); } @@ -433,7 +433,7 @@ public abstract class BlobStoreRepository extends AbstractLifecycleComponent snapshotFormat(Version version) { + private BlobStoreFormat snapshotFormat(Version version) { if(legacyMetaData(version)) { return snapshotLegacyFormat; } else { diff --git a/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/node/hotthreads/RestNodesHotThreadsAction.java b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/node/hotthreads/RestNodesHotThreadsAction.java index 53bec14f967..19bee19509a 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/node/hotthreads/RestNodesHotThreadsAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/node/hotthreads/RestNodesHotThreadsAction.java @@ -69,7 +69,7 @@ public class RestNodesHotThreadsAction extends BaseRestHandler { @Override public RestResponse buildResponse(NodesHotThreadsResponse response) throws Exception { StringBuilder sb = new StringBuilder(); - for (NodeHotThreads node : response) { + for (NodeHotThreads node : response.getNodes()) { sb.append("::: ").append(node.getNode().toString()).append("\n"); Strings.spaceify(3, node.getHotThreads(), sb); sb.append('\n'); diff --git a/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/node/info/RestNodesInfoAction.java b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/node/info/RestNodesInfoAction.java index bd6637cb788..65b7715385f 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/node/info/RestNodesInfoAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/node/info/RestNodesInfoAction.java @@ -20,22 +20,17 @@ package org.elasticsearch.rest.action.admin.cluster.node.info; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequest; -import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse; import org.elasticsearch.client.Client; import org.elasticsearch.common.Strings; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsFilter; import org.elasticsearch.common.util.set.Sets; -import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.rest.BaseRestHandler; -import org.elasticsearch.rest.BytesRestResponse; import org.elasticsearch.rest.RestChannel; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.rest.RestResponse; -import org.elasticsearch.rest.RestStatus; -import org.elasticsearch.rest.action.support.RestBuilderListener; +import org.elasticsearch.rest.action.support.RestActions.NodesResponseRestListener; import java.util.Set; @@ -106,15 +101,6 @@ public class RestNodesInfoAction extends BaseRestHandler { settingsFilter.addFilterSettingParams(request); - client.admin().cluster().nodesInfo(nodesInfoRequest, new RestBuilderListener(channel) { - - @Override - public RestResponse buildResponse(NodesInfoResponse response, XContentBuilder builder) throws Exception { - builder.startObject(); - response.toXContent(builder, request); - builder.endObject(); - return new BytesRestResponse(RestStatus.OK, builder); - } - }); + client.admin().cluster().nodesInfo(nodesInfoRequest, new NodesResponseRestListener<>(channel)); } } diff --git a/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/node/stats/RestNodesStatsAction.java b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/node/stats/RestNodesStatsAction.java index 1e2aece1646..47cce5283a9 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/node/stats/RestNodesStatsAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/node/stats/RestNodesStatsAction.java @@ -20,7 +20,6 @@ package org.elasticsearch.rest.action.admin.cluster.node.stats; 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.action.admin.indices.stats.CommonStatsFlags.Flag; import org.elasticsearch.client.Client; @@ -31,7 +30,7 @@ import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestChannel; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.rest.action.support.RestToXContentListener; +import org.elasticsearch.rest.action.support.RestActions.NodesResponseRestListener; import java.util.Set; @@ -114,6 +113,6 @@ public class RestNodesStatsAction extends BaseRestHandler { nodesStatsRequest.indices().includeSegmentFileSizes(true); } - client.admin().cluster().nodesStats(nodesStatsRequest, new RestToXContentListener<>(channel)); + client.admin().cluster().nodesStats(nodesStatsRequest, new NodesResponseRestListener<>(channel)); } } diff --git a/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/stats/RestClusterStatsAction.java b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/stats/RestClusterStatsAction.java index a02dcfccb98..29cc6377494 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/stats/RestClusterStatsAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/admin/cluster/stats/RestClusterStatsAction.java @@ -27,8 +27,7 @@ import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestChannel; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.rest.action.support.RestToXContentListener; - +import org.elasticsearch.rest.action.support.RestActions.NodesResponseRestListener; /** * @@ -46,6 +45,6 @@ public class RestClusterStatsAction extends BaseRestHandler { public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) { ClusterStatsRequest clusterStatsRequest = new ClusterStatsRequest().nodesIds(request.paramAsStringArray("nodeId", null)); clusterStatsRequest.timeout(request.param("timeout")); - client.admin().cluster().clusterStats(clusterStatsRequest, new RestToXContentListener<>(channel)); + client.admin().cluster().clusterStats(clusterStatsRequest, new NodesResponseRestListener<>(channel)); } } diff --git a/core/src/main/java/org/elasticsearch/rest/action/admin/indices/validate/query/RestValidateQueryAction.java b/core/src/main/java/org/elasticsearch/rest/action/admin/indices/validate/query/RestValidateQueryAction.java index 4ff7234b2ef..6ac71708e32 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/admin/indices/validate/query/RestValidateQueryAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/admin/indices/validate/query/RestValidateQueryAction.java @@ -82,7 +82,7 @@ public class RestValidateQueryAction extends BaseRestHandler { return; } } else { - QueryBuilder queryBuilder = RestActions.urlParamsToQueryBuilder(request); + QueryBuilder queryBuilder = RestActions.urlParamsToQueryBuilder(request); if (queryBuilder != null) { validateQueryRequest.query(queryBuilder); } diff --git a/core/src/main/java/org/elasticsearch/rest/action/cat/RestCountAction.java b/core/src/main/java/org/elasticsearch/rest/action/cat/RestCountAction.java index 6fd64430c20..46e8fadd05a 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/cat/RestCountAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/cat/RestCountAction.java @@ -68,7 +68,7 @@ public class RestCountAction extends AbstractCatAction { if (source != null) { searchSourceBuilder.query(RestActions.getQueryContent(new BytesArray(source), indicesQueriesRegistry, parseFieldMatcher)); } else { - QueryBuilder queryBuilder = RestActions.urlParamsToQueryBuilder(request); + QueryBuilder queryBuilder = RestActions.urlParamsToQueryBuilder(request); if (queryBuilder != null) { searchSourceBuilder.query(queryBuilder); } diff --git a/core/src/main/java/org/elasticsearch/rest/action/cat/RestRecoveryAction.java b/core/src/main/java/org/elasticsearch/rest/action/cat/RestRecoveryAction.java index 7c555c9b357..4764462d958 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/cat/RestRecoveryAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/cat/RestRecoveryAction.java @@ -88,7 +88,9 @@ public class RestRecoveryAction extends AbstractCatAction { .addCell("type", "alias:ty;desc:recovery type") .addCell("stage", "alias:st;desc:recovery stage") .addCell("source_host", "alias:shost;desc:source host") + .addCell("source_node", "alias:snode;desc:source node name") .addCell("target_host", "alias:thost;desc:target host") + .addCell("target_node", "alias:tnode;desc:target node name") .addCell("repository", "alias:rep;desc:repository") .addCell("snapshot", "alias:snap;desc:snapshot") .addCell("files", "alias:f;desc:number of files to recover") @@ -149,7 +151,9 @@ public class RestRecoveryAction extends AbstractCatAction { t.addCell(state.getType().toString().toLowerCase(Locale.ROOT)); t.addCell(state.getStage().toString().toLowerCase(Locale.ROOT)); t.addCell(state.getSourceNode() == null ? "n/a" : state.getSourceNode().getHostName()); + t.addCell(state.getSourceNode() == null ? "n/a" : state.getSourceNode().getName()); t.addCell(state.getTargetNode().getHostName()); + t.addCell(state.getTargetNode().getName()); t.addCell(state.getRestoreSource() == null ? "n/a" : state.getRestoreSource().snapshotId().getRepository()); t.addCell(state.getRestoreSource() == null ? "n/a" : state.getRestoreSource().snapshotId().getSnapshot()); t.addCell(state.getIndex().totalRecoverFiles()); diff --git a/core/src/main/java/org/elasticsearch/rest/action/count/RestCountAction.java b/core/src/main/java/org/elasticsearch/rest/action/count/RestCountAction.java index c423f7a8537..71e5832071c 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/count/RestCountAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/count/RestCountAction.java @@ -74,7 +74,7 @@ public class RestCountAction extends BaseRestHandler { BytesReference restContent = RestActions.getRestContent(request); searchSourceBuilder.query(RestActions.getQueryContent(restContent, indicesQueriesRegistry, parseFieldMatcher)); } else { - QueryBuilder queryBuilder = RestActions.urlParamsToQueryBuilder(request); + QueryBuilder queryBuilder = RestActions.urlParamsToQueryBuilder(request); if (queryBuilder != null) { searchSourceBuilder.query(queryBuilder); } diff --git a/core/src/main/java/org/elasticsearch/rest/action/explain/RestExplainAction.java b/core/src/main/java/org/elasticsearch/rest/action/explain/RestExplainAction.java index a1fdc13437c..47f5e7da19b 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/explain/RestExplainAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/explain/RestExplainAction.java @@ -74,7 +74,7 @@ public class RestExplainAction extends BaseRestHandler { BytesReference restContent = RestActions.getRestContent(request); explainRequest.query(RestActions.getQueryContent(restContent, indicesQueriesRegistry, parseFieldMatcher)); } else if (queryString != null) { - QueryBuilder query = RestActions.urlParamsToQueryBuilder(request); + QueryBuilder query = RestActions.urlParamsToQueryBuilder(request); explainRequest.query(query); } diff --git a/core/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java b/core/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java index 5a65c8df116..8d6b003779b 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java @@ -162,7 +162,7 @@ public class RestSearchAction extends BaseRestHandler { * values that are not overridden by the rest request. */ private static void parseSearchSource(final SearchSourceBuilder searchSourceBuilder, RestRequest request) { - QueryBuilder queryBuilder = RestActions.urlParamsToQueryBuilder(request); + QueryBuilder queryBuilder = RestActions.urlParamsToQueryBuilder(request); if (queryBuilder != null) { searchSourceBuilder.query(queryBuilder); } diff --git a/core/src/main/java/org/elasticsearch/rest/action/support/RestActions.java b/core/src/main/java/org/elasticsearch/rest/action/support/RestActions.java index 9ab523ba1e6..51d5089ec6f 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/support/RestActions.java +++ b/core/src/main/java/org/elasticsearch/rest/action/support/RestActions.java @@ -21,13 +21,17 @@ package org.elasticsearch.rest.action.support; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ExceptionsHelper; +import org.elasticsearch.action.FailedNodeException; import org.elasticsearch.action.ShardOperationFailedException; import org.elasticsearch.action.support.broadcast.BroadcastResponse; +import org.elasticsearch.action.support.nodes.BaseNodeResponse; +import org.elasticsearch.action.support.nodes.BaseNodesResponse; import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.lucene.uid.Versions; import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.ToXContent.Params; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; @@ -38,9 +42,14 @@ import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryStringQueryBuilder; import org.elasticsearch.indices.query.IndicesQueriesRegistry; +import org.elasticsearch.rest.BytesRestResponse; +import org.elasticsearch.rest.RestChannel; import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.RestResponse; +import org.elasticsearch.rest.RestStatus; import java.io.IOException; +import java.util.List; /** * @@ -63,25 +72,21 @@ public class RestActions { return (version == Versions.MATCH_ANY) ? defaultVersion : version; } - static final class Fields { - static final String _SHARDS = "_shards"; - static final String TOTAL = "total"; - static final String SUCCESSFUL = "successful"; - static final String FAILED = "failed"; - static final String FAILURES = "failures"; + public static void buildBroadcastShardsHeader(XContentBuilder builder, Params params, BroadcastResponse response) throws IOException { + buildBroadcastShardsHeader(builder, params, + response.getTotalShards(), response.getSuccessfulShards(), response.getFailedShards(), + response.getShardFailures()); } - public static void buildBroadcastShardsHeader(XContentBuilder builder, ToXContent.Params params, BroadcastResponse response) throws IOException { - buildBroadcastShardsHeader(builder, params, response.getTotalShards(), response.getSuccessfulShards(), response.getFailedShards(), response.getShardFailures()); - } - - public static void buildBroadcastShardsHeader(XContentBuilder builder, ToXContent.Params params, int total, int successful, int failed, ShardOperationFailedException[] shardFailures) throws IOException { - builder.startObject(Fields._SHARDS); - builder.field(Fields.TOTAL, total); - builder.field(Fields.SUCCESSFUL, successful); - builder.field(Fields.FAILED, failed); + public static void buildBroadcastShardsHeader(XContentBuilder builder, Params params, + int total, int successful, int failed, + ShardOperationFailedException[] shardFailures) throws IOException { + builder.startObject("_shards"); + builder.field("total", total); + builder.field("successful", successful); + builder.field("failed", failed); if (shardFailures != null && shardFailures.length > 0) { - builder.startArray(Fields.FAILURES); + builder.startArray("failures"); final boolean group = params.paramAsBoolean("group_shard_failures", true); // we group by default for (ShardOperationFailedException shardFailure : group ? ExceptionsHelper.groupBy(shardFailures) : shardFailures) { builder.startObject(); @@ -92,8 +97,96 @@ public class RestActions { } builder.endObject(); } + /** + * Create the XContent header for any {@link BaseNodesResponse}. + * + * @param builder XContent builder. + * @param params XContent parameters. + * @param response The response containing individual, node-level responses. + * @see #buildNodesHeader(XContentBuilder, Params, int, int, int, List) + */ + public static void buildNodesHeader(final XContentBuilder builder, final Params params, + final BaseNodesResponse response) + throws IOException { + final int successful = response.getNodes().size(); + final int failed = response.failures().size(); - public static QueryBuilder urlParamsToQueryBuilder(RestRequest request) { + buildNodesHeader(builder, params, successful + failed, successful, failed, response.failures()); + } + + /** + * Create the XContent header for any {@link BaseNodesResponse}. This looks like: + * + * "_nodes" : { + * "total" : 3, + * "successful" : 1, + * "failed" : 2, + * "failures" : [ { ... }, { ... } ] + * } + * + * Prefer the overload that properly invokes this method to calling this directly. + * + * @param builder XContent builder. + * @param params XContent parameters. + * @param total The total number of nodes touched. + * @param successful The successful number of responses received. + * @param failed The number of failures (effectively {@code total - successful}). + * @param failures The failure exceptions related to {@code failed}. + * @see #buildNodesHeader(XContentBuilder, Params, BaseNodesResponse) + */ + public static void buildNodesHeader(final XContentBuilder builder, final Params params, + final int total, final int successful, final int failed, + final List failures) throws IOException { + builder.startObject("_nodes"); + builder.field("total", total); + builder.field("successful", successful); + builder.field("failed", failed); + + if (failures.isEmpty() == false) { + builder.startArray("failures"); + for (FailedNodeException failure : failures) { + builder.startObject(); + failure.toXContent(builder, params); + builder.endObject(); + } + builder.endArray(); + } + + builder.endObject(); + } + + /** + * Automatically transform the {@link ToXContent}-compatible, nodes-level {@code response} into a a {@link BytesRestResponse}. + *

+ * This looks like: + * + * { + * "_nodes" : { ... }, + * "cluster_name" : "...", + * ... + * } + * + * + * @param builder XContent builder. + * @param params XContent parameters. + * @param response The nodes-level (plural) response. + * @return Never {@code null}. + * @throws IOException if building the response causes an issue + */ + public static BytesRestResponse nodesResponse(final XContentBuilder builder, + final Params params, + final NodesResponse response) + throws IOException { + builder.startObject(); + RestActions.buildNodesHeader(builder, params, response); + builder.field("cluster_name", response.getClusterName().value()); + response.toXContent(builder, params); + builder.endObject(); + + return new BytesRestResponse(RestStatus.OK, builder); + } + + public static QueryBuilder urlParamsToQueryBuilder(RestRequest request) { String queryString = request.param("q"); if (queryString == null) { return null; @@ -130,7 +223,8 @@ public class RestActions { return content; } - public static QueryBuilder getQueryContent(BytesReference source, IndicesQueriesRegistry indicesQueriesRegistry, ParseFieldMatcher parseFieldMatcher) { + public static QueryBuilder getQueryContent(BytesReference source, IndicesQueriesRegistry indicesQueriesRegistry, + ParseFieldMatcher parseFieldMatcher) { try (XContentParser requestParser = XContentFactory.xContent(source).createParser(source)) { QueryParseContext context = new QueryParseContext(indicesQueriesRegistry, requestParser, parseFieldMatcher); return context.parseTopLevelQueryBuilder(); @@ -158,4 +252,32 @@ public class RestActions { public static boolean hasBodyContent(final RestRequest request) { return request.hasContent() || request.hasParam("source"); } + + /** + * {@code NodesResponseRestBuilderListener} automatically translates any {@link BaseNodesResponse} (multi-node) response that is + * {@link ToXContent}-compatible into a {@link RestResponse} with the necessary header info (e.g., "cluster_name"). + *

+ * This is meant to avoid a slew of anonymous classes doing (or worse): + * + * client.admin().cluster().request(nodesRequest, new RestBuilderListener<NodesResponse>(channel) { + * public RestResponse buildResponse(NodesResponse response, XContentBuilder builder) throws Exception { + * return RestActions.nodesResponse(builder, ToXContent.EMPTY_PARAMS, response); + * } + * }); + * + */ + public static class NodesResponseRestListener + extends RestBuilderListener { + + public NodesResponseRestListener(RestChannel channel) { + super(channel); + } + + @Override + public RestResponse buildResponse(NodesResponse response, XContentBuilder builder) throws Exception { + return RestActions.nodesResponse(builder, ToXContent.EMPTY_PARAMS, response); + } + + } + } diff --git a/core/src/main/java/org/elasticsearch/rest/support/RestUtils.java b/core/src/main/java/org/elasticsearch/rest/support/RestUtils.java index 7a976fe1f1d..ef7a7ac0edd 100644 --- a/core/src/main/java/org/elasticsearch/rest/support/RestUtils.java +++ b/core/src/main/java/org/elasticsearch/rest/support/RestUtils.java @@ -73,7 +73,7 @@ public class RestUtils { name = decodeComponent(s.substring(pos, i)); } pos = i + 1; - } else if (c == '&') { + } else if (c == '&' || c == ';') { if (name == null && pos != i) { // We haven't seen an `=' so far but moved forward. // Must be a param of the form '&a&' so add it with diff --git a/core/src/main/java/org/elasticsearch/search/DocValueFormat.java b/core/src/main/java/org/elasticsearch/search/DocValueFormat.java index 78f8460f1cc..c7c993b82b6 100644 --- a/core/src/main/java/org/elasticsearch/search/DocValueFormat.java +++ b/core/src/main/java/org/elasticsearch/search/DocValueFormat.java @@ -20,7 +20,6 @@ package org.elasticsearch.search; import org.apache.lucene.document.InetAddressPoint; -import org.apache.lucene.index.Term; import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.geo.GeoHashUtils; import org.elasticsearch.common.io.stream.NamedWriteable; @@ -29,8 +28,8 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.joda.DateMathParser; import org.elasticsearch.common.joda.FormatDateTimeFormatter; import org.elasticsearch.common.joda.Joda; +import org.elasticsearch.common.network.InetAddresses; import org.elasticsearch.common.network.NetworkAddress; -import org.elasticsearch.index.mapper.ip.IpFieldMapper; import org.elasticsearch.index.mapper.ip.LegacyIpFieldMapper; import org.joda.time.DateTimeZone; @@ -48,16 +47,33 @@ import java.util.concurrent.Callable; /** A formatter for values as returned by the fielddata/doc-values APIs. */ public interface DocValueFormat extends NamedWriteable { + /** Format a long value. This is used by terms and histogram aggregations + * to format keys for fields that use longs as a doc value representation + * such as the {@code long} and {@code date} fields. */ String format(long value); + /** Format a double value. This is used by terms and stats aggregations + * to format keys for fields that use numbers as a doc value representation + * such as the {@code long}, {@code double} or {@code date} fields. */ String format(double value); + /** Format a double value. This is used by terms aggregations to format + * keys for fields that use binary doc value representations such as the + * {@code keyword} and {@code ip} fields. */ String format(BytesRef value); + /** Parse a value that was formatted with {@link #format(long)} back to the + * original long value. */ long parseLong(String value, boolean roundUp, Callable now); + /** Parse a value that was formatted with {@link #format(double)} back to + * the original double value. */ double parseDouble(String value, boolean roundUp, Callable now); + /** Parse a value that was formatted with {@link #format(BytesRef)} back + * to the original BytesRef. */ + BytesRef parseBytesRef(String value); + public static final DocValueFormat RAW = new DocValueFormat() { @Override @@ -81,7 +97,7 @@ public interface DocValueFormat extends NamedWriteable { @Override public String format(BytesRef value) { - return Term.toString(value); + return value.utf8ToString(); } @Override @@ -99,6 +115,10 @@ public interface DocValueFormat extends NamedWriteable { public double parseDouble(String value, boolean roundUp, Callable now) { return Double.parseDouble(value); } + + public BytesRef parseBytesRef(String value) { + return new BytesRef(value); + } }; public static final class DateTime implements DocValueFormat { @@ -154,6 +174,11 @@ public interface DocValueFormat extends NamedWriteable { public double parseDouble(String value, boolean roundUp, Callable now) { return parseLong(value, roundUp, now); } + + @Override + public BytesRef parseBytesRef(String value) { + throw new UnsupportedOperationException(); + } } public static final DocValueFormat GEOHASH = new DocValueFormat() { @@ -191,6 +216,11 @@ public interface DocValueFormat extends NamedWriteable { public double parseDouble(String value, boolean roundUp, Callable now) { throw new UnsupportedOperationException(); } + + @Override + public BytesRef parseBytesRef(String value) { + throw new UnsupportedOperationException(); + } }; public static final DocValueFormat BOOLEAN = new DocValueFormat() { @@ -221,13 +251,24 @@ public interface DocValueFormat extends NamedWriteable { @Override public long parseLong(String value, boolean roundUp, Callable now) { - throw new UnsupportedOperationException(); + switch (value) { + case "false": + return 0; + case "true": + return 1; + } + throw new IllegalArgumentException("Cannot parse boolean [" + value + "], expected either [true] or [false]"); } @Override public double parseDouble(String value, boolean roundUp, Callable now) { throw new UnsupportedOperationException(); } + + @Override + public BytesRef parseBytesRef(String value) { + throw new UnsupportedOperationException(); + } }; public static final DocValueFormat IP = new DocValueFormat() { @@ -268,6 +309,11 @@ public interface DocValueFormat extends NamedWriteable { public double parseDouble(String value, boolean roundUp, Callable now) { return parseLong(value, roundUp, now); } + + @Override + public BytesRef parseBytesRef(String value) { + return new BytesRef(InetAddressPoint.encode(InetAddresses.forString(value))); + } }; public static final class Decimal implements DocValueFormat { @@ -344,5 +390,9 @@ public interface DocValueFormat extends NamedWriteable { return n.doubleValue(); } + @Override + public BytesRef parseBytesRef(String value) { + throw new UnsupportedOperationException(); + } } } diff --git a/core/src/main/java/org/elasticsearch/search/SearchModule.java b/core/src/main/java/org/elasticsearch/search/SearchModule.java index 3429b1ba18b..e0a6ccd09b4 100644 --- a/core/src/main/java/org/elasticsearch/search/SearchModule.java +++ b/core/src/main/java/org/elasticsearch/search/SearchModule.java @@ -359,7 +359,7 @@ public class SearchModule extends AbstractModule { * is the name by under which the reader is registered. So it is the name that the query should use as its * {@link NamedWriteable#getWriteableName()} too. */ - public > void registerQuery(Writeable.Reader reader, QueryParser queryParser, + public void registerQuery(Writeable.Reader reader, QueryParser queryParser, ParseField queryName) { queryParserRegistry.register(queryParser, queryName); namedWriteableRegistry.register(QueryBuilder.class, queryName.getPreferredName(), reader); diff --git a/core/src/main/java/org/elasticsearch/search/SearchService.java b/core/src/main/java/org/elasticsearch/search/SearchService.java index 24746431949..636e4338063 100644 --- a/core/src/main/java/org/elasticsearch/search/SearchService.java +++ b/core/src/main/java/org/elasticsearch/search/SearchService.java @@ -104,6 +104,7 @@ import org.elasticsearch.search.query.QuerySearchResultProvider; import org.elasticsearch.search.query.ScrollQuerySearchResult; import org.elasticsearch.search.rescore.RescoreBuilder; import org.elasticsearch.search.searchafter.SearchAfterBuilder; +import org.elasticsearch.search.sort.SortAndFormats; import org.elasticsearch.search.sort.SortBuilder; import org.elasticsearch.search.suggest.Suggesters; import org.elasticsearch.threadpool.ThreadPool; @@ -698,7 +699,7 @@ public class SearchService extends AbstractLifecycleComponent imp } if (source.sorts() != null) { try { - Optional optionalSort = SortBuilder.buildSort(source.sorts(), context.getQueryShardContext()); + Optional optionalSort = SortBuilder.buildSort(source.sorts(), context.getQueryShardContext()); if (optionalSort.isPresent()) { context.sort(optionalSort.get()); } diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilders.java b/core/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilders.java index 1da7c28cf09..23fa8007d5b 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilders.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilders.java @@ -142,7 +142,7 @@ public class AggregationBuilders { /** * Create a new {@link Filter} aggregation with the given name. */ - public static FilterAggregatorBuilder filter(String name, QueryBuilder filter) { + public static FilterAggregatorBuilder filter(String name, QueryBuilder filter) { return new FilterAggregatorBuilder(name, filter); } @@ -156,7 +156,7 @@ public class AggregationBuilders { /** * Create a new {@link Filters} aggregation with the given name. */ - public static FiltersAggregatorBuilder filters(String name, QueryBuilder... filters) { + public static FiltersAggregatorBuilder filters(String name, QueryBuilder... filters) { return new FiltersAggregatorBuilder(name, filters); } diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregatorBuilder.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregatorBuilder.java index 1a0c6decdf9..9024e902d7d 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregatorBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregatorBuilder.java @@ -41,7 +41,7 @@ public class FilterAggregatorBuilder extends AggregatorBuilder filter; + private final QueryBuilder filter; /** * @param name @@ -51,7 +51,7 @@ public class FilterAggregatorBuilder extends AggregatorBuilder filter) { + public FilterAggregatorBuilder(String name, QueryBuilder filter) { super(name, InternalFilter.TYPE); if (filter == null) { throw new IllegalArgumentException("[filter] must not be null: [" + name + "]"); @@ -92,7 +92,7 @@ public class FilterAggregatorBuilder extends AggregatorBuilder filter = context.parseInnerQueryBuilder(); + QueryBuilder filter = context.parseInnerQueryBuilder(); if (filter == null) { throw new ParsingException(null, "filter cannot be null in filter aggregation [{}]", aggregationName); diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregatorFactory.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregatorFactory.java index 13b1e62b338..212494ef48b 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregatorFactory.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregatorFactory.java @@ -38,7 +38,7 @@ public class FilterAggregatorFactory extends AggregatorFactory filterBuilder, AggregationContext context, + public FilterAggregatorFactory(String name, Type type, QueryBuilder filterBuilder, AggregationContext context, AggregatorFactory parent, AggregatorFactories.Builder subFactoriesBuilder, Map metaData) throws IOException { super(name, type, context, parent, subFactoriesBuilder, metaData); IndexSearcher contextSearcher = context.searchContext().searcher(); diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregator.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregator.java index ca071d7cfc9..a5ce89c4666 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregator.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregator.java @@ -59,9 +59,9 @@ public class FiltersAggregator extends BucketsAggregator { public static class KeyedFilter implements Writeable, ToXContent { private final String key; - private final QueryBuilder filter; + private final QueryBuilder filter; - public KeyedFilter(String key, QueryBuilder filter) { + public KeyedFilter(String key, QueryBuilder filter) { if (key == null) { throw new IllegalArgumentException("[key] must not be null"); } @@ -94,7 +94,7 @@ public class FiltersAggregator extends BucketsAggregator { return key; } - public QueryBuilder filter() { + public QueryBuilder filter() { return filter; } diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregatorBuilder.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregatorBuilder.java index ca9f7f6c7c3..52a1b949b4b 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregatorBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregatorBuilder.java @@ -80,7 +80,7 @@ public class FiltersAggregatorBuilder extends AggregatorBuilder... filters) { + public FiltersAggregatorBuilder(String name, QueryBuilder... filters) { super(name, InternalFilters.TYPE); List keyedFilters = new ArrayList<>(filters.length); for (int i = 0; i < filters.length; i++) { @@ -204,7 +204,7 @@ public class FiltersAggregatorBuilder extends AggregatorBuilder keyedFilters = null; - List> nonKeyedFilters = null; + List nonKeyedFilters = null; XContentParser.Token token = null; String currentFieldName = null; @@ -235,7 +235,7 @@ public class FiltersAggregatorBuilder extends AggregatorBuilder filter = context.parseInnerQueryBuilder(); + QueryBuilder filter = context.parseInnerQueryBuilder(); keyedFilters.add(new FiltersAggregator.KeyedFilter(key, filter == null ? matchAllQuery() : filter)); } } @@ -247,7 +247,7 @@ public class FiltersAggregatorBuilder extends AggregatorBuilder(); while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { - QueryBuilder filter = context.parseInnerQueryBuilder(); + QueryBuilder filter = context.parseInnerQueryBuilder(); nonKeyedFilters.add(filter == null ? QueryBuilders.matchAllQuery() : filter); } } else { @@ -270,7 +270,7 @@ public class FiltersAggregatorBuilder extends AggregatorBuilder[nonKeyedFilters.size()])); + nonKeyedFilters.toArray(new QueryBuilder[nonKeyedFilters.size()])); } if (otherBucket != null) { factory.otherBucket(otherBucket); diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregatorBuilder.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregatorBuilder.java index 373d757a22c..55b85bef0d9 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregatorBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregatorBuilder.java @@ -58,7 +58,7 @@ public class SignificantTermsAggregatorBuilder extends ValuesSourceAggregatorBui private IncludeExclude includeExclude = null; private String executionHint = null; - private QueryBuilder filterBuilder = null; + private QueryBuilder filterBuilder = null; private TermsAggregator.BucketCountThresholds bucketCountThresholds = new BucketCountThresholds(DEFAULT_BUCKET_COUNT_THRESHOLDS); private SignificanceHeuristic significanceHeuristic = DEFAULT_SIGNIFICANCE_HEURISTIC; @@ -176,7 +176,7 @@ public class SignificantTermsAggregatorBuilder extends ValuesSourceAggregatorBui return executionHint; } - public SignificantTermsAggregatorBuilder backgroundFilter(QueryBuilder backgroundFilter) { + public SignificantTermsAggregatorBuilder backgroundFilter(QueryBuilder backgroundFilter) { if (backgroundFilter == null) { throw new IllegalArgumentException("[backgroundFilter] must not be null: [" + name + "]"); } @@ -184,7 +184,7 @@ public class SignificantTermsAggregatorBuilder extends ValuesSourceAggregatorBui return this; } - public QueryBuilder backgroundFilter() { + public QueryBuilder backgroundFilter() { return filterBuilder; } diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregatorFactory.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregatorFactory.java index 0f0a37d909a..ce3f83079ea 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregatorFactory.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregatorFactory.java @@ -65,12 +65,12 @@ public class SignificantTermsAggregatorFactory extends ValuesSourceAggregatorFac private MappedFieldType fieldType; private FilterableTermsEnum termsEnum; private int numberOfAggregatorsCreated; - private final QueryBuilder filterBuilder; + private final QueryBuilder filterBuilder; private final TermsAggregator.BucketCountThresholds bucketCountThresholds; private final SignificanceHeuristic significanceHeuristic; public SignificantTermsAggregatorFactory(String name, Type type, ValuesSourceConfig config, IncludeExclude includeExclude, - String executionHint, QueryBuilder filterBuilder, TermsAggregator.BucketCountThresholds bucketCountThresholds, + String executionHint, QueryBuilder filterBuilder, TermsAggregator.BucketCountThresholds bucketCountThresholds, SignificanceHeuristic significanceHeuristic, AggregationContext context, AggregatorFactory parent, AggregatorFactories.Builder subFactoriesBuilder, Map metaData) throws IOException { super(name, type, config, context, parent, subFactoriesBuilder, metaData); diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsParser.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsParser.java index b6549c6dc29..60805bea692 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsParser.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsParser.java @@ -66,7 +66,7 @@ public class SignificantTermsParser extends AbstractTermsParser { if (incExc != null) { factory.includeExclude(incExc); } - QueryBuilder backgroundFilter = (QueryBuilder) otherOptions.get(SignificantTermsAggregatorBuilder.BACKGROUND_FILTER); + QueryBuilder backgroundFilter = (QueryBuilder) otherOptions.get(SignificantTermsAggregatorBuilder.BACKGROUND_FILTER); if (backgroundFilter != null) { factory.backgroundFilter(backgroundFilter); } @@ -89,7 +89,7 @@ public class SignificantTermsParser extends AbstractTermsParser { return true; } else if (parseFieldMatcher.match(currentFieldName, SignificantTermsAggregatorBuilder.BACKGROUND_FILTER)) { QueryParseContext queryParseContext = new QueryParseContext(queriesRegistry, parser, parseFieldMatcher); - QueryBuilder filter = queryParseContext.parseInnerQueryBuilder(); + QueryBuilder filter = queryParseContext.parseInnerQueryBuilder(); otherOptions.put(SignificantTermsAggregatorBuilder.BACKGROUND_FILTER, filter); return true; } diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/TopHitsAggregator.java b/core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/TopHitsAggregator.java index 8e50dc60ea8..07292f1d29f 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/TopHitsAggregator.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/TopHitsAggregator.java @@ -24,7 +24,6 @@ import org.apache.lucene.search.FieldDoc; import org.apache.lucene.search.LeafCollector; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.Scorer; -import org.apache.lucene.search.Sort; import org.apache.lucene.search.TopDocs; import org.apache.lucene.search.TopDocsCollector; import org.apache.lucene.search.TopFieldCollector; @@ -45,6 +44,7 @@ import org.elasticsearch.search.fetch.FetchSearchResult; import org.elasticsearch.search.internal.InternalSearchHit; import org.elasticsearch.search.internal.InternalSearchHits; import org.elasticsearch.search.internal.SubSearchContext; +import org.elasticsearch.search.sort.SortAndFormats; import java.io.IOException; import java.util.List; @@ -78,9 +78,9 @@ public class TopHitsAggregator extends MetricsAggregator { @Override public boolean needsScores() { - Sort sort = subSearchContext.sort(); + SortAndFormats sort = subSearchContext.sort(); if (sort != null) { - return sort.needsScores() || subSearchContext.trackScores(); + return sort.sort.needsScores() || subSearchContext.trackScores(); } else { // sort by score return true; @@ -112,12 +112,12 @@ public class TopHitsAggregator extends MetricsAggregator { public void collect(int docId, long bucket) throws IOException { TopDocsAndLeafCollector collectors = topDocsCollectors.get(bucket); if (collectors == null) { - Sort sort = subSearchContext.sort(); + SortAndFormats sort = subSearchContext.sort(); int topN = subSearchContext.from() + subSearchContext.size(); // In the QueryPhase we don't need this protection, because it is build into the IndexSearcher, // but here we create collectors ourselves and we need prevent OOM because of crazy an offset and size. topN = Math.min(topN, subSearchContext.searcher().getIndexReader().maxDoc()); - TopDocsCollector topLevelCollector = sort != null ? TopFieldCollector.create(sort, topN, true, subSearchContext.trackScores(), subSearchContext.trackScores()) : TopScoreDocCollector.create(topN); + TopDocsCollector topLevelCollector = sort != null ? TopFieldCollector.create(sort.sort, topN, true, subSearchContext.trackScores(), subSearchContext.trackScores()) : TopScoreDocCollector.create(topN); collectors = new TopDocsAndLeafCollector(topLevelCollector); collectors.leafCollector = collectors.topLevelCollector.getLeafCollector(ctx); collectors.leafCollector.setScorer(scorer); @@ -137,7 +137,7 @@ public class TopHitsAggregator extends MetricsAggregator { } else { final TopDocs topDocs = topDocsCollector.topLevelCollector.topDocs(); - subSearchContext.queryResult().topDocs(topDocs); + subSearchContext.queryResult().topDocs(topDocs, subSearchContext.sort() == null ? null : subSearchContext.sort().formats); int[] docIdsToLoad = new int[topDocs.scoreDocs.length]; for (int i = 0; i < topDocs.scoreDocs.length; i++) { docIdsToLoad[i] = topDocs.scoreDocs[i].doc; @@ -153,7 +153,7 @@ public class TopHitsAggregator extends MetricsAggregator { searchHitFields.score(scoreDoc.score); if (scoreDoc instanceof FieldDoc) { FieldDoc fieldDoc = (FieldDoc) scoreDoc; - searchHitFields.sortValues(fieldDoc.fields); + searchHitFields.sortValues(fieldDoc.fields, subSearchContext.sort().formats); } } topHits = new InternalTopHits(name, subSearchContext.from(), subSearchContext.size(), topDocs, fetchResult.hits(), pipelineAggregators(), @@ -166,7 +166,7 @@ public class TopHitsAggregator extends MetricsAggregator { public InternalTopHits buildEmptyAggregation() { TopDocs topDocs; if (subSearchContext.sort() != null) { - topDocs = new TopFieldDocs(0, new FieldDoc[0], subSearchContext.sort().getSort(), Float.NaN); + topDocs = new TopFieldDocs(0, new FieldDoc[0], subSearchContext.sort().sort.getSort(), Float.NaN); } else { topDocs = Lucene.EMPTY_TOP_DOCS; } diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/TopHitsAggregatorFactory.java b/core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/TopHitsAggregatorFactory.java index 478f03c7eac..ac001222301 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/TopHitsAggregatorFactory.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/TopHitsAggregatorFactory.java @@ -19,7 +19,6 @@ package org.elasticsearch.search.aggregations.metrics.tophits; -import org.apache.lucene.search.Sort; import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.SearchScript; import org.elasticsearch.search.aggregations.Aggregator; @@ -35,6 +34,7 @@ import org.elasticsearch.search.fetch.fielddata.FieldDataFieldsFetchSubPhase; import org.elasticsearch.search.fetch.source.FetchSourceContext; import org.elasticsearch.search.highlight.HighlightBuilder; import org.elasticsearch.search.internal.SubSearchContext; +import org.elasticsearch.search.sort.SortAndFormats; import org.elasticsearch.search.sort.SortBuilder; import java.io.IOException; @@ -87,7 +87,7 @@ public class TopHitsAggregatorFactory extends AggregatorFactory optionalSort = SortBuilder.buildSort(sorts, subSearchContext.getQueryShardContext()); + Optional optionalSort = SortBuilder.buildSort(sorts, subSearchContext.getQueryShardContext()); if (optionalSort.isPresent()) { subSearchContext.sort(optionalSort.get()); } diff --git a/core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java b/core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java index b656df4e154..61f4acb81aa 100644 --- a/core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java @@ -120,9 +120,9 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ return new HighlightBuilder(); } - private QueryBuilder queryBuilder; + private QueryBuilder queryBuilder; - private QueryBuilder postQueryBuilder; + private QueryBuilder postQueryBuilder; private int from = -1; @@ -371,7 +371,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ * * @see org.elasticsearch.index.query.QueryBuilders */ - public SearchSourceBuilder query(QueryBuilder query) { + public SearchSourceBuilder query(QueryBuilder query) { this.queryBuilder = query; return this; } @@ -379,7 +379,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ /** * Gets the query for this request */ - public QueryBuilder query() { + public QueryBuilder query() { return queryBuilder; } @@ -388,7 +388,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ * only has affect on the search hits (not aggregations). This filter is * always executed as last filtering mechanism. */ - public SearchSourceBuilder postFilter(QueryBuilder postFilter) { + public SearchSourceBuilder postFilter(QueryBuilder postFilter) { this.postQueryBuilder = postFilter; return this; } @@ -396,7 +396,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ /** * Gets the post filter for this request */ - public QueryBuilder postFilter() { + public QueryBuilder postFilter() { return postQueryBuilder; } @@ -910,11 +910,11 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ */ public SearchSourceBuilder rewrite(QueryShardContext context) throws IOException { assert (this.equals(shallowCopy(queryBuilder, postQueryBuilder))); - QueryBuilder queryBuilder = null; + QueryBuilder queryBuilder = null; if (this.queryBuilder != null) { queryBuilder = this.queryBuilder.rewrite(context); } - QueryBuilder postQueryBuilder = null; + QueryBuilder postQueryBuilder = null; if (this.postQueryBuilder != null) { postQueryBuilder = this.postQueryBuilder.rewrite(context); } @@ -925,7 +925,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ return this; } - private SearchSourceBuilder shallowCopy(QueryBuilder queryBuilder, QueryBuilder postQueryBuilder) { + private SearchSourceBuilder shallowCopy(QueryBuilder queryBuilder, QueryBuilder postQueryBuilder) { SearchSourceBuilder rewrittenBuilder = new SearchSourceBuilder(); rewrittenBuilder.aggregations = aggregations; rewrittenBuilder.explain = explain; diff --git a/core/src/main/java/org/elasticsearch/search/controller/SearchPhaseController.java b/core/src/main/java/org/elasticsearch/search/controller/SearchPhaseController.java index 1c48be1b959..a8ecc7a508c 100644 --- a/core/src/main/java/org/elasticsearch/search/controller/SearchPhaseController.java +++ b/core/src/main/java/org/elasticsearch/search/controller/SearchPhaseController.java @@ -362,7 +362,7 @@ public class SearchPhaseController extends AbstractComponent { if (sorted) { FieldDoc fieldDoc = (FieldDoc) shardDoc; - searchHit.sortValues(fieldDoc.fields); + searchHit.sortValues(fieldDoc.fields, firstResult.sortValueFormats()); if (sortScoreIndex != -1) { searchHit.score(((Number) fieldDoc.fields[sortScoreIndex]).floatValue()); } diff --git a/core/src/main/java/org/elasticsearch/search/fetch/innerhits/InnerHitsContext.java b/core/src/main/java/org/elasticsearch/search/fetch/innerhits/InnerHitsContext.java index 56059fc0d01..31921457207 100644 --- a/core/src/main/java/org/elasticsearch/search/fetch/innerhits/InnerHitsContext.java +++ b/core/src/main/java/org/elasticsearch/search/fetch/innerhits/InnerHitsContext.java @@ -142,7 +142,7 @@ public final class InnerHitsContext { TopDocsCollector topDocsCollector; if (sort() != null) { try { - topDocsCollector = TopFieldCollector.create(sort(), topN, true, trackScores(), trackScores()); + topDocsCollector = TopFieldCollector.create(sort().sort, topN, true, trackScores(), trackScores()); } catch (IOException e) { throw ExceptionsHelper.convertToElastic(e); } @@ -317,7 +317,7 @@ public final class InnerHitsContext { int topN = Math.min(from() + size(), context.searcher().getIndexReader().maxDoc()); TopDocsCollector topDocsCollector; if (sort() != null) { - topDocsCollector = TopFieldCollector.create(sort(), topN, true, trackScores(), trackScores()); + topDocsCollector = TopFieldCollector.create(sort().sort, topN, true, trackScores(), trackScores()); } else { topDocsCollector = TopScoreDocCollector.create(topN); } diff --git a/core/src/main/java/org/elasticsearch/search/fetch/innerhits/InnerHitsFetchSubPhase.java b/core/src/main/java/org/elasticsearch/search/fetch/innerhits/InnerHitsFetchSubPhase.java index ea7edcc3dd4..82c3755cdc9 100644 --- a/core/src/main/java/org/elasticsearch/search/fetch/innerhits/InnerHitsFetchSubPhase.java +++ b/core/src/main/java/org/elasticsearch/search/fetch/innerhits/InnerHitsFetchSubPhase.java @@ -73,7 +73,7 @@ public class InnerHitsFetchSubPhase implements FetchSubPhase { } catch (IOException e) { throw ExceptionsHelper.convertToElastic(e); } - innerHits.queryResult().topDocs(topDocs); + innerHits.queryResult().topDocs(topDocs, innerHits.sort() == null ? null : innerHits.sort().formats); int[] docIdsToLoad = new int[topDocs.scoreDocs.length]; for (int i = 0; i < topDocs.scoreDocs.length; i++) { docIdsToLoad[i] = topDocs.scoreDocs[i].doc; @@ -89,7 +89,7 @@ public class InnerHitsFetchSubPhase implements FetchSubPhase { searchHitFields.score(scoreDoc.score); if (scoreDoc instanceof FieldDoc) { FieldDoc fieldDoc = (FieldDoc) scoreDoc; - searchHitFields.sortValues(fieldDoc.fields); + searchHitFields.sortValues(fieldDoc.fields, innerHits.sort().formats); } } results.put(entry.getKey(), fetchResult.hits()); diff --git a/core/src/main/java/org/elasticsearch/search/highlight/AbstractHighlighterBuilder.java b/core/src/main/java/org/elasticsearch/search/highlight/AbstractHighlighterBuilder.java index e19dd33efc8..557567fe354 100644 --- a/core/src/main/java/org/elasticsearch/search/highlight/AbstractHighlighterBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/highlight/AbstractHighlighterBuilder.java @@ -80,7 +80,7 @@ public abstract class AbstractHighlighterBuilder highlightQuery; + protected QueryBuilder highlightQuery; protected Order order; @@ -275,7 +275,7 @@ public abstract class AbstractHighlighterBuilder highlightQuery) { + public HB highlightQuery(QueryBuilder highlightQuery) { this.highlightQuery = highlightQuery; return (HB) this; } @@ -283,7 +283,7 @@ public abstract class AbstractHighlighterBuilder highlightQuery() { + public QueryBuilder highlightQuery() { return this.highlightQuery; } diff --git a/core/src/main/java/org/elasticsearch/search/highlight/HighlightPhase.java b/core/src/main/java/org/elasticsearch/search/highlight/HighlightPhase.java index b6f41135025..92011fd77e7 100644 --- a/core/src/main/java/org/elasticsearch/search/highlight/HighlightPhase.java +++ b/core/src/main/java/org/elasticsearch/search/highlight/HighlightPhase.java @@ -26,6 +26,9 @@ import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.mapper.DocumentMapper; import org.elasticsearch.index.mapper.FieldMapper; +import org.elasticsearch.index.mapper.core.KeywordFieldMapper; +import org.elasticsearch.index.mapper.core.StringFieldMapper; +import org.elasticsearch.index.mapper.core.TextFieldMapper; import org.elasticsearch.index.mapper.internal.SourceFieldMapper; import org.elasticsearch.search.SearchParseElement; import org.elasticsearch.search.fetch.FetchSubPhase; @@ -102,6 +105,21 @@ public class HighlightPhase extends AbstractComponent implements FetchSubPhase { continue; } + // We should prevent highlighting if a field is anything but a text or keyword field. + // However, someone might implement a custom field type that has text and still want to + // highlight on that. We cannot know in advance if the highlighter will be able to + // highlight such a field and so we do the following: + // If the field is only highlighted because the field matches a wildcard we assume + // it was a mistake and do not process it. + // If the field was explicitly given we assume that whoever issued the query knew + // what they were doing and try to highlight anyway. + if (fieldNameContainsWildcards) { + if (fieldMapper.fieldType().typeName().equals(TextFieldMapper.CONTENT_TYPE) == false && + fieldMapper.fieldType().typeName().equals(KeywordFieldMapper.CONTENT_TYPE) == false && + fieldMapper.fieldType().typeName().equals(StringFieldMapper.CONTENT_TYPE) == false) { + continue; + } + } String highlighterType = field.fieldOptions().highlighterType(); if (highlighterType == null) { for(String highlighterCandidate : STANDARD_HIGHLIGHTERS_BY_PRECEDENCE) { diff --git a/core/src/main/java/org/elasticsearch/search/internal/DefaultSearchContext.java b/core/src/main/java/org/elasticsearch/search/internal/DefaultSearchContext.java index 435e809a893..96319303420 100644 --- a/core/src/main/java/org/elasticsearch/search/internal/DefaultSearchContext.java +++ b/core/src/main/java/org/elasticsearch/search/internal/DefaultSearchContext.java @@ -25,7 +25,6 @@ import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.Collector; import org.apache.lucene.search.ConstantScoreQuery; import org.apache.lucene.search.Query; -import org.apache.lucene.search.Sort; import org.apache.lucene.search.FieldDoc; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.Counter; @@ -71,6 +70,7 @@ import org.elasticsearch.search.profile.Profilers; import org.elasticsearch.search.query.QueryPhaseExecutionException; import org.elasticsearch.search.query.QuerySearchResult; import org.elasticsearch.search.rescore.RescoreSearchContext; +import org.elasticsearch.search.sort.SortAndFormats; import org.elasticsearch.search.suggest.SuggestionSearchContext; import java.io.IOException; @@ -114,7 +114,7 @@ public class DefaultSearchContext extends SearchContext { private FetchSourceContext fetchSourceContext; private int from = -1; private int size = -1; - private Sort sort; + private SortAndFormats sort; private Float minimumScore; private boolean trackScores = false; // when sorting, track scores as well... private FieldDoc searchAfter; @@ -532,13 +532,13 @@ public class DefaultSearchContext extends SearchContext { } @Override - public SearchContext sort(Sort sort) { + public SearchContext sort(SortAndFormats sort) { this.sort = sort; return this; } @Override - public Sort sort() { + public SortAndFormats sort() { return this.sort; } diff --git a/core/src/main/java/org/elasticsearch/search/internal/FilteredSearchContext.java b/core/src/main/java/org/elasticsearch/search/internal/FilteredSearchContext.java index 283e1dd60e8..8009d0b5fe4 100644 --- a/core/src/main/java/org/elasticsearch/search/internal/FilteredSearchContext.java +++ b/core/src/main/java/org/elasticsearch/search/internal/FilteredSearchContext.java @@ -22,7 +22,6 @@ package org.elasticsearch.search.internal; import org.apache.lucene.search.Collector; import org.apache.lucene.search.FieldDoc; import org.apache.lucene.search.Query; -import org.apache.lucene.search.Sort; import org.apache.lucene.util.Counter; import org.elasticsearch.action.search.SearchType; import org.elasticsearch.cache.recycler.PageCacheRecycler; @@ -55,6 +54,7 @@ import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.profile.Profilers; import org.elasticsearch.search.query.QuerySearchResult; import org.elasticsearch.search.rescore.RescoreSearchContext; +import org.elasticsearch.search.sort.SortAndFormats; import org.elasticsearch.search.suggest.SuggestionSearchContext; import java.util.List; @@ -306,12 +306,12 @@ public abstract class FilteredSearchContext extends SearchContext { } @Override - public SearchContext sort(Sort sort) { + public SearchContext sort(SortAndFormats sort) { return in.sort(sort); } @Override - public Sort sort() { + public SortAndFormats sort() { return in.sort(); } diff --git a/core/src/main/java/org/elasticsearch/search/internal/InternalSearchHit.java b/core/src/main/java/org/elasticsearch/search/internal/InternalSearchHit.java index 628f409974e..f67ed51b226 100644 --- a/core/src/main/java/org/elasticsearch/search/internal/InternalSearchHit.java +++ b/core/src/main/java/org/elasticsearch/search/internal/InternalSearchHit.java @@ -24,7 +24,6 @@ import org.apache.lucene.util.BytesRef; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Strings; -import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.compress.CompressorFactory; import org.elasticsearch.common.io.stream.StreamInput; @@ -34,6 +33,7 @@ import org.elasticsearch.common.text.Text; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentHelper; +import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHitField; import org.elasticsearch.search.SearchHits; @@ -44,6 +44,7 @@ import org.elasticsearch.search.lookup.SourceLookup; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -326,21 +327,13 @@ public class InternalSearchHit implements SearchHit { this.highlightFields = highlightFields; } - public void sortValues(Object[] sortValues) { - // LUCENE 4 UPGRADE: There must be a better way - // we want to convert to a Text object here, and not BytesRef - - // Don't write into sortValues! Otherwise the fields in FieldDoc is modified, which may be used in other places. (SearchContext#lastEmitedDoc) - Object[] sortValuesCopy = new Object[sortValues.length]; - System.arraycopy(sortValues, 0, sortValuesCopy, 0, sortValues.length); - if (sortValues != null) { - for (int i = 0; i < sortValues.length; i++) { - if (sortValues[i] instanceof BytesRef) { - sortValuesCopy[i] = new Text(new BytesArray((BytesRef) sortValues[i])); - } + public void sortValues(Object[] sortValues, DocValueFormat[] sortValueFormats) { + this.sortValues = Arrays.copyOf(sortValues, sortValues.length); + for (int i = 0; i < sortValues.length; ++i) { + if (this.sortValues[i] instanceof BytesRef) { + this.sortValues[i] = sortValueFormats[i].format((BytesRef) sortValues[i]); } } - this.sortValues = sortValuesCopy; } @Override @@ -618,8 +611,6 @@ public class InternalSearchHit implements SearchHit { sortValues[i] = in.readShort(); } else if (type == 8) { sortValues[i] = in.readBoolean(); - } else if (type == 9) { - sortValues[i] = in.readText(); } else { throw new IOException("Can't match type [" + type + "]"); } @@ -726,9 +717,6 @@ public class InternalSearchHit implements SearchHit { } else if (type == Boolean.class) { out.writeByte((byte) 8); out.writeBoolean((Boolean) sortValue); - } else if (sortValue instanceof Text) { - out.writeByte((byte) 9); - out.writeText((Text) sortValue); } else { throw new IOException("Can't handle sort field value of type [" + type + "]"); } diff --git a/core/src/main/java/org/elasticsearch/search/internal/SearchContext.java b/core/src/main/java/org/elasticsearch/search/internal/SearchContext.java index 8b55c764bbb..550a5f76caf 100644 --- a/core/src/main/java/org/elasticsearch/search/internal/SearchContext.java +++ b/core/src/main/java/org/elasticsearch/search/internal/SearchContext.java @@ -59,6 +59,7 @@ import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.profile.Profilers; import org.elasticsearch.search.query.QuerySearchResult; import org.elasticsearch.search.rescore.RescoreSearchContext; +import org.elasticsearch.search.sort.SortAndFormats; import org.elasticsearch.search.suggest.SuggestionSearchContext; import java.util.ArrayList; @@ -244,9 +245,9 @@ public abstract class SearchContext implements Releasable { public abstract Float minimumScore(); - public abstract SearchContext sort(Sort sort); + public abstract SearchContext sort(SortAndFormats sort); - public abstract Sort sort(); + public abstract SortAndFormats sort(); public abstract SearchContext trackScores(boolean trackScores); diff --git a/core/src/main/java/org/elasticsearch/search/internal/SubSearchContext.java b/core/src/main/java/org/elasticsearch/search/internal/SubSearchContext.java index be2c3798430..6cacf86d65f 100644 --- a/core/src/main/java/org/elasticsearch/search/internal/SubSearchContext.java +++ b/core/src/main/java/org/elasticsearch/search/internal/SubSearchContext.java @@ -19,19 +19,18 @@ package org.elasticsearch.search.internal; import org.apache.lucene.search.Query; -import org.apache.lucene.search.Sort; import org.apache.lucene.util.Counter; import org.elasticsearch.action.search.SearchType; import org.elasticsearch.index.query.ParsedQuery; import org.elasticsearch.search.aggregations.SearchContextAggregations; import org.elasticsearch.search.fetch.FetchSearchResult; -import org.elasticsearch.search.fetch.innerhits.InnerHitsContext; import org.elasticsearch.search.fetch.script.ScriptFieldsContext; import org.elasticsearch.search.fetch.source.FetchSourceContext; import org.elasticsearch.search.highlight.SearchContextHighlight; import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.query.QuerySearchResult; import org.elasticsearch.search.rescore.RescoreSearchContext; +import org.elasticsearch.search.sort.SortAndFormats; import org.elasticsearch.search.suggest.SuggestionSearchContext; import java.util.ArrayList; @@ -48,7 +47,7 @@ public class SubSearchContext extends FilteredSearchContext { private int from; private int size = DEFAULT_SIZE; - private Sort sort; + private SortAndFormats sort; private ParsedQuery parsedQuery; private Query query; @@ -172,13 +171,13 @@ public class SubSearchContext extends FilteredSearchContext { } @Override - public SearchContext sort(Sort sort) { + public SearchContext sort(SortAndFormats sort) { this.sort = sort; return this; } @Override - public Sort sort() { + public SortAndFormats sort() { return sort; } diff --git a/core/src/main/java/org/elasticsearch/search/query/QueryPhase.java b/core/src/main/java/org/elasticsearch/search/query/QueryPhase.java index 62210655a00..a29831f5a04 100644 --- a/core/src/main/java/org/elasticsearch/search/query/QueryPhase.java +++ b/core/src/main/java/org/elasticsearch/search/query/QueryPhase.java @@ -46,6 +46,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.lucene.MinimumScoreCollector; import org.elasticsearch.common.lucene.search.FilteredCollector; +import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.SearchParseElement; import org.elasticsearch.search.SearchPhase; import org.elasticsearch.search.SearchService; @@ -58,6 +59,7 @@ import org.elasticsearch.search.profile.ProfileShardResult; import org.elasticsearch.search.profile.Profiler; import org.elasticsearch.search.rescore.RescorePhase; import org.elasticsearch.search.rescore.RescoreSearchContext; +import org.elasticsearch.search.sort.SortAndFormats; import org.elasticsearch.search.sort.TrackScoresParseElement; import org.elasticsearch.search.suggest.SuggestPhase; @@ -119,7 +121,9 @@ public class QueryPhase implements SearchPhase { if (searchContext.hasOnlySuggest()) { suggestPhase.execute(searchContext); // TODO: fix this once we can fetch docs for suggestions - searchContext.queryResult().topDocs(new TopDocs(0, Lucene.EMPTY_SCORE_DOCS, 0)); + searchContext.queryResult().topDocs( + new TopDocs(0, Lucene.EMPTY_SCORE_DOCS, 0), + new DocValueFormat[0]); return; } // Pre-process aggregations as late as possible. In the case of a DFS_Q_T_F @@ -141,15 +145,15 @@ public class QueryPhase implements SearchPhase { } } - private static boolean returnsDocsInOrder(Query query, Sort sort) { - if (sort == null || Sort.RELEVANCE.equals(sort)) { + private static boolean returnsDocsInOrder(Query query, SortAndFormats sf) { + if (sf == null || Sort.RELEVANCE.equals(sf.sort)) { // sort by score // queries that return constant scores will return docs in index // order since Lucene tie-breaks on the doc id return query.getClass() == ConstantScoreQuery.class || query.getClass() == MatchAllDocsQuery.class; } else { - return Sort.INDEXORDER.equals(sort); + return Sort.INDEXORDER.equals(sf.sort); } } @@ -176,6 +180,7 @@ public class QueryPhase implements SearchPhase { Collector collector; Callable topDocsCallable; + DocValueFormat[] sortValueFormats = new DocValueFormat[0]; assert query == searcher.rewrite(query); // already rewritten @@ -229,8 +234,10 @@ public class QueryPhase implements SearchPhase { } assert numDocs > 0; if (searchContext.sort() != null) { - topDocsCollector = TopFieldCollector.create(searchContext.sort(), numDocs, + SortAndFormats sf = searchContext.sort(); + topDocsCollector = TopFieldCollector.create(sf.sort, numDocs, (FieldDoc) after, true, searchContext.trackScores(), searchContext.trackScores()); + sortValueFormats = sf.formats; } else { rescore = !searchContext.rescore().isEmpty(); for (RescoreSearchContext rescoreContext : searchContext.rescore()) { @@ -402,7 +409,7 @@ public class QueryPhase implements SearchPhase { queryResult.terminatedEarly(false); } - queryResult.topDocs(topDocsCallable.call()); + queryResult.topDocs(topDocsCallable.call(), sortValueFormats); if (searchContext.getProfilers() != null) { List shardResults = Profiler.buildShardResults(searchContext.getProfilers().getProfilers()); diff --git a/core/src/main/java/org/elasticsearch/search/query/QuerySearchResult.java b/core/src/main/java/org/elasticsearch/search/query/QuerySearchResult.java index 2b82633ebfd..1408ebe8359 100644 --- a/core/src/main/java/org/elasticsearch/search/query/QuerySearchResult.java +++ b/core/src/main/java/org/elasticsearch/search/query/QuerySearchResult.java @@ -19,12 +19,14 @@ package org.elasticsearch.search.query; +import org.apache.lucene.search.FieldDoc; import org.apache.lucene.search.TopDocs; import org.elasticsearch.Version; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.SearchShardTarget; import org.elasticsearch.search.aggregations.Aggregations; import org.elasticsearch.search.aggregations.InternalAggregations; @@ -51,6 +53,7 @@ public class QuerySearchResult extends QuerySearchResultProvider { private int from; private int size; private TopDocs topDocs; + private DocValueFormat[] sortValueFormats; private InternalAggregations aggregations; private List pipelineAggregators; private Suggest suggest; @@ -112,8 +115,20 @@ public class QuerySearchResult extends QuerySearchResultProvider { return topDocs; } - public void topDocs(TopDocs topDocs) { + public void topDocs(TopDocs topDocs, DocValueFormat[] sortValueFormats) { this.topDocs = topDocs; + if (topDocs.scoreDocs.length > 0 && topDocs.scoreDocs[0] instanceof FieldDoc) { + int numFields = ((FieldDoc) topDocs.scoreDocs[0]).fields.length; + if (numFields != sortValueFormats.length) { + throw new IllegalArgumentException("The number of sort fields does not match: " + + numFields + " != " + sortValueFormats.length); + } + } + this.sortValueFormats = sortValueFormats; + } + + public DocValueFormat[] sortValueFormats() { + return sortValueFormats; } public Aggregations aggregations() { @@ -192,6 +207,15 @@ public class QuerySearchResult extends QuerySearchResultProvider { // shardTarget = readSearchShardTarget(in); from = in.readVInt(); size = in.readVInt(); + int numSortFieldsPlus1 = in.readVInt(); + if (numSortFieldsPlus1 == 0) { + sortValueFormats = null; + } else { + sortValueFormats = new DocValueFormat[numSortFieldsPlus1 - 1]; + for (int i = 0; i < sortValueFormats.length; ++i) { + sortValueFormats[i] = in.readNamedWriteable(DocValueFormat.class); + } + } topDocs = readTopDocs(in); if (in.readBoolean()) { aggregations = InternalAggregations.readAggregations(in); @@ -233,6 +257,14 @@ public class QuerySearchResult extends QuerySearchResultProvider { // shardTarget.writeTo(out); out.writeVInt(from); out.writeVInt(size); + if (sortValueFormats == null) { + out.writeVInt(0); + } else { + out.writeVInt(1 + sortValueFormats.length); + for (int i = 0; i < sortValueFormats.length; ++i) { + out.writeNamedWriteable(sortValueFormats[i]); + } + } writeTopDocs(out, topDocs); if (aggregations == null) { out.writeBoolean(false); diff --git a/core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java b/core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java index 2d4778012d3..e91468c805f 100644 --- a/core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java @@ -41,7 +41,7 @@ public class QueryRescorerBuilder extends RescoreBuilder { public static final float DEFAULT_RESCORE_QUERYWEIGHT = 1.0f; public static final float DEFAULT_QUERYWEIGHT = 1.0f; public static final QueryRescoreMode DEFAULT_SCORE_MODE = QueryRescoreMode.Total; - private final QueryBuilder queryBuilder; + private final QueryBuilder queryBuilder; private float rescoreQueryWeight = DEFAULT_RESCORE_QUERYWEIGHT; private float queryWeight = DEFAULT_QUERYWEIGHT; private QueryRescoreMode scoreMode = DEFAULT_SCORE_MODE; @@ -70,7 +70,7 @@ public class QueryRescorerBuilder extends RescoreBuilder { * Creates a new {@link QueryRescorerBuilder} instance * @param builder the query builder to build the rescore query from */ - public QueryRescorerBuilder(QueryBuilder builder) { + public QueryRescorerBuilder(QueryBuilder builder) { this.queryBuilder = builder; } @@ -96,7 +96,7 @@ public class QueryRescorerBuilder extends RescoreBuilder { /** * @return the query used for this rescore query */ - public QueryBuilder getRescoreQuery() { + public QueryBuilder getRescoreQuery() { return this.queryBuilder; } @@ -209,12 +209,12 @@ public class QueryRescorerBuilder extends RescoreBuilder { */ private static class InnerBuilder { - private QueryBuilder queryBuilder; + private QueryBuilder queryBuilder; private float rescoreQueryWeight = DEFAULT_RESCORE_QUERYWEIGHT; private float queryWeight = DEFAULT_QUERYWEIGHT; private QueryRescoreMode scoreMode = DEFAULT_SCORE_MODE; - void setQueryBuilder(QueryBuilder builder) { + void setQueryBuilder(QueryBuilder builder) { this.queryBuilder = builder; } diff --git a/core/src/main/java/org/elasticsearch/search/rescore/RescoreBuilder.java b/core/src/main/java/org/elasticsearch/search/rescore/RescoreBuilder.java index e29e7dcd6e9..16c9c9ba8c7 100644 --- a/core/src/main/java/org/elasticsearch/search/rescore/RescoreBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/rescore/RescoreBuilder.java @@ -125,7 +125,7 @@ public abstract class RescoreBuilder> extends ToXC public abstract QueryRescoreContext build(QueryShardContext context) throws IOException; - public static QueryRescorerBuilder queryRescorer(QueryBuilder queryBuilder) { + public static QueryRescorerBuilder queryRescorer(QueryBuilder queryBuilder) { return new QueryRescorerBuilder(queryBuilder); } diff --git a/core/src/main/java/org/elasticsearch/search/rescore/RescorePhase.java b/core/src/main/java/org/elasticsearch/search/rescore/RescorePhase.java index 732a80bad20..b82ed941e1c 100644 --- a/core/src/main/java/org/elasticsearch/search/rescore/RescorePhase.java +++ b/core/src/main/java/org/elasticsearch/search/rescore/RescorePhase.java @@ -61,7 +61,7 @@ public class RescorePhase extends AbstractComponent implements SearchPhase { for (RescoreSearchContext ctx : context.rescore()) { topDocs = ctx.rescorer().rescore(topDocs, context, ctx); } - context.queryResult().topDocs(topDocs); + context.queryResult().topDocs(topDocs, context.queryResult().sortValueFormats()); } catch (IOException e) { throw new ElasticsearchException("Rescore Phase Failed", e); } diff --git a/core/src/main/java/org/elasticsearch/search/searchafter/SearchAfterBuilder.java b/core/src/main/java/org/elasticsearch/search/searchafter/SearchAfterBuilder.java index 6d72efdf368..6ed4b0db5bc 100644 --- a/core/src/main/java/org/elasticsearch/search/searchafter/SearchAfterBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/searchafter/SearchAfterBuilder.java @@ -20,9 +20,7 @@ package org.elasticsearch.search.searchafter; import org.apache.lucene.search.FieldDoc; -import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortField; -import org.apache.lucene.util.BytesRef; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.ParseFieldMatcher; @@ -36,6 +34,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.fielddata.IndexFieldData; +import org.elasticsearch.search.DocValueFormat; +import org.elasticsearch.search.sort.SortAndFormats; import java.io.IOException; import java.util.ArrayList; @@ -104,21 +104,23 @@ public class SearchAfterBuilder implements ToXContent, Writeable { return Arrays.copyOf(sortValues, sortValues.length); } - public static FieldDoc buildFieldDoc(Sort sort, Object[] values) { - if (sort == null || sort.getSort() == null || sort.getSort().length == 0) { + public static FieldDoc buildFieldDoc(SortAndFormats sort, Object[] values) { + if (sort == null || sort.sort.getSort() == null || sort.sort.getSort().length == 0) { throw new IllegalArgumentException("Sort must contain at least one field."); } - SortField[] sortFields = sort.getSort(); + SortField[] sortFields = sort.sort.getSort(); if (sortFields.length != values.length) { throw new IllegalArgumentException( - SEARCH_AFTER.getPreferredName() + " has " + values.length + " value(s) but sort has " + sort.getSort().length + "."); + SEARCH_AFTER.getPreferredName() + " has " + values.length + " value(s) but sort has " + + sort.sort.getSort().length + "."); } Object[] fieldValues = new Object[sortFields.length]; for (int i = 0; i < sortFields.length; i++) { SortField sortField = sortFields[i]; + DocValueFormat format = sort.formats[i]; if (values[i] != null) { - fieldValues[i] = convertValueFromSortField(values[i], sortField); + fieldValues[i] = convertValueFromSortField(values[i], sortField, format); } else { fieldValues[i] = null; } @@ -130,15 +132,15 @@ public class SearchAfterBuilder implements ToXContent, Writeable { return new FieldDoc(Integer.MAX_VALUE, 0, fieldValues); } - private static Object convertValueFromSortField(Object value, SortField sortField) { + private static Object convertValueFromSortField(Object value, SortField sortField, DocValueFormat format) { if (sortField.getComparatorSource() instanceof IndexFieldData.XFieldComparatorSource) { IndexFieldData.XFieldComparatorSource cmpSource = (IndexFieldData.XFieldComparatorSource) sortField.getComparatorSource(); - return convertValueFromSortType(sortField.getField(), cmpSource.reducedType(), value); + return convertValueFromSortType(sortField.getField(), cmpSource.reducedType(), value, format); } - return convertValueFromSortType(sortField.getField(), sortField.getType(), value); + return convertValueFromSortType(sortField.getField(), sortField.getType(), value, format); } - private static Object convertValueFromSortType(String fieldName, SortField.Type sortType, Object value) { + private static Object convertValueFromSortType(String fieldName, SortField.Type sortType, Object value, DocValueFormat format) { try { switch (sortType) { case DOC: @@ -179,7 +181,7 @@ public class SearchAfterBuilder implements ToXContent, Writeable { case STRING_VAL: case STRING: - return new BytesRef(value.toString()); + return format.parseBytesRef(value.toString()); default: throw new IllegalArgumentException("Comparator type [" + sortType.name() + "] for field [" + fieldName diff --git a/core/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java b/core/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java index 8d89322e5cd..892673f890a 100644 --- a/core/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java @@ -34,6 +34,7 @@ import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.index.query.QueryShardException; +import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.MultiValueMode; import java.io.IOException; @@ -55,8 +56,10 @@ public class FieldSortBuilder extends SortBuilder { * special field name to sort by index order */ public static final String DOC_FIELD_NAME = "_doc"; - private static final SortField SORT_DOC = new SortField(null, SortField.Type.DOC); - private static final SortField SORT_DOC_REVERSE = new SortField(null, SortField.Type.DOC, true); + private static final SortFieldAndFormat SORT_DOC = new SortFieldAndFormat( + new SortField(null, SortField.Type.DOC), DocValueFormat.RAW); + private static final SortFieldAndFormat SORT_DOC_REVERSE = new SortFieldAndFormat( + new SortField(null, SortField.Type.DOC, true), DocValueFormat.RAW); private final String fieldName; @@ -66,7 +69,7 @@ public class FieldSortBuilder extends SortBuilder { private SortMode sortMode; - private QueryBuilder nestedFilter; + private QueryBuilder nestedFilter; private String nestedPath; @@ -189,7 +192,7 @@ public class FieldSortBuilder extends SortBuilder { * TODO should the above getters and setters be deprecated/ changed in * favour of real getters and setters? */ - public FieldSortBuilder setNestedFilter(QueryBuilder nestedFilter) { + public FieldSortBuilder setNestedFilter(QueryBuilder nestedFilter) { this.nestedFilter = nestedFilter; return this; } @@ -198,7 +201,7 @@ public class FieldSortBuilder extends SortBuilder { * Returns the nested filter that the nested objects should match with in * order to be taken into account for sorting. */ - public QueryBuilder getNestedFilter() { + public QueryBuilder getNestedFilter() { return this.nestedFilter; } @@ -246,7 +249,7 @@ public class FieldSortBuilder extends SortBuilder { } @Override - public SortField build(QueryShardContext context) throws IOException { + public SortFieldAndFormat build(QueryShardContext context) throws IOException { if (DOC_FIELD_NAME.equals(fieldName)) { if (order == SortOrder.DESC) { return SORT_DOC_REVERSE; @@ -281,7 +284,8 @@ public class FieldSortBuilder extends SortBuilder { } IndexFieldData.XFieldComparatorSource fieldComparatorSource = fieldData .comparatorSource(missing, localSortMode, nested); - return new SortField(fieldType.name(), fieldComparatorSource, reverse); + SortField field = new SortField(fieldType.name(), fieldComparatorSource, reverse); + return new SortFieldAndFormat(field, fieldType.docValueFormat(null, null)); } } @@ -324,7 +328,7 @@ public class FieldSortBuilder extends SortBuilder { public static FieldSortBuilder fromXContent(QueryParseContext context, String fieldName) throws IOException { XContentParser parser = context.parser(); - QueryBuilder nestedFilter = null; + QueryBuilder nestedFilter = null; String nestedPath = null; Object missing = null; SortOrder order = null; diff --git a/core/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortBuilder.java b/core/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortBuilder.java index 2e08e38a96a..dce9a7ec3fe 100644 --- a/core/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortBuilder.java @@ -51,6 +51,7 @@ import org.elasticsearch.index.query.GeoValidationMethod; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryShardContext; +import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.MultiValueMode; import java.io.IOException; @@ -292,7 +293,7 @@ public class GeoDistanceSortBuilder extends SortBuilder * Sets the nested filter that the nested objects should match with in order to be taken into account * for sorting. */ - public GeoDistanceSortBuilder setNestedFilter(QueryBuilder nestedFilter) { + public GeoDistanceSortBuilder setNestedFilter(QueryBuilder nestedFilter) { this.nestedFilter = nestedFilter; return this; } @@ -301,7 +302,7 @@ public class GeoDistanceSortBuilder extends SortBuilder * Returns the nested filter that the nested objects should match with in order to be taken into account * for sorting. **/ - public QueryBuilder getNestedFilter() { + public QueryBuilder getNestedFilter() { return this.nestedFilter; } @@ -406,7 +407,7 @@ public class GeoDistanceSortBuilder extends SortBuilder GeoDistance geoDistance = GeoDistance.DEFAULT; SortOrder order = SortOrder.ASC; SortMode sortMode = null; - QueryBuilder nestedFilter = null; + QueryBuilder nestedFilter = null; String nestedPath = null; boolean coerce = GeoValidationMethod.DEFAULT_LENIENT_PARSING; @@ -504,7 +505,7 @@ public class GeoDistanceSortBuilder extends SortBuilder } @Override - public SortField build(QueryShardContext context) throws IOException { + public SortFieldAndFormat build(QueryShardContext context) throws IOException { final boolean indexCreatedBeforeV2_0 = context.indexVersionCreated().before(Version.V_2_0_0); // validation was not available prior to 2.x, so to support bwc percolation queries we only ignore_malformed on 2.x created indexes List localPoints = new ArrayList(); @@ -585,7 +586,7 @@ public class GeoDistanceSortBuilder extends SortBuilder }; - return new SortField(fieldName, geoDistanceComparatorSource, reverse); + return new SortFieldAndFormat(new SortField(fieldName, geoDistanceComparatorSource, reverse), DocValueFormat.RAW); } static void parseGeoPoints(XContentParser parser, List geoPoints) throws IOException { diff --git a/core/src/main/java/org/elasticsearch/search/sort/ScoreSortBuilder.java b/core/src/main/java/org/elasticsearch/search/sort/ScoreSortBuilder.java index 8267429f77c..5b9b139e495 100644 --- a/core/src/main/java/org/elasticsearch/search/sort/ScoreSortBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/sort/ScoreSortBuilder.java @@ -29,6 +29,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryShardContext; +import org.elasticsearch.search.DocValueFormat; import java.io.IOException; import java.util.Objects; @@ -40,8 +41,10 @@ public class ScoreSortBuilder extends SortBuilder { public static final String NAME = "_score"; public static final ParseField ORDER_FIELD = new ParseField("order"); - private static final SortField SORT_SCORE = new SortField(null, SortField.Type.SCORE); - private static final SortField SORT_SCORE_REVERSE = new SortField(null, SortField.Type.SCORE, true); + private static final SortFieldAndFormat SORT_SCORE = new SortFieldAndFormat( + new SortField(null, SortField.Type.SCORE), DocValueFormat.RAW); + private static final SortFieldAndFormat SORT_SCORE_REVERSE = new SortFieldAndFormat( + new SortField(null, SortField.Type.SCORE, true), DocValueFormat.RAW); /** * Build a ScoreSortBuilder default to descending sort order. @@ -106,7 +109,7 @@ public class ScoreSortBuilder extends SortBuilder { } @Override - public SortField build(QueryShardContext context) { + public SortFieldAndFormat build(QueryShardContext context) { if (order == SortOrder.DESC) { return SORT_SCORE; } else { diff --git a/core/src/main/java/org/elasticsearch/search/sort/ScriptSortBuilder.java b/core/src/main/java/org/elasticsearch/search/sort/ScriptSortBuilder.java index 8a713e4992b..eeb418c0a97 100644 --- a/core/src/main/java/org/elasticsearch/search/sort/ScriptSortBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/sort/ScriptSortBuilder.java @@ -52,6 +52,7 @@ import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptParameterParser; import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue; import org.elasticsearch.script.SearchScript; +import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.MultiValueMode; import java.io.IOException; @@ -80,7 +81,7 @@ public class ScriptSortBuilder extends SortBuilder { private SortMode sortMode; - private QueryBuilder nestedFilter; + private QueryBuilder nestedFilter; private String nestedPath; @@ -170,7 +171,7 @@ public class ScriptSortBuilder extends SortBuilder { * Sets the nested filter that the nested objects should match with in order to be taken into account * for sorting. */ - public ScriptSortBuilder setNestedFilter(QueryBuilder nestedFilter) { + public ScriptSortBuilder setNestedFilter(QueryBuilder nestedFilter) { this.nestedFilter = nestedFilter; return this; } @@ -178,7 +179,7 @@ public class ScriptSortBuilder extends SortBuilder { /** * Gets the nested filter. */ - public QueryBuilder getNestedFilter() { + public QueryBuilder getNestedFilter() { return this.nestedFilter; } @@ -236,7 +237,7 @@ public class ScriptSortBuilder extends SortBuilder { ScriptSortType type = null; SortMode sortMode = null; SortOrder order = null; - QueryBuilder nestedFilter = null; + QueryBuilder nestedFilter = null; String nestedPath = null; Map params = new HashMap<>(); @@ -302,7 +303,7 @@ public class ScriptSortBuilder extends SortBuilder { @Override - public SortField build(QueryShardContext context) throws IOException { + public SortFieldAndFormat build(QueryShardContext context) throws IOException { final SearchScript searchScript = context.getScriptService().search( context.lookup(), script, ScriptContext.Standard.SEARCH, Collections.emptyMap(), context.getClusterState()); @@ -366,7 +367,7 @@ public class ScriptSortBuilder extends SortBuilder { throw new QueryShardException(context, "custom script sort type [" + type + "] not supported"); } - return new SortField("_script", fieldComparatorSource, reverse); + return new SortFieldAndFormat(new SortField("_script", fieldComparatorSource, reverse), DocValueFormat.RAW); } @Override diff --git a/core/src/main/java/org/elasticsearch/search/sort/SortAndFormats.java b/core/src/main/java/org/elasticsearch/search/sort/SortAndFormats.java new file mode 100644 index 00000000000..21a9d112fea --- /dev/null +++ b/core/src/main/java/org/elasticsearch/search/sort/SortAndFormats.java @@ -0,0 +1,38 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.elasticsearch.search.sort; + +import org.apache.lucene.search.Sort; +import org.elasticsearch.search.DocValueFormat; + +public final class SortAndFormats { + + public final Sort sort; + public final DocValueFormat[] formats; + + public SortAndFormats(Sort sort, DocValueFormat[] formats) { + if (sort.getSort().length != formats.length) { + throw new IllegalArgumentException("Number of sort field mismatch: " + + sort.getSort().length + " != " + formats.length); + } + this.sort = sort; + this.formats = formats; + } + +} diff --git a/core/src/main/java/org/elasticsearch/search/sort/SortBuilder.java b/core/src/main/java/org/elasticsearch/search/sort/SortBuilder.java index 805d6e90c47..7fb0baf6548 100644 --- a/core/src/main/java/org/elasticsearch/search/sort/SortBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/sort/SortBuilder.java @@ -34,6 +34,7 @@ import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.index.query.QueryShardException; +import org.elasticsearch.search.DocValueFormat; import java.io.IOException; import java.util.ArrayList; @@ -65,9 +66,9 @@ public abstract class SortBuilder> extends ToXContentTo } /** - * Create a @link {@link SortField} from this builder. + * Create a @link {@link SortFieldAndFormat} from this builder. */ - protected abstract SortField build(QueryShardContext context) throws IOException; + protected abstract SortFieldAndFormat build(QueryShardContext context) throws IOException; /** * Set the order of sorting. @@ -143,10 +144,13 @@ public abstract class SortBuilder> extends ToXContentTo } } - public static Optional buildSort(List> sortBuilders, QueryShardContext context) throws IOException { + public static Optional buildSort(List> sortBuilders, QueryShardContext context) throws IOException { List sortFields = new ArrayList<>(sortBuilders.size()); + List sortFormats = new ArrayList<>(sortBuilders.size()); for (SortBuilder builder : sortBuilders) { - sortFields.add(builder.build(context)); + SortFieldAndFormat sf = builder.build(context); + sortFields.add(sf.field); + sortFormats.add(sf.format); } if (!sortFields.isEmpty()) { // optimize if we just sort on score non reversed, we don't really @@ -163,13 +167,15 @@ public abstract class SortBuilder> extends ToXContentTo } } if (sort) { - return Optional.of(new Sort(sortFields.toArray(new SortField[sortFields.size()]))); + return Optional.of(new SortAndFormats( + new Sort(sortFields.toArray(new SortField[sortFields.size()])), + sortFormats.toArray(new DocValueFormat[sortFormats.size()]))); } } return Optional.empty(); } - protected static Nested resolveNested(QueryShardContext context, String nestedPath, QueryBuilder nestedFilter) throws IOException { + protected static Nested resolveNested(QueryShardContext context, String nestedPath, QueryBuilder nestedFilter) throws IOException { Nested nested = null; if (nestedPath != null) { BitSetProducer rootDocumentsFilter = context.bitsetFilter(Queries.newNonNestedFilter()); diff --git a/core/src/main/java/org/elasticsearch/search/sort/SortFieldAndFormat.java b/core/src/main/java/org/elasticsearch/search/sort/SortFieldAndFormat.java new file mode 100644 index 00000000000..f9756b79068 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/search/sort/SortFieldAndFormat.java @@ -0,0 +1,36 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.elasticsearch.search.sort; + +import java.util.Objects; + +import org.apache.lucene.search.SortField; +import org.elasticsearch.search.DocValueFormat; + +public final class SortFieldAndFormat { + + public final SortField field; + public final DocValueFormat format; + + public SortFieldAndFormat(SortField field, DocValueFormat format) { + this.field = Objects.requireNonNull(field); + this.format = Objects.requireNonNull(format); + } + +} diff --git a/core/src/main/java/org/elasticsearch/snapshots/RestoreService.java b/core/src/main/java/org/elasticsearch/snapshots/RestoreService.java index 8419b7c2667..5338f927005 100644 --- a/core/src/main/java/org/elasticsearch/snapshots/RestoreService.java +++ b/core/src/main/java/org/elasticsearch/snapshots/RestoreService.java @@ -190,7 +190,7 @@ public class RestoreService extends AbstractComponent implements ClusterStateLis // Read snapshot info and metadata from the repository Repository repository = repositoriesService.repository(request.repository()); final SnapshotId snapshotId = new SnapshotId(request.repository(), request.name()); - final Snapshot snapshot = repository.readSnapshot(snapshotId); + final SnapshotInfo snapshot = repository.readSnapshot(snapshotId); List filteredIndices = SnapshotUtils.filterIndices(snapshot.indices(), request.indices(), request.indicesOptions()); MetaData metaDataIn = repository.readSnapshotMetaData(snapshotId, snapshot, filteredIndices); @@ -708,7 +708,7 @@ public class RestoreService extends AbstractComponent implements ClusterStateLis * @param snapshotId snapshot id * @param snapshot snapshot metadata */ - private void validateSnapshotRestorable(SnapshotId snapshotId, Snapshot snapshot) { + private void validateSnapshotRestorable(SnapshotId snapshotId, SnapshotInfo snapshot) { if (!snapshot.state().restorable()) { throw new SnapshotRestoreException(snapshotId, "unsupported snapshot state [" + snapshot.state() + "]"); } @@ -765,7 +765,7 @@ public class RestoreService extends AbstractComponent implements ClusterStateLis UPDATE_RESTORE_ACTION_NAME, request, EmptyTransportResponseHandler.INSTANCE_SAME); } - private boolean failed(Snapshot snapshot, String index) { + private boolean failed(SnapshotInfo snapshot, String index) { for (SnapshotShardFailure failure : snapshot.shardFailures()) { if (index.equals(failure.index())) { return true; diff --git a/core/src/main/java/org/elasticsearch/snapshots/Snapshot.java b/core/src/main/java/org/elasticsearch/snapshots/Snapshot.java deleted file mode 100644 index 13ec659b629..00000000000 --- a/core/src/main/java/org/elasticsearch/snapshots/Snapshot.java +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.snapshots; - -import org.elasticsearch.ElasticsearchParseException; -import org.elasticsearch.Version; -import org.elasticsearch.common.ParseFieldMatcher; -import org.elasticsearch.common.xcontent.FromXContentBuilder; -import org.elasticsearch.common.xcontent.ToXContent; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentParser; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Represent information about snapshot - */ -public class Snapshot implements Comparable, ToXContent, FromXContentBuilder { - - private final String name; - - private final Version version; - - private final SnapshotState state; - - private final String reason; - - private final List indices; - - private final long startTime; - - private final long endTime; - - private final int totalShard; - - private final int successfulShards; - - private final List shardFailures; - - private final static List NO_FAILURES = Collections.emptyList(); - - public final static Snapshot PROTO = new Snapshot(); - - private Snapshot(String name, List indices, SnapshotState state, String reason, Version version, long startTime, long endTime, - int totalShard, int successfulShards, List shardFailures) { - assert name != null; - assert indices != null; - assert state != null; - assert shardFailures != null; - this.name = name; - this.indices = indices; - this.state = state; - this.reason = reason; - this.version = version; - this.startTime = startTime; - this.endTime = endTime; - this.totalShard = totalShard; - this.successfulShards = successfulShards; - this.shardFailures = shardFailures; - } - - - public Snapshot(String name, List indices, long startTime) { - this(name, indices, SnapshotState.IN_PROGRESS, null, Version.CURRENT, startTime, 0L, 0, 0, NO_FAILURES); - } - - public Snapshot(String name, List indices, long startTime, String reason, long endTime, - int totalShard, List shardFailures) { - this(name, indices, snapshotState(reason, shardFailures), reason, Version.CURRENT, - startTime, endTime, totalShard, totalShard - shardFailures.size(), shardFailures); - } - - /** - * Special constructor for the prototype object - */ - private Snapshot() { - this("", Collections.emptyList(), 0); - } - - private static SnapshotState snapshotState(String reason, List shardFailures) { - if (reason == null) { - if (shardFailures.isEmpty()) { - return SnapshotState.SUCCESS; - } else { - return SnapshotState.PARTIAL; - } - } else { - return SnapshotState.FAILED; - } - } - - /** - * Returns snapshot name - * - * @return snapshot name - */ - public String name() { - return name; - } - - /** - * Returns current snapshot state - * - * @return snapshot state - */ - public SnapshotState state() { - return state; - } - - /** - * Returns reason for complete snapshot failure - * - * @return snapshot failure reason - */ - public String reason() { - return reason; - } - - /** - * Returns version of Elasticsearch that was used to create this snapshot - * - * @return Elasticsearch version - */ - public Version version() { - return version; - } - - /** - * Returns indices that were included into this snapshot - * - * @return list of indices - */ - public List indices() { - return indices; - } - - /** - * Returns time when snapshot started - * - * @return snapshot start time - */ - public long startTime() { - return startTime; - } - - /** - * Returns time when snapshot ended - *

- * Can be 0L if snapshot is still running - * - * @return snapshot end time - */ - public long endTime() { - return endTime; - } - - /** - * Returns total number of shards that were snapshotted - * - * @return number of shards - */ - public int totalShard() { - return totalShard; - } - - /** - * Returns total number of shards that were successfully snapshotted - * - * @return number of successful shards - */ - public int successfulShards() { - return successfulShards; - } - - /** - * Returns shard failures - */ - public List shardFailures() { - return shardFailures; - } - - /** - * Compares two snapshots by their start time - * - * @param o other snapshot - * @return the value {@code 0} if snapshots were created at the same time; - * a value less than {@code 0} if this snapshot was created before snapshot {@code o}; and - * a value greater than {@code 0} if this snapshot was created after snapshot {@code o}; - */ - @Override - public int compareTo(Snapshot o) { - return Long.compare(startTime, o.startTime); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Snapshot that = (Snapshot) o; - - if (startTime != that.startTime) return false; - if (!name.equals(that.name)) return false; - - return true; - } - - @Override - public int hashCode() { - int result = name.hashCode(); - result = 31 * result + Long.hashCode(startTime); - return result; - } - - @Override - public Snapshot fromXContent(XContentParser parser, ParseFieldMatcher parseFieldMatcher) throws IOException { - return fromXContent(parser); - } - - static final class Fields { - static final String SNAPSHOT = "snapshot"; - static final String NAME = "name"; - static final String VERSION_ID = "version_id"; - static final String INDICES = "indices"; - static final String STATE = "state"; - static final String REASON = "reason"; - static final String START_TIME = "start_time"; - static final String END_TIME = "end_time"; - static final String TOTAL_SHARDS = "total_shards"; - static final String SUCCESSFUL_SHARDS = "successful_shards"; - static final String FAILURES = "failures"; - } - - - @Override - public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException { - builder.startObject(Fields.SNAPSHOT); - builder.field(Fields.NAME, name); - builder.field(Fields.VERSION_ID, version.id); - builder.startArray(Fields.INDICES); - for (String index : indices) { - builder.value(index); - } - builder.endArray(); - builder.field(Fields.STATE, state); - if (reason != null) { - builder.field(Fields.REASON, reason); - } - builder.field(Fields.START_TIME, startTime); - builder.field(Fields.END_TIME, endTime); - builder.field(Fields.TOTAL_SHARDS, totalShard); - builder.field(Fields.SUCCESSFUL_SHARDS, successfulShards); - builder.startArray(Fields.FAILURES); - for (SnapshotShardFailure shardFailure : shardFailures) { - builder.startObject(); - shardFailure.toXContent(builder, params); - builder.endObject(); - } - builder.endArray(); - builder.endObject(); - return builder; - } - - - public static Snapshot fromXContent(XContentParser parser) throws IOException { - String name = null; - Version version = Version.CURRENT; - SnapshotState state = SnapshotState.IN_PROGRESS; - String reason = null; - List indices = Collections.emptyList(); - long startTime = 0; - long endTime = 0; - int totalShard = 0; - int successfulShards = 0; - List shardFailures = NO_FAILURES; - if (parser.currentToken() == null) { // fresh parser? move to the first token - parser.nextToken(); - } - if (parser.currentToken() == XContentParser.Token.START_OBJECT) { // on a start object move to next token - parser.nextToken(); - } - XContentParser.Token token; - if ((token = parser.nextToken()) == XContentParser.Token.START_OBJECT) { - String currentFieldName = parser.currentName(); - if ("snapshot".equals(currentFieldName)) { - while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { - if (token == XContentParser.Token.FIELD_NAME) { - currentFieldName = parser.currentName(); - token = parser.nextToken(); - if (token.isValue()) { - if ("name".equals(currentFieldName)) { - name = parser.text(); - } else if ("state".equals(currentFieldName)) { - state = SnapshotState.valueOf(parser.text()); - } else if ("reason".equals(currentFieldName)) { - reason = parser.text(); - } else if ("start_time".equals(currentFieldName)) { - startTime = parser.longValue(); - } else if ("end_time".equals(currentFieldName)) { - endTime = parser.longValue(); - } else if ("total_shards".equals(currentFieldName)) { - totalShard = parser.intValue(); - } else if ("successful_shards".equals(currentFieldName)) { - successfulShards = parser.intValue(); - } else if ("version_id".equals(currentFieldName)) { - version = Version.fromId(parser.intValue()); - } - } else if (token == XContentParser.Token.START_ARRAY) { - if ("indices".equals(currentFieldName)) { - ArrayList indicesArray = new ArrayList<>(); - while (parser.nextToken() != XContentParser.Token.END_ARRAY) { - indicesArray.add(parser.text()); - } - indices = Collections.unmodifiableList(indicesArray); - } else if ("failures".equals(currentFieldName)) { - ArrayList shardFailureArrayList = new ArrayList<>(); - while (parser.nextToken() != XContentParser.Token.END_ARRAY) { - shardFailureArrayList.add(SnapshotShardFailure.fromXContent(parser)); - } - shardFailures = Collections.unmodifiableList(shardFailureArrayList); - } else { - // It was probably created by newer version - ignoring - parser.skipChildren(); - } - } else if (token == XContentParser.Token.START_OBJECT) { - // It was probably created by newer version - ignoring - parser.skipChildren(); - } - } - } - } - } else { - throw new ElasticsearchParseException("unexpected token [" + token + "]"); - } - return new Snapshot(name, indices, state, reason, version, startTime, endTime, totalShard, successfulShards, shardFailures); - } - -} diff --git a/core/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java b/core/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java index 354094404ae..871e765cfd0 100644 --- a/core/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java +++ b/core/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java @@ -18,15 +18,19 @@ */ package org.elasticsearch.snapshots; +import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.Version; import org.elasticsearch.action.ShardOperationFailedException; +import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Streamable; +import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.joda.FormatDateTimeFormatter; import org.elasticsearch.common.joda.Joda; +import org.elasticsearch.common.xcontent.FromXContentBuilder; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.rest.RestStatus; import java.io.IOException; @@ -35,52 +39,109 @@ import java.util.Collections; import java.util.List; /** - * Information about snapshot + * Information about a snapshot */ -public class SnapshotInfo implements ToXContent, Streamable { +public final class SnapshotInfo implements Comparable, ToXContent, FromXContentBuilder, Writeable { + public static final SnapshotInfo PROTO = new SnapshotInfo("", Collections.emptyList(), 0); private static final FormatDateTimeFormatter DATE_TIME_FORMATTER = Joda.forPattern("strictDateOptionalTime"); + private static final String SNAPSHOT = "snapshot"; + private static final String INDICES = "indices"; + private static final String STATE = "state"; + private static final String REASON = "reason"; + private static final String START_TIME = "start_time"; + private static final String START_TIME_IN_MILLIS = "start_time_in_millis"; + private static final String END_TIME = "end_time"; + private static final String END_TIME_IN_MILLIS = "end_time_in_millis"; + private static final String DURATION = "duration"; + private static final String DURATION_IN_MILLIS = "duration_in_millis"; + private static final String FAILURES = "failures"; + private static final String SHARDS = "shards"; + private static final String TOTAL = "total"; + private static final String FAILED = "failed"; + private static final String SUCCESSFUL = "successful"; + private static final String VERSION_ID = "version_id"; + private static final String VERSION = "version"; + private static final String NAME = "name"; + private static final String TOTAL_SHARDS = "total_shards"; + private static final String SUCCESSFUL_SHARDS = "successful_shards"; - private String name; + private final String name; - private SnapshotState state; + private final SnapshotState state; - private String reason; + private final String reason; - private List indices; + private final List indices; - private long startTime; + private final long startTime; - private long endTime; + private final long endTime; - private int totalShards; + private final int totalShards; - private int successfulShards; + private final int successfulShards; - private Version version; + private final Version version; - private List shardFailures; + private final List shardFailures; - SnapshotInfo() { + public SnapshotInfo(String name, List indices, long startTime) { + this(name, indices, SnapshotState.IN_PROGRESS, null, Version.CURRENT, startTime, 0L, 0, 0, Collections.emptyList()); + } + public SnapshotInfo(String name, List indices, long startTime, String reason, long endTime, + int totalShards, List shardFailures) { + this(name, indices, snapshotState(reason, shardFailures), reason, Version.CURRENT, + startTime, endTime, totalShards, totalShards - shardFailures.size(), shardFailures); + } + + private SnapshotInfo(String name, List indices, SnapshotState state, String reason, Version version, long startTime, + long endTime, int totalShards, int successfulShards, List shardFailures) { + assert name != null; + assert indices != null; + assert state != null; + assert shardFailures != null; + this.name = name; + this.indices = indices; + this.state = state; + this.reason = reason; + this.version = version; + this.startTime = startTime; + this.endTime = endTime; + this.totalShards = totalShards; + this.successfulShards = successfulShards; + this.shardFailures = shardFailures; } /** - * Creates a new snapshot information from a {@link Snapshot} - * - * @param snapshot snapshot information returned by repository + * Constructs snapshot information from stream input */ - public SnapshotInfo(Snapshot snapshot) { - name = snapshot.name(); - state = snapshot.state(); - reason = snapshot.reason(); - indices = snapshot.indices(); - startTime = snapshot.startTime(); - endTime = snapshot.endTime(); - totalShards = snapshot.totalShard(); - successfulShards = snapshot.successfulShards(); - shardFailures = snapshot.shardFailures(); - version = snapshot.version(); + public SnapshotInfo(final StreamInput in) throws IOException { + name = in.readString(); + int size = in.readVInt(); + List indicesListBuilder = new ArrayList<>(); + for (int i = 0; i < size; i++) { + indicesListBuilder.add(in.readString()); + } + indices = Collections.unmodifiableList(indicesListBuilder); + state = SnapshotState.fromValue(in.readByte()); + reason = in.readOptionalString(); + startTime = in.readVLong(); + endTime = in.readVLong(); + totalShards = in.readVInt(); + successfulShards = in.readVInt(); + size = in.readVInt(); + if (size > 0) { + List failureBuilder = new ArrayList<>(); + for (int i = 0; i < size; i++) { + failureBuilder.add(SnapshotShardFailure.readSnapshotShardFailure(in)); + } + shardFailures = Collections.unmodifiableList(failureBuilder); + } else { + shardFailures = Collections.emptyList(); + } + version = Version.readVersion(in); } /** @@ -184,6 +245,39 @@ public class SnapshotInfo implements ToXContent, Streamable { return version; } + /** + * Compares two snapshots by their start time + * + * @param o other snapshot + * @return the value {@code 0} if snapshots were created at the same time; + * a value less than {@code 0} if this snapshot was created before snapshot {@code o}; and + * a value greater than {@code 0} if this snapshot was created after snapshot {@code o}; + */ + @Override + public int compareTo(final SnapshotInfo o) { + return Long.compare(startTime, o.startTime); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final SnapshotInfo that = (SnapshotInfo) o; + return startTime == that.startTime && name.equals(that.name); + } + + @Override + public int hashCode() { + int result = name.hashCode(); + result = 31 * result + Long.hashCode(startTime); + return result; + } + /** * Returns snapshot REST status */ @@ -194,98 +288,166 @@ public class SnapshotInfo implements ToXContent, Streamable { if (shardFailures.size() == 0) { return RestStatus.OK; } - return RestStatus.status(successfulShards, totalShards, shardFailures.toArray(new ShardOperationFailedException[shardFailures.size()])); - } - - static final class Fields { - static final String INDICES = "indices"; - static final String STATE = "state"; - static final String REASON = "reason"; - static final String START_TIME = "start_time"; - static final String START_TIME_IN_MILLIS = "start_time_in_millis"; - static final String END_TIME = "end_time"; - static final String END_TIME_IN_MILLIS = "end_time_in_millis"; - static final String DURATION = "duration"; - static final String DURATION_IN_MILLIS = "duration_in_millis"; - static final String FAILURES = "failures"; - static final String SHARDS = "shards"; - static final String TOTAL = "total"; - static final String FAILED = "failed"; - static final String SUCCESSFUL = "successful"; - static final String VERSION_ID = "version_id"; - static final String VERSION = "version"; + return RestStatus.status(successfulShards, totalShards, + shardFailures.toArray(new ShardOperationFailedException[shardFailures.size()])); } @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject(); - builder.field("snapshot", name); - builder.field(Fields.VERSION_ID, version.id); - builder.field(Fields.VERSION, version.toString()); - builder.startArray(Fields.INDICES); + public XContentBuilder toXContent(final XContentBuilder builder, final Params params) throws IOException { + builder.startObject(SNAPSHOT); + builder.field(NAME, name); + builder.field(VERSION_ID, version.id); + builder.startArray(INDICES); for (String index : indices) { builder.value(index); } builder.endArray(); - builder.field(Fields.STATE, state); + builder.field(STATE, state); if (reason != null) { - builder.field(Fields.REASON, reason); + builder.field(REASON, reason); } - if (startTime != 0) { - builder.field(Fields.START_TIME, DATE_TIME_FORMATTER.printer().print(startTime)); - builder.field(Fields.START_TIME_IN_MILLIS, startTime); - } - if (endTime != 0) { - builder.field(Fields.END_TIME, DATE_TIME_FORMATTER.printer().print(endTime)); - builder.field(Fields.END_TIME_IN_MILLIS, endTime); - builder.timeValueField(Fields.DURATION_IN_MILLIS, Fields.DURATION, endTime - startTime); - } - builder.startArray(Fields.FAILURES); + builder.field(START_TIME, startTime); + builder.field(END_TIME, endTime); + builder.field(TOTAL_SHARDS, totalShards); + builder.field(SUCCESSFUL_SHARDS, successfulShards); + builder.startArray(FAILURES); for (SnapshotShardFailure shardFailure : shardFailures) { builder.startObject(); shardFailure.toXContent(builder, params); builder.endObject(); } builder.endArray(); - builder.startObject(Fields.SHARDS); - builder.field(Fields.TOTAL, totalShards); - builder.field(Fields.FAILED, failedShards()); - builder.field(Fields.SUCCESSFUL, successfulShards); + builder.endObject(); + return builder; + } + + /** + * Produces the external X-content that is delivered through the REST layer. + */ + public XContentBuilder toExternalXContent(final XContentBuilder builder, final ToXContent.Params params) throws IOException { + builder.startObject(); + builder.field(SNAPSHOT, name); + builder.field(VERSION_ID, version.id); + builder.field(VERSION, version.toString()); + builder.startArray(INDICES); + for (String index : indices) { + builder.value(index); + } + builder.endArray(); + builder.field(STATE, state); + if (reason != null) { + builder.field(REASON, reason); + } + if (startTime != 0) { + builder.field(START_TIME, DATE_TIME_FORMATTER.printer().print(startTime)); + builder.field(START_TIME_IN_MILLIS, startTime); + } + if (endTime != 0) { + builder.field(END_TIME, DATE_TIME_FORMATTER.printer().print(endTime)); + builder.field(END_TIME_IN_MILLIS, endTime); + builder.timeValueField(DURATION_IN_MILLIS, DURATION, endTime - startTime); + } + builder.startArray(FAILURES); + for (SnapshotShardFailure shardFailure : shardFailures) { + builder.startObject(); + shardFailure.toXContent(builder, params); + builder.endObject(); + } + builder.endArray(); + builder.startObject(SHARDS); + builder.field(TOTAL, totalShards); + builder.field(FAILED, failedShards()); + builder.field(SUCCESSFUL, successfulShards); builder.endObject(); builder.endObject(); return builder; } @Override - public void readFrom(StreamInput in) throws IOException { - name = in.readString(); - int size = in.readVInt(); - List indicesListBuilder = new ArrayList<>(); - for (int i = 0; i < size; i++) { - indicesListBuilder.add(in.readString()); + public SnapshotInfo fromXContent(final XContentParser parser, final ParseFieldMatcher matcher) throws IOException { + return fromXContent(parser); + } + + /** + * This method creates a SnapshotInfo from internal x-content. It does not + * handle x-content written with the external version as external x-content + * is only for display purposes and does not need to be parsed. + */ + public static SnapshotInfo fromXContent(final XContentParser parser) throws IOException { + String name = null; + Version version = Version.CURRENT; + SnapshotState state = SnapshotState.IN_PROGRESS; + String reason = null; + List indices = Collections.emptyList(); + long startTime = 0; + long endTime = 0; + int totalShard = 0; + int successfulShards = 0; + List shardFailures = Collections.emptyList(); + if (parser.currentToken() == null) { // fresh parser? move to the first token + parser.nextToken(); } - indices = Collections.unmodifiableList(indicesListBuilder); - state = SnapshotState.fromValue(in.readByte()); - reason = in.readOptionalString(); - startTime = in.readVLong(); - endTime = in.readVLong(); - totalShards = in.readVInt(); - successfulShards = in.readVInt(); - size = in.readVInt(); - if (size > 0) { - List failureBuilder = new ArrayList<>(); - for (int i = 0; i < size; i++) { - failureBuilder.add(SnapshotShardFailure.readSnapshotShardFailure(in)); + if (parser.currentToken() == XContentParser.Token.START_OBJECT) { // on a start object move to next token + parser.nextToken(); + } + XContentParser.Token token; + if ((token = parser.nextToken()) == XContentParser.Token.START_OBJECT) { + String currentFieldName = parser.currentName(); + if (SNAPSHOT.equals(currentFieldName)) { + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + token = parser.nextToken(); + if (token.isValue()) { + if (NAME.equals(currentFieldName)) { + name = parser.text(); + } else if (STATE.equals(currentFieldName)) { + state = SnapshotState.valueOf(parser.text()); + } else if (REASON.equals(currentFieldName)) { + reason = parser.text(); + } else if (START_TIME.equals(currentFieldName)) { + startTime = parser.longValue(); + } else if (END_TIME.equals(currentFieldName)) { + endTime = parser.longValue(); + } else if (TOTAL_SHARDS.equals(currentFieldName)) { + totalShard = parser.intValue(); + } else if (SUCCESSFUL_SHARDS.equals(currentFieldName)) { + successfulShards = parser.intValue(); + } else if (VERSION_ID.equals(currentFieldName)) { + version = Version.fromId(parser.intValue()); + } + } else if (token == XContentParser.Token.START_ARRAY) { + if (INDICES.equals(currentFieldName)) { + ArrayList indicesArray = new ArrayList<>(); + while (parser.nextToken() != XContentParser.Token.END_ARRAY) { + indicesArray.add(parser.text()); + } + indices = Collections.unmodifiableList(indicesArray); + } else if (FAILURES.equals(currentFieldName)) { + ArrayList shardFailureArrayList = new ArrayList<>(); + while (parser.nextToken() != XContentParser.Token.END_ARRAY) { + shardFailureArrayList.add(SnapshotShardFailure.fromXContent(parser)); + } + shardFailures = Collections.unmodifiableList(shardFailureArrayList); + } else { + // It was probably created by newer version - ignoring + parser.skipChildren(); + } + } else if (token == XContentParser.Token.START_OBJECT) { + // It was probably created by newer version - ignoring + parser.skipChildren(); + } + } + } } - shardFailures = Collections.unmodifiableList(failureBuilder); } else { - shardFailures = Collections.emptyList(); + throw new ElasticsearchParseException("unexpected token [" + token + "]"); } - version = Version.readVersion(in); + return new SnapshotInfo(name, indices, state, reason, version, startTime, endTime, totalShard, successfulShards, shardFailures); } @Override - public void writeTo(StreamOutput out) throws IOException { + public void writeTo(final StreamOutput out) throws IOException { out.writeString(name); out.writeVInt(indices.size()); for (String index : indices) { @@ -304,26 +466,16 @@ public class SnapshotInfo implements ToXContent, Streamable { Version.writeVersion(version, out); } - /** - * Reads snapshot information from stream input - * - * @param in stream input - * @return deserialized snapshot info - */ - public static SnapshotInfo readSnapshotInfo(StreamInput in) throws IOException { - SnapshotInfo snapshotInfo = new SnapshotInfo(); - snapshotInfo.readFrom(in); - return snapshotInfo; - } - - /** - * Reads optional snapshot information from stream input - * - * @param in stream input - * @return deserialized snapshot info or null - */ - public static SnapshotInfo readOptionalSnapshotInfo(StreamInput in) throws IOException { - return in.readOptionalStreamable(SnapshotInfo::new); + private static SnapshotState snapshotState(final String reason, final List shardFailures) { + if (reason == null) { + if (shardFailures.isEmpty()) { + return SnapshotState.SUCCESS; + } else { + return SnapshotState.PARTIAL; + } + } else { + return SnapshotState.FAILED; + } } } diff --git a/core/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java b/core/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java index 186a1965a96..8e6681893c9 100644 --- a/core/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java +++ b/core/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java @@ -126,7 +126,7 @@ public class SnapshotsService extends AbstractLifecycleComponent entries = currentSnapshots(snapshotId.getRepository(), new String[]{snapshotId.getSnapshot()}); if (!entries.isEmpty()) { @@ -141,8 +141,8 @@ public class SnapshotsService extends AbstractLifecycleComponent snapshots(String repositoryName, boolean ignoreUnavailable) { - Set snapshotSet = new HashSet<>(); + public List snapshots(String repositoryName, boolean ignoreUnavailable) { + Set snapshotSet = new HashSet<>(); List entries = currentSnapshots(repositoryName, null); for (SnapshotsInProgress.Entry entry : entries) { snapshotSet.add(inProgressSnapshot(entry)); @@ -161,7 +161,7 @@ public class SnapshotsService extends AbstractLifecycleComponent snapshotList = new ArrayList<>(snapshotSet); + ArrayList snapshotList = new ArrayList<>(snapshotSet); CollectionUtil.timSort(snapshotList); return Collections.unmodifiableList(snapshotList); } @@ -172,8 +172,8 @@ public class SnapshotsService extends AbstractLifecycleComponent currentSnapshots(String repositoryName) { - List snapshotList = new ArrayList<>(); + public List currentSnapshots(String repositoryName) { + List snapshotList = new ArrayList<>(); List entries = currentSnapshots(repositoryName, null); for (SnapshotsInProgress.Entry entry : entries) { snapshotList.add(inProgressSnapshot(entry)); @@ -408,8 +408,8 @@ public class SnapshotsService extends AbstractLifecycleComponent shardStatus = new HashMap<>(); Repository repository = repositoriesService.repository(snapshotId.getRepository()); IndexShardRepository indexShardRepository = repositoriesService.indexShardRepository(snapshotId.getRepository()); - Snapshot snapshot = repository.readSnapshot(snapshotId); + SnapshotInfo snapshot = repository.readSnapshot(snapshotId); MetaData metaData = repository.readSnapshotMetaData(snapshotId, snapshot, snapshot.indices()); for (String index : snapshot.indices()) { IndexMetaData indexMetaData = metaData.indices().get(index); @@ -800,8 +800,8 @@ public class SnapshotsService extends AbstractLifecycleComponent nodesMap = nodeHotThreads.getNodesMap(); assertThat(nodesMap.size(), equalTo(cluster().size())); - for (NodeHotThreads ht : nodeHotThreads) { + for (NodeHotThreads ht : nodeHotThreads.getNodes()) { assertNotNull(ht.getHotThreads()); //logger.info(ht.getHotThreads()); } diff --git a/core/src/test/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainIT.java b/core/src/test/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainIT.java index 8168d1a8819..628e26bc4cf 100644 --- a/core/src/test/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainIT.java +++ b/core/src/test/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainIT.java @@ -28,7 +28,6 @@ import org.elasticsearch.cluster.routing.UnassignedInfo; import org.elasticsearch.cluster.routing.allocation.decider.Decision; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.test.ESIntegTestCase; -import org.elasticsearch.test.ESSingleNodeTestCase; import java.util.HashMap; import java.util.List; @@ -37,7 +36,6 @@ import java.util.Map; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.greaterThanOrEqualTo; /** * Tests for the cluster allocation explanation @@ -54,7 +52,7 @@ public final class ClusterAllocationExplainIT extends ESIntegTestCase { @Override public void run() { NodesStatsResponse resp = client().admin().cluster().prepareNodesStats().get(); - assertThat(resp.getNodes().length, equalTo(3)); + assertThat(resp.getNodes().size(), equalTo(3)); } }); diff --git a/core/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/CancellableTasksTests.java b/core/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/CancellableTasksTests.java index d96531b2f6c..9af2bb07417 100644 --- a/core/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/CancellableTasksTests.java +++ b/core/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/CancellableTasksTests.java @@ -255,12 +255,12 @@ public class CancellableTasksTests extends TaskManagerTestCase { // Make sure that the request was successful assertNull(throwableReference.get()); assertNotNull(responseReference.get()); - assertEquals(nodesCount, responseReference.get().getNodes().length); + assertEquals(nodesCount, responseReference.get().getNodes().size()); assertEquals(0, responseReference.get().failureCount()); } else { // We canceled the request, in this case it should have fail, but we should get partial response assertNull(throwableReference.get()); - assertEquals(nodesCount, responseReference.get().failureCount() + responseReference.get().getNodes().length); + assertEquals(nodesCount, responseReference.get().failureCount() + responseReference.get().getNodes().size()); // and we should have at least as many failures as the number of blocked operations // (we might have cancelled some non-blocked operations before they even started and that's ok) assertThat(responseReference.get().failureCount(), greaterThanOrEqualTo(blockedNodesCount)); diff --git a/core/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TaskManagerTestCase.java b/core/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TaskManagerTestCase.java index 9c0e2bfcafd..ffc19aa0dcd 100644 --- a/core/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TaskManagerTestCase.java +++ b/core/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TaskManagerTestCase.java @@ -50,11 +50,9 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import java.io.IOException; -import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.function.Supplier; import static java.util.Collections.emptyMap; @@ -88,7 +86,6 @@ public abstract class TaskManagerTestCase extends ESTestCase { testNodes = new TestNode[nodesCount]; for (int i = 0; i < testNodes.length; i++) { testNodes[i] = new TestNode("node" + i, threadPool, settings); - ; } } @@ -113,27 +110,22 @@ public abstract class TaskManagerTestCase extends ESTestCase { static class NodesResponse extends BaseNodesResponse { - private int failureCount; - - protected NodesResponse(ClusterName clusterName, NodeResponse[] nodes, int failureCount) { - super(clusterName, nodes); - this.failureCount = failureCount; + protected NodesResponse(ClusterName clusterName, List nodes, List failures) { + super(clusterName, nodes, failures); } @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - failureCount = in.readVInt(); + protected List readNodesFrom(StreamInput in) throws IOException { + return in.readStreamableList(NodeResponse::new); } @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeVInt(failureCount); + protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { + out.writeStreamableList(nodes); } public int failureCount() { - return failureCount; + return failures().size(); } } @@ -148,24 +140,12 @@ public abstract class TaskManagerTestCase extends ESTestCase { Supplier nodeRequest) { super(settings, actionName, clusterName, threadPool, clusterService, transportService, new ActionFilters(new HashSet<>()), new IndexNameExpressionResolver(Settings.EMPTY), - request, nodeRequest, ThreadPool.Names.GENERIC); + request, nodeRequest, ThreadPool.Names.GENERIC, NodeResponse.class); } @Override - protected NodesResponse newResponse(NodesRequest request, AtomicReferenceArray responses) { - final List nodesList = new ArrayList<>(); - int failureCount = 0; - for (int i = 0; i < responses.length(); i++) { - Object resp = responses.get(i); - if (resp instanceof NodeResponse) { // will also filter out null response for unallocated ones - nodesList.add((NodeResponse) resp); - } else if (resp instanceof FailedNodeException) { - failureCount++; - } else { - logger.warn("unknown response type [{}], expected NodeLocalGatewayMetaState or FailedNodeException", resp); - } - } - return new NodesResponse(clusterName, nodesList.toArray(new NodeResponse[nodesList.size()]), failureCount); + protected NodesResponse newResponse(NodesRequest request, List responses, List failures) { + return new NodesResponse(clusterName, responses, failures); } @Override diff --git a/core/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TestTaskPlugin.java b/core/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TestTaskPlugin.java index 7f1d6c8b835..ec05ff9c984 100644 --- a/core/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TestTaskPlugin.java +++ b/core/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TestTaskPlugin.java @@ -56,7 +56,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.concurrent.atomic.AtomicReferenceArray; import static org.elasticsearch.test.ESTestCase.awaitBusy; @@ -111,31 +110,26 @@ public class TestTaskPlugin extends Plugin { public static class NodesResponse extends BaseNodesResponse { - private int failureCount; - NodesResponse() { } - public NodesResponse(ClusterName clusterName, NodeResponse[] nodes, int failureCount) { - super(clusterName, nodes); - this.failureCount = failureCount; + public NodesResponse(ClusterName clusterName, List nodes, List failures) { + super(clusterName, nodes, failures); } @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - failureCount = in.readVInt(); + protected List readNodesFrom(StreamInput in) throws IOException { + return in.readStreamableList(NodeResponse::new); } @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeVInt(failureCount); + protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { + out.writeStreamableList(nodes); } public int failureCount() { - return failureCount; + return failures().size(); } } @@ -219,25 +213,13 @@ public class TestTaskPlugin extends Plugin { public TransportTestTaskAction(Settings settings, ClusterName clusterName, ThreadPool threadPool, ClusterService clusterService, TransportService transportService) { super(settings, TestTaskAction.NAME, clusterName, threadPool, clusterService, transportService, - new ActionFilters(new HashSet<>()), new IndexNameExpressionResolver(Settings.EMPTY), - NodesRequest::new, NodeRequest::new, ThreadPool.Names.GENERIC); + new ActionFilters(new HashSet<>()), new IndexNameExpressionResolver(Settings.EMPTY), + NodesRequest::new, NodeRequest::new, ThreadPool.Names.GENERIC, NodeResponse.class); } @Override - protected NodesResponse newResponse(NodesRequest request, AtomicReferenceArray responses) { - final List nodesList = new ArrayList<>(); - int failureCount = 0; - for (int i = 0; i < responses.length(); i++) { - Object resp = responses.get(i); - if (resp instanceof NodeResponse) { // will also filter out null response for unallocated ones - nodesList.add((NodeResponse) resp); - } else if (resp instanceof FailedNodeException) { - failureCount++; - } else { - logger.warn("unknown response type [{}], expected NodeLocalGatewayMetaState or FailedNodeException", resp); - } - } - return new NodesResponse(clusterName, nodesList.toArray(new NodeResponse[nodesList.size()]), failureCount); + protected NodesResponse newResponse(NodesRequest request, List responses, List failures) { + return new NodesResponse(clusterName, responses, failures); } @Override diff --git a/core/src/test/java/org/elasticsearch/action/support/nodes/TransportNodesActionTests.java b/core/src/test/java/org/elasticsearch/action/support/nodes/TransportNodesActionTests.java index 6a7f7ac3398..a3335d87fd6 100644 --- a/core/src/test/java/org/elasticsearch/action/support/nodes/TransportNodesActionTests.java +++ b/core/src/test/java/org/elasticsearch/action/support/nodes/TransportNodesActionTests.java @@ -20,6 +20,7 @@ package org.elasticsearch.action.support.nodes; import org.elasticsearch.Version; +import org.elasticsearch.action.FailedNodeException; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.action.support.broadcast.node.TransportBroadcastByNodeActionTests; @@ -28,6 +29,8 @@ import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.node.DiscoveryNodes; import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.DummyTransportAddress; import org.elasticsearch.test.ESTestCase; @@ -39,6 +42,7 @@ import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -53,6 +57,7 @@ import java.util.function.Supplier; import static org.elasticsearch.cluster.service.ClusterServiceUtils.createClusterService; import static org.elasticsearch.cluster.service.ClusterServiceUtils.setState; +import static org.mockito.Mockito.mock; public class TransportNodesActionTests extends ESTestCase { @@ -92,6 +97,42 @@ public class TransportNodesActionTests extends ESTestCase { assertEquals(clusterService.state().nodes().resolveNodesIds(finalNodesIds).length, capturedRequests.size()); } + public void testNewResponseNullArray() { + expectThrows(NullPointerException.class, () -> action.newResponse(new TestNodesRequest(), null)); + } + + public void testNewResponse() { + TestNodesRequest request = new TestNodesRequest(); + List expectedNodeResponses = mockList(TestNodeResponse.class, randomIntBetween(0, 2)); + expectedNodeResponses.add(new TestNodeResponse()); + List nodeResponses = new ArrayList<>(expectedNodeResponses); + // This should be ignored: + nodeResponses.add(new OtherNodeResponse()); + List failures = mockList(FailedNodeException.class, randomIntBetween(0, 2)); + + List allResponses = new ArrayList<>(expectedNodeResponses); + allResponses.addAll(failures); + + Collections.shuffle(allResponses, random()); + + AtomicReferenceArray atomicArray = new AtomicReferenceArray<>(allResponses.toArray()); + + TestNodesResponse response = action.newResponse(request, atomicArray); + + assertSame(request, response.request); + // note: I shuffled the overall list, so it's not possible to guarantee that it's in the right order + assertTrue(expectedNodeResponses.containsAll(response.getNodes())); + assertTrue(failures.containsAll(response.failures())); + } + + private List mockList(Class clazz, int size) { + List failures = new ArrayList<>(size); + for (int i = 0; i < size; ++i) { + failures.add(mock(clazz)); + } + return failures; + } + private enum NodeSelector { LOCAL("_local"), ELECTED_MASTER("_master"), MASTER_ELIGIBLE("master:true"), DATA("data:true"), CUSTOM_ATTRIBUTE("attr:value"); @@ -165,26 +206,20 @@ public class TransportNodesActionTests extends ESTestCase { return new DiscoveryNode(node, node, DummyTransportAddress.INSTANCE, attributes, roles, Version.CURRENT); } - private static class TestTransportNodesAction extends TransportNodesAction { + private static class TestTransportNodesAction + extends TransportNodesAction { TestTransportNodesAction(Settings settings, ThreadPool threadPool, ClusterService clusterService, TransportService transportService, ActionFilters actionFilters, Supplier request, Supplier nodeRequest, String nodeExecutor) { super(settings, "indices:admin/test", CLUSTER_NAME, threadPool, clusterService, transportService, actionFilters, - null, request, nodeRequest, nodeExecutor); + null, request, nodeRequest, nodeExecutor, TestNodeResponse.class); } @Override - protected TestNodesResponse newResponse(TestNodesRequest request, AtomicReferenceArray nodesResponses) { - final List nodeResponses = new ArrayList<>(); - for (int i = 0; i < nodesResponses.length(); i++) { - Object resp = nodesResponses.get(i); - if (resp instanceof TestNodeResponse) { - nodeResponses.add((TestNodeResponse) resp); - } - } - return new TestNodesResponse(nodeResponses); + protected TestNodesResponse newResponse(TestNodesRequest request, + List responses, List failures) { + return new TestNodesResponse(request, responses, failures); } @Override @@ -216,16 +251,28 @@ public class TransportNodesActionTests extends ESTestCase { private static class TestNodesResponse extends BaseNodesResponse { - private final List nodeResponses; + private final TestNodesRequest request; - TestNodesResponse(List nodeResponses) { - this.nodeResponses = nodeResponses; + TestNodesResponse(TestNodesRequest request, List nodeResponses, List failures) { + super(CLUSTER_NAME, nodeResponses, failures); + this.request = request; + } + + @Override + protected List readNodesFrom(StreamInput in) throws IOException { + return in.readStreamableList(TestNodeResponse::new); + } + + @Override + protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { + out.writeStreamableList(nodes); } } - private static class TestNodeRequest extends BaseNodeRequest { - } + private static class TestNodeRequest extends BaseNodeRequest { } + + private static class TestNodeResponse extends BaseNodeResponse { } + + private static class OtherNodeResponse extends BaseNodeResponse { } - private static class TestNodeResponse extends BaseNodeResponse { - } } diff --git a/core/src/test/java/org/elasticsearch/bwcompat/ClusterStateBackwardsCompatIT.java b/core/src/test/java/org/elasticsearch/bwcompat/ClusterStateBackwardsCompatIT.java index 81d894e3349..a4427befea2 100644 --- a/core/src/test/java/org/elasticsearch/bwcompat/ClusterStateBackwardsCompatIT.java +++ b/core/src/test/java/org/elasticsearch/bwcompat/ClusterStateBackwardsCompatIT.java @@ -44,7 +44,7 @@ public class ClusterStateBackwardsCompatIT extends ESBackcompatTestCase { createIndex("test"); // connect to each node with a custom TransportClient, issue a ClusterStateRequest to test serialization - for (NodeInfo n : clusterNodes()) { + for (NodeInfo n : clusterNodes().getNodes()) { try (TransportClient tc = newTransportClient()) { tc.addTransportAddress(n.getNode().getAddress()); ClusterStateResponse response = tc.admin().cluster().prepareState().execute().actionGet(); @@ -68,7 +68,7 @@ public class ClusterStateBackwardsCompatIT extends ESBackcompatTestCase { try { enableIndexBlock("test-blocks", block.getKey()); - for (NodeInfo n : clusterNodes()) { + for (NodeInfo n : clusterNodes().getNodes()) { try (TransportClient tc = newTransportClient()) { tc.addTransportAddress(n.getNode().getAddress()); diff --git a/core/src/test/java/org/elasticsearch/client/transport/FailAndRetryMockTransport.java b/core/src/test/java/org/elasticsearch/client/transport/FailAndRetryMockTransport.java index 0aaec63fef0..50fbbd4fcb8 100644 --- a/core/src/test/java/org/elasticsearch/client/transport/FailAndRetryMockTransport.java +++ b/core/src/test/java/org/elasticsearch/client/transport/FailAndRetryMockTransport.java @@ -74,11 +74,7 @@ abstract class FailAndRetryMockTransport imp //we make sure that nodes get added to the connected ones when calling addTransportAddress, by returning proper nodes info if (connectMode) { TransportResponseHandler transportResponseHandler = transportServiceAdapter.onResponseReceived(requestId); - if (action.equals(TransportLivenessAction.NAME)) { - transportResponseHandler.handleResponse(new LivenessResponse(clusterName, node)); - } else { - transportResponseHandler.handleResponse(new TransportService.HandshakeResponse(node, clusterName, Version.CURRENT)); - } + transportResponseHandler.handleResponse(new LivenessResponse(ClusterName.DEFAULT, node)); return; } diff --git a/core/src/test/java/org/elasticsearch/cluster/DiskUsageTests.java b/core/src/test/java/org/elasticsearch/cluster/DiskUsageTests.java index 1826ced24ea..31c9c21b8e7 100644 --- a/core/src/test/java/org/elasticsearch/cluster/DiskUsageTests.java +++ b/core/src/test/java/org/elasticsearch/cluster/DiskUsageTests.java @@ -41,6 +41,8 @@ import org.elasticsearch.monitor.fs.FsInfo; import org.elasticsearch.test.ESTestCase; import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; import static java.util.Collections.emptyMap; import static java.util.Collections.emptySet; @@ -196,14 +198,14 @@ public class DiskUsageTests extends ESTestCase { new FsInfo.Path("/least", "/dev/sda", 100, 90, 70), new FsInfo.Path("/most", "/dev/sda", 100, 90, 80), }; - NodeStats[] nodeStats = new NodeStats[] { + List nodeStats = Arrays.asList( new NodeStats(new DiscoveryNode("node_1", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT), 0, null,null,null,null,null,new FsInfo(0, node1FSInfo), null,null,null,null,null, null), new NodeStats(new DiscoveryNode("node_2", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT), 0, null,null,null,null,null, new FsInfo(0, node2FSInfo), null,null,null,null,null, null), new NodeStats(new DiscoveryNode("node_3", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT), 0, null,null,null,null,null, new FsInfo(0, node3FSInfo), null,null,null,null,null, null) - }; + ); InternalClusterInfoService.fillDiskUsagePerNode(logger, nodeStats, newLeastAvaiableUsages, newMostAvaiableUsages); DiskUsage leastNode_1 = newLeastAvaiableUsages.get("node_1"); DiskUsage mostNode_1 = newMostAvaiableUsages.get("node_1"); @@ -237,14 +239,14 @@ public class DiskUsageTests extends ESTestCase { new FsInfo.Path("/most", "/dev/sda", 100, 90, 70), new FsInfo.Path("/least", "/dev/sda", 10, -8, 0), }; - NodeStats[] nodeStats = new NodeStats[] { + List nodeStats = Arrays.asList( new NodeStats(new DiscoveryNode("node_1", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT), 0, null,null,null,null,null,new FsInfo(0, node1FSInfo), null,null,null,null,null, null), new NodeStats(new DiscoveryNode("node_2", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT), 0, null,null,null,null,null, new FsInfo(0, node2FSInfo), null,null,null,null,null, null), new NodeStats(new DiscoveryNode("node_3", DummyTransportAddress.INSTANCE, emptyMap(), emptySet(), Version.CURRENT), 0, null,null,null,null,null, new FsInfo(0, node3FSInfo), null,null,null,null,null, null) - }; + ); InternalClusterInfoService.fillDiskUsagePerNode(logger, nodeStats, newLeastAvailableUsages, newMostAvailableUsages); DiskUsage leastNode_1 = newLeastAvailableUsages.get("node_1"); DiskUsage mostNode_1 = newMostAvailableUsages.get("node_1"); diff --git a/core/src/test/java/org/elasticsearch/cluster/ack/AckClusterUpdateSettingsIT.java b/core/src/test/java/org/elasticsearch/cluster/ack/AckClusterUpdateSettingsIT.java index 8e2dea63d6a..8d13f04240e 100644 --- a/core/src/test/java/org/elasticsearch/cluster/ack/AckClusterUpdateSettingsIT.java +++ b/core/src/test/java/org/elasticsearch/cluster/ack/AckClusterUpdateSettingsIT.java @@ -81,7 +81,7 @@ public class AckClusterUpdateSettingsIT extends ESIntegTestCase { NodesInfoResponse nodesInfo = client().admin().cluster().prepareNodesInfo().get(); String excludedNodeId = null; - for (NodeInfo nodeInfo : nodesInfo) { + for (NodeInfo nodeInfo : nodesInfo.getNodes()) { if (nodeInfo.getNode().isDataNode()) { excludedNodeId = nodeInfo.getNode().getId(); break; @@ -124,7 +124,7 @@ public class AckClusterUpdateSettingsIT extends ESIntegTestCase { NodesInfoResponse nodesInfo = client().admin().cluster().prepareNodesInfo().get(); String excludedNodeId = null; - for (NodeInfo nodeInfo : nodesInfo) { + for (NodeInfo nodeInfo : nodesInfo.getNodes()) { if (nodeInfo.getNode().isDataNode()) { excludedNodeId = nodeInfo.getNode().getId(); break; diff --git a/core/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/MockDiskUsagesIT.java b/core/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/MockDiskUsagesIT.java index 81a28adee2d..ef54c6fd637 100644 --- a/core/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/MockDiskUsagesIT.java +++ b/core/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/MockDiskUsagesIT.java @@ -59,7 +59,7 @@ public class MockDiskUsagesIT extends ESIntegTestCase { @Override public void run() { NodesStatsResponse resp = client().admin().cluster().prepareNodesStats().get(); - assertThat(resp.getNodes().length, equalTo(3)); + assertThat(resp.getNodes().size(), equalTo(3)); } }); diff --git a/core/src/test/java/org/elasticsearch/common/geo/builders/AbstractShapeBuilderTestCase.java b/core/src/test/java/org/elasticsearch/common/geo/builders/AbstractShapeBuilderTestCase.java index 79b890ab401..9cbd4bb769d 100644 --- a/core/src/test/java/org/elasticsearch/common/geo/builders/AbstractShapeBuilderTestCase.java +++ b/core/src/test/java/org/elasticsearch/common/geo/builders/AbstractShapeBuilderTestCase.java @@ -34,8 +34,6 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import java.io.IOException; -import java.util.Collections; - import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.not; @@ -81,7 +79,7 @@ public abstract class AbstractShapeBuilderTestCase exte contentBuilder.prettyPrint(); } XContentBuilder builder = testShape.toXContent(contentBuilder, ToXContent.EMPTY_PARAMS); - XContentBuilder shuffled = shuffleXContent(builder, Collections.emptySet()); + XContentBuilder shuffled = shuffleXContent(builder); XContentParser shapeParser = XContentHelper.createParser(shuffled.bytes()); shapeParser.nextToken(); ShapeBuilder parsedShape = ShapeBuilder.parse(shapeParser); diff --git a/core/src/test/java/org/elasticsearch/common/io/stream/BytesStreamsTests.java b/core/src/test/java/org/elasticsearch/common/io/stream/BytesStreamsTests.java index 381120fdc0f..9fcbb708156 100644 --- a/core/src/test/java/org/elasticsearch/common/io/stream/BytesStreamsTests.java +++ b/core/src/test/java/org/elasticsearch/common/io/stream/BytesStreamsTests.java @@ -22,20 +22,20 @@ package org.elasticsearch.common.io.stream; import org.apache.lucene.util.Constants; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.geo.GeoPoint; -import org.elasticsearch.common.joda.FormatDateTimeFormatter; -import org.elasticsearch.common.joda.Joda; import org.elasticsearch.common.lucene.BytesRefs; import org.elasticsearch.common.util.BigArrays; -import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.test.ESTestCase; import org.joda.time.DateTimeZone; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import static org.hamcrest.Matchers.closeTo; import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.startsWith; @@ -431,6 +431,33 @@ public class BytesStreamsTests extends ESTestCase { endsWith(" claims to have a different name [intentionally-broken] than it was read from [test-named-writeable].")); } + public void testWriteStreamableList() throws IOException { + final int size = randomIntBetween(0, 5); + final List expected = new ArrayList<>(size); + + for (int i = 0; i < size; ++i) { + expected.add(new TestStreamable(randomBoolean())); + } + + final BytesStreamOutput out = new BytesStreamOutput(); + out.writeStreamableList(expected); + + final StreamInput in = StreamInput.wrap(out.bytes().toBytes()); + + List loaded = in.readStreamableList(TestStreamable::new); + + assertThat(loaded, hasSize(expected.size())); + + for (int i = 0; i < expected.size(); ++i) { + assertEquals(expected.get(i).value, loaded.get(i).value); + } + + assertEquals(0, in.available()); + + in.close(); + out.close(); + } + private static abstract class BaseNamedWriteable implements NamedWriteable { } @@ -544,4 +571,25 @@ public class BytesStreamsTests extends ESTestCase { assertEquals(point, geoPoint); } } + + private static class TestStreamable implements Streamable { + + private boolean value; + + public TestStreamable() { } + + public TestStreamable(boolean value) { + this.value = value; + } + + @Override + public void readFrom(StreamInput in) throws IOException { + value = in.readBoolean(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeBoolean(value); + } + } } diff --git a/core/src/test/java/org/elasticsearch/common/network/NetworkAddressTests.java b/core/src/test/java/org/elasticsearch/common/network/NetworkAddressTests.java index d62e6ac7dba..4f08eee9b77 100644 --- a/core/src/test/java/org/elasticsearch/common/network/NetworkAddressTests.java +++ b/core/src/test/java/org/elasticsearch/common/network/NetworkAddressTests.java @@ -100,4 +100,5 @@ public class NetworkAddressTests extends ESTestCase { byte bytes[] = InetAddress.getByName(address).getAddress(); return Inet6Address.getByAddress(hostname, bytes, scopeid); } + } diff --git a/core/src/test/java/org/elasticsearch/common/xcontent/ConstructingObjectParserTests.java b/core/src/test/java/org/elasticsearch/common/xcontent/ConstructingObjectParserTests.java index ff23a822832..e04fdab12aa 100644 --- a/core/src/test/java/org/elasticsearch/common/xcontent/ConstructingObjectParserTests.java +++ b/core/src/test/java/org/elasticsearch/common/xcontent/ConstructingObjectParserTests.java @@ -28,7 +28,6 @@ import org.elasticsearch.test.ESTestCase; import java.io.IOException; -import static java.util.Collections.emptySet; import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg; import static org.hamcrest.Matchers.instanceOf; @@ -48,7 +47,7 @@ public class ConstructingObjectParserTests extends ESTestCase { expected.setD(randomBoolean()); XContentBuilder builder = XContentFactory.jsonBuilder().prettyPrint(); expected.toXContent(builder, ToXContent.EMPTY_PARAMS); - builder = shuffleXContent(builder, emptySet()); + builder = shuffleXContent(builder); BytesReference bytes = builder.bytes(); XContentParser parser = XContentFactory.xContent(bytes).createParser(bytes); try { diff --git a/core/src/test/java/org/elasticsearch/discovery/zen/ZenDiscoveryIT.java b/core/src/test/java/org/elasticsearch/discovery/zen/ZenDiscoveryIT.java index 2de9d669511..d12a0ff55a3 100644 --- a/core/src/test/java/org/elasticsearch/discovery/zen/ZenDiscoveryIT.java +++ b/core/src/test/java/org/elasticsearch/discovery/zen/ZenDiscoveryIT.java @@ -349,9 +349,9 @@ public class ZenDiscoveryIT extends ESIntegTestCase { logger.info("--> request node discovery stats"); NodesStatsResponse statsResponse = client().admin().cluster().prepareNodesStats().clear().setDiscovery(true).get(); - assertThat(statsResponse.getNodes().length, equalTo(1)); + assertThat(statsResponse.getNodes().size(), equalTo(1)); - DiscoveryStats stats = statsResponse.getNodes()[0].getDiscoveryStats(); + DiscoveryStats stats = statsResponse.getNodes().get(0).getDiscoveryStats(); assertThat(stats.getQueueStats(), notNullValue()); assertThat(stats.getQueueStats().getTotal(), equalTo(0)); assertThat(stats.getQueueStats().getCommitted(), equalTo(0)); diff --git a/core/src/test/java/org/elasticsearch/gateway/AsyncShardFetchTests.java b/core/src/test/java/org/elasticsearch/gateway/AsyncShardFetchTests.java index 3ab15baf2e0..b710aa50ee0 100644 --- a/core/src/test/java/org/elasticsearch/gateway/AsyncShardFetchTests.java +++ b/core/src/test/java/org/elasticsearch/gateway/AsyncShardFetchTests.java @@ -284,10 +284,11 @@ public class AsyncShardFetchTests extends ESTestCase { assert entry != null; entry.executeLatch.await(); if (entry.failure != null) { - processAsyncFetch(shardId, null, new FailedNodeException[]{new FailedNodeException(nodeId, - "unexpected", entry.failure)}); + processAsyncFetch(shardId, null, Collections.singletonList(new FailedNodeException(nodeId, + "unexpected", + entry.failure))); } else { - processAsyncFetch(shardId, new Response[]{entry.response}, null); + processAsyncFetch(shardId, Collections.singletonList(entry.response), null); } } catch (Throwable e) { logger.error("unexpected failure", e); diff --git a/core/src/test/java/org/elasticsearch/gateway/RecoveryFromGatewayIT.java b/core/src/test/java/org/elasticsearch/gateway/RecoveryFromGatewayIT.java index 702e83e7d55..aaa29ad1970 100644 --- a/core/src/test/java/org/elasticsearch/gateway/RecoveryFromGatewayIT.java +++ b/core/src/test/java/org/elasticsearch/gateway/RecoveryFromGatewayIT.java @@ -63,9 +63,9 @@ import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; import static org.elasticsearch.index.query.QueryBuilders.termQuery; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; -import static org.hamcrest.Matchers.arrayWithSize; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; @@ -568,12 +568,12 @@ public class RecoveryFromGatewayIT extends ESIntegTestCase { .execute(new TransportNodesListGatewayStartedShards.Request(shardId, new String[]{node.getId()})) .get(); - assertThat(response.getNodes(), arrayWithSize(1)); - assertThat(response.getNodes()[0].allocationId(), notNullValue()); + assertThat(response.getNodes(), hasSize(1)); + assertThat(response.getNodes().get(0).allocationId(), notNullValue()); if (corrupt) { - assertThat(response.getNodes()[0].storeException(), notNullValue()); + assertThat(response.getNodes().get(0).storeException(), notNullValue()); } else { - assertThat(response.getNodes()[0].storeException(), nullValue()); + assertThat(response.getNodes().get(0).storeException(), nullValue()); } // start another node so cluster consistency checks won't time out due to the lack of state diff --git a/core/src/test/java/org/elasticsearch/index/mapper/core/DateFieldMapperTests.java b/core/src/test/java/org/elasticsearch/index/mapper/core/DateFieldMapperTests.java index 9f09e3e2e13..ee19d094a3f 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/core/DateFieldMapperTests.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/core/DateFieldMapperTests.java @@ -251,4 +251,55 @@ public class DateFieldMapperTests extends ESSingleNodeTestCase { .endObject() .bytes()); } + + public void testNullValue() throws IOException { + String mapping = XContentFactory.jsonBuilder().startObject() + .startObject("type") + .startObject("properties") + .startObject("field") + .field("type", "date") + .endObject() + .endObject() + .endObject().endObject().string(); + + DocumentMapper mapper = parser.parse("type", new CompressedXContent(mapping)); + assertEquals(mapping, mapper.mappingSource().toString()); + + ParsedDocument doc = mapper.parse("test", "type", "1", XContentFactory.jsonBuilder() + .startObject() + .nullField("field") + .endObject() + .bytes()); + assertArrayEquals(new IndexableField[0], doc.rootDoc().getFields("field")); + + mapping = XContentFactory.jsonBuilder().startObject() + .startObject("type") + .startObject("properties") + .startObject("field") + .field("type", "date") + .field("null_value", "2016-03-11") + .endObject() + .endObject() + .endObject().endObject().string(); + + mapper = parser.parse("type", new CompressedXContent(mapping)); + assertEquals(mapping, mapper.mappingSource().toString()); + + doc = mapper.parse("test", "type", "1", XContentFactory.jsonBuilder() + .startObject() + .nullField("field") + .endObject() + .bytes()); + IndexableField[] fields = doc.rootDoc().getFields("field"); + assertEquals(2, fields.length); + IndexableField pointField = fields[0]; + assertEquals(1, pointField.fieldType().pointDimensionCount()); + assertEquals(8, pointField.fieldType().pointNumBytes()); + assertFalse(pointField.fieldType().stored()); + assertEquals(1457654400000L, pointField.numericValue().longValue()); + IndexableField dvField = fields[1]; + assertEquals(DocValuesType.SORTED_NUMERIC, dvField.fieldType().docValuesType()); + assertEquals(1457654400000L, dvField.numericValue().longValue()); + assertFalse(dvField.fieldType().stored()); + } } diff --git a/core/src/test/java/org/elasticsearch/index/mapper/core/KeywordFieldMapperTests.java b/core/src/test/java/org/elasticsearch/index/mapper/core/KeywordFieldMapperTests.java index 28867ed1f73..8b9c9134fa3 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/core/KeywordFieldMapperTests.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/core/KeywordFieldMapperTests.java @@ -126,14 +126,28 @@ public class KeywordFieldMapperTests extends ESSingleNodeTestCase { public void testNullValue() throws IOException { String mapping = XContentFactory.jsonBuilder().startObject().startObject("type") - .startObject("properties").startObject("field").field("type", "keyword").field("null_value", "uri").endObject().endObject() + .startObject("properties").startObject("field").field("type", "keyword").endObject().endObject() .endObject().endObject().string(); DocumentMapper mapper = parser.parse("type", new CompressedXContent(mapping)); - assertEquals(mapping, mapper.mappingSource().toString()); ParsedDocument doc = mapper.parse("test", "type", "1", XContentFactory.jsonBuilder() + .startObject() + .nullField("field") + .endObject() + .bytes()); + assertArrayEquals(new IndexableField[0], doc.rootDoc().getFields("field")); + + mapping = XContentFactory.jsonBuilder().startObject().startObject("type") + .startObject("properties").startObject("field").field("type", "keyword").field("null_value", "uri").endObject().endObject() + .endObject().endObject().string(); + + mapper = parser.parse("type", new CompressedXContent(mapping)); + + assertEquals(mapping, mapper.mappingSource().toString()); + + doc = mapper.parse("test", "type", "1", XContentFactory.jsonBuilder() .startObject() .endObject() .bytes()); diff --git a/core/src/test/java/org/elasticsearch/index/mapper/core/NumberFieldMapperTests.java b/core/src/test/java/org/elasticsearch/index/mapper/core/NumberFieldMapperTests.java index 0f0f5a33213..45cc09fff0e 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/core/NumberFieldMapperTests.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/core/NumberFieldMapperTests.java @@ -316,4 +316,65 @@ public class NumberFieldMapperTests extends ESSingleNodeTestCase { assertThat(e.getMessage(), containsString("Mapping definition for [foo] has unsupported parameters: [norms")); } } + + public void testNullValue() throws IOException { + for (String type : TYPES) { + doTestNullValue(type); + } + } + + private void doTestNullValue(String type) throws IOException { + String mapping = XContentFactory.jsonBuilder().startObject() + .startObject("type") + .startObject("properties") + .startObject("field") + .field("type", type) + .endObject() + .endObject() + .endObject().endObject().string(); + + DocumentMapper mapper = parser.parse("type", new CompressedXContent(mapping)); + assertEquals(mapping, mapper.mappingSource().toString()); + + ParsedDocument doc = mapper.parse("test", "type", "1", XContentFactory.jsonBuilder() + .startObject() + .nullField("field") + .endObject() + .bytes()); + assertArrayEquals(new IndexableField[0], doc.rootDoc().getFields("field")); + + Object missing; + if (Arrays.asList("float", "double").contains(type)) { + missing = 123d; + } else { + missing = 123L; + } + mapping = XContentFactory.jsonBuilder().startObject() + .startObject("type") + .startObject("properties") + .startObject("field") + .field("type", type) + .field("null_value", missing) + .endObject() + .endObject() + .endObject().endObject().string(); + + mapper = parser.parse("type", new CompressedXContent(mapping)); + assertEquals(mapping, mapper.mappingSource().toString()); + + doc = mapper.parse("test", "type", "1", XContentFactory.jsonBuilder() + .startObject() + .nullField("field") + .endObject() + .bytes()); + IndexableField[] fields = doc.rootDoc().getFields("field"); + assertEquals(2, fields.length); + IndexableField pointField = fields[0]; + assertEquals(1, pointField.fieldType().pointDimensionCount()); + assertFalse(pointField.fieldType().stored()); + assertEquals(123, pointField.numericValue().doubleValue(), 0d); + IndexableField dvField = fields[1]; + assertEquals(DocValuesType.SORTED_NUMERIC, dvField.fieldType().docValuesType()); + assertFalse(dvField.fieldType().stored()); + } } diff --git a/core/src/test/java/org/elasticsearch/index/mapper/core/NumberFieldTypeTests.java b/core/src/test/java/org/elasticsearch/index/mapper/core/NumberFieldTypeTests.java index 25591591e42..22dec5bdde5 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/core/NumberFieldTypeTests.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/core/NumberFieldTypeTests.java @@ -75,4 +75,35 @@ public class NumberFieldTypeTests extends FieldTypeTestCase { () -> ft.rangeQuery("1", "3", true, true)); assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); } + + public void testConversions() { + assertEquals((byte) 3, NumberType.BYTE.parse(3d)); + assertEquals((short) 3, NumberType.SHORT.parse(3d)); + assertEquals(3, NumberType.INTEGER.parse(3d)); + assertEquals(3L, NumberType.LONG.parse(3d)); + assertEquals(3f, NumberType.FLOAT.parse(3d)); + assertEquals(3d, NumberType.DOUBLE.parse(3d)); + + IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> NumberType.BYTE.parse(3.5)); + assertEquals("Value [3.5] has a decimal part", e.getMessage()); + e = expectThrows(IllegalArgumentException.class, () -> NumberType.SHORT.parse(3.5)); + assertEquals("Value [3.5] has a decimal part", e.getMessage()); + e = expectThrows(IllegalArgumentException.class, () -> NumberType.INTEGER.parse(3.5)); + assertEquals("Value [3.5] has a decimal part", e.getMessage()); + e = expectThrows(IllegalArgumentException.class, () -> NumberType.LONG.parse(3.5)); + assertEquals("Value [3.5] has a decimal part", e.getMessage()); + assertEquals(3.5f, NumberType.FLOAT.parse(3.5)); + assertEquals(3.5d, NumberType.DOUBLE.parse(3.5)); + + e = expectThrows(IllegalArgumentException.class, () -> NumberType.BYTE.parse(128)); + assertEquals("Value [128] is out of range for a byte", e.getMessage()); + e = expectThrows(IllegalArgumentException.class, () -> NumberType.SHORT.parse(65536)); + assertEquals("Value [65536] is out of range for a short", e.getMessage()); + e = expectThrows(IllegalArgumentException.class, () -> NumberType.INTEGER.parse(2147483648L)); + assertEquals("Value [2147483648] is out of range for an integer", e.getMessage()); + e = expectThrows(IllegalArgumentException.class, () -> NumberType.LONG.parse(10000000000000000000d)); + assertEquals("Value [1.0E19] is out of range for a long", e.getMessage()); + assertEquals(1.1f, NumberType.FLOAT.parse(1.1)); // accuracy loss is expected + assertEquals(1.1d, NumberType.DOUBLE.parse(1.1)); + } } diff --git a/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalMapperPlugin.java b/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalMapperPlugin.java index 863e0c25fb0..87daaa58769 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalMapperPlugin.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalMapperPlugin.java @@ -43,6 +43,7 @@ public class ExternalMapperPlugin extends Plugin { indicesModule.registerMapper(EXTERNAL, new ExternalMapper.TypeParser(EXTERNAL, "foo")); indicesModule.registerMapper(EXTERNAL_BIS, new ExternalMapper.TypeParser(EXTERNAL_BIS, "bar")); indicesModule.registerMapper(EXTERNAL_UPPER, new ExternalMapper.TypeParser(EXTERNAL_UPPER, "FOO BAR")); + indicesModule.registerMapper(FakeStringFieldMapper.CONTENT_TYPE, new FakeStringFieldMapper.TypeParser()); } -} \ No newline at end of file +} diff --git a/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalValuesMapperIntegrationIT.java b/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalValuesMapperIntegrationIT.java index 171245841a0..350cbc43f9a 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalValuesMapperIntegrationIT.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalValuesMapperIntegrationIT.java @@ -25,10 +25,12 @@ import org.elasticsearch.common.geo.builders.ShapeBuilders; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.search.highlight.HighlightBuilder; import org.elasticsearch.test.ESIntegTestCase; import java.util.Collection; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse; import static org.hamcrest.Matchers.equalTo; public class ExternalValuesMapperIntegrationIT extends ESIntegTestCase { @@ -37,6 +39,54 @@ public class ExternalValuesMapperIntegrationIT extends ESIntegTestCase { return pluginList(ExternalMapperPlugin.class); } + public void testHighlightingOnCustomString() throws Exception { + prepareCreate("test-idx").addMapping("type", + XContentFactory.jsonBuilder().startObject().startObject("type") + .startObject("properties") + .startObject("field").field("type", FakeStringFieldMapper.CONTENT_TYPE).endObject() + .endObject() + .endObject().endObject()).execute().get(); + ensureYellow("test-idx"); + + index("test-idx", "type", "1", XContentFactory.jsonBuilder() + .startObject() + .field("field", "Every day is exactly the same") + .endObject()); + refresh(); + + SearchResponse response; + // test if the highlighting is excluded when we use wildcards + response = client().prepareSearch("test-idx") + .setQuery(QueryBuilders.matchQuery("field", "exactly the same")) + .highlighter(new HighlightBuilder().field("*")) + .execute().actionGet(); + assertSearchResponse(response); + assertThat(response.getHits().getTotalHits(), equalTo(1L)); + assertThat(response.getHits().getAt(0).getHighlightFields().size(), equalTo(0)); + + // make sure it is not excluded when we explicitly provide the fieldname + response = client().prepareSearch("test-idx") + .setQuery(QueryBuilders.matchQuery("field", "exactly the same")) + .highlighter(new HighlightBuilder().field("field")) + .execute().actionGet(); + assertSearchResponse(response); + assertThat(response.getHits().getTotalHits(), equalTo(1L)); + assertThat(response.getHits().getAt(0).getHighlightFields().size(), equalTo(1)); + assertThat(response.getHits().getAt(0).getHighlightFields().get("field").fragments()[0].string(), equalTo("Every day is " + + "exactly the same")); + + // make sure it is not excluded when we explicitly provide the fieldname and a wildcard + response = client().prepareSearch("test-idx") + .setQuery(QueryBuilders.matchQuery("field", "exactly the same")) + .highlighter(new HighlightBuilder().field("*").field("field")) + .execute().actionGet(); + assertSearchResponse(response); + assertThat(response.getHits().getTotalHits(), equalTo(1L)); + assertThat(response.getHits().getAt(0).getHighlightFields().size(), equalTo(1)); + assertThat(response.getHits().getAt(0).getHighlightFields().get("field").fragments()[0].string(), equalTo("Every day is " + + "exactly the same")); + } + public void testExternalValues() throws Exception { prepareCreate("test-idx").addMapping("type", XContentFactory.jsonBuilder().startObject().startObject("type") diff --git a/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/FakeStringFieldMapper.java b/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/FakeStringFieldMapper.java new file mode 100755 index 00000000000..e0c1243f82f --- /dev/null +++ b/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/FakeStringFieldMapper.java @@ -0,0 +1,193 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.index.mapper.externalvalues; + +import org.apache.lucene.document.Field; +import org.apache.lucene.document.SortedSetDocValuesField; +import org.apache.lucene.index.IndexOptions; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.MultiTermQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.RegexpQuery; +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.Nullable; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.index.mapper.FieldMapper; +import org.elasticsearch.index.mapper.MappedFieldType; +import org.elasticsearch.index.mapper.Mapper; +import org.elasticsearch.index.mapper.MapperParsingException; +import org.elasticsearch.index.mapper.ParseContext; +import org.elasticsearch.index.mapper.core.StringFieldMapper; +import org.elasticsearch.index.query.QueryShardContext; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import static org.elasticsearch.index.mapper.core.TypeParsers.parseTextField; + +// Like a String mapper but with very few options. We just use it to test if highlighting on a custom string mapped field works as expected. +public class FakeStringFieldMapper extends FieldMapper { + + public static final String CONTENT_TYPE = "fake_string"; + + public static class Defaults { + + public static final MappedFieldType FIELD_TYPE = new FakeStringFieldType(); + + static { + FIELD_TYPE.freeze(); + } + } + + public static class Builder extends FieldMapper.Builder { + + public Builder(String name) { + super(name, Defaults.FIELD_TYPE, Defaults.FIELD_TYPE); + builder = this; + } + + @Override + public FakeStringFieldType fieldType() { + return (FakeStringFieldType) super.fieldType(); + } + + @Override + public FakeStringFieldMapper build(BuilderContext context) { + setupFieldType(context); + return new FakeStringFieldMapper( + name, fieldType(), defaultFieldType, + context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo); + } + } + + public static class TypeParser implements Mapper.TypeParser { + + public TypeParser() { + } + + @Override + public Mapper.Builder parse(String fieldName, Map node, ParserContext parserContext) throws MapperParsingException { + FakeStringFieldMapper.Builder builder = new FakeStringFieldMapper.Builder(fieldName); + parseTextField(builder, fieldName, node, parserContext); + return builder; + } + } + + public static final class FakeStringFieldType extends MappedFieldType { + + + public FakeStringFieldType() { + } + + protected FakeStringFieldType(FakeStringFieldType ref) { + super(ref); + } + + public FakeStringFieldType clone() { + return new FakeStringFieldType(this); + } + + @Override + public String typeName() { + return CONTENT_TYPE; + } + + @Override + public Query nullValueQuery() { + if (nullValue() == null) { + return null; + } + return termQuery(nullValue(), null); + } + + @Override + public Query regexpQuery(String value, int flags, int maxDeterminizedStates, @Nullable MultiTermQuery.RewriteMethod method, + @Nullable QueryShardContext context) { + RegexpQuery query = new RegexpQuery(new Term(name(), indexedValueForSearch(value)), flags, maxDeterminizedStates); + if (method != null) { + query.setRewriteMethod(method); + } + return query; + } + } + + protected FakeStringFieldMapper(String simpleName, FakeStringFieldType fieldType, MappedFieldType defaultFieldType, + Settings indexSettings, MultiFields multiFields, CopyTo copyTo) { + super(simpleName, fieldType, defaultFieldType, indexSettings, multiFields, copyTo); + } + + @Override + protected StringFieldMapper clone() { + return (StringFieldMapper) super.clone(); + } + + @Override + protected boolean customBoost() { + return true; + } + + @Override + protected void parseCreateField(ParseContext context, List fields) throws IOException { + StringFieldMapper.ValueAndBoost valueAndBoost = parseCreateFieldForString(context, fieldType().boost()); + if (valueAndBoost.value() == null) { + return; + } + if (fieldType().indexOptions() != IndexOptions.NONE || fieldType().stored()) { + Field field = new Field(fieldType().name(), valueAndBoost.value(), fieldType()); + fields.add(field); + } + if (fieldType().hasDocValues()) { + fields.add(new SortedSetDocValuesField(fieldType().name(), new BytesRef(valueAndBoost.value()))); + } + } + + public static StringFieldMapper.ValueAndBoost parseCreateFieldForString(ParseContext context, float defaultBoost) throws IOException { + if (context.externalValueSet()) { + return new StringFieldMapper.ValueAndBoost(context.externalValue().toString(), defaultBoost); + } + XContentParser parser = context.parser(); + return new StringFieldMapper.ValueAndBoost(parser.textOrNull(), defaultBoost); + } + + @Override + protected String contentType() { + return CONTENT_TYPE; + } + + @Override + protected void doMerge(Mapper mergeWith, boolean updateAllTypes) { + super.doMerge(mergeWith, updateAllTypes); + } + + @Override + public FakeStringFieldType fieldType() { + return (FakeStringFieldType) super.fieldType(); + } + + @Override + protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException { + super.doXContentBody(builder, includeDefaults, params); + doXContentAnalyzers(builder, includeDefaults); + } + +} diff --git a/core/src/test/java/org/elasticsearch/index/mapper/ip/IpFieldMapperTests.java b/core/src/test/java/org/elasticsearch/index/mapper/ip/IpFieldMapperTests.java index 3bb96cce31e..25979c5a632 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/ip/IpFieldMapperTests.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/ip/IpFieldMapperTests.java @@ -36,6 +36,7 @@ import org.junit.Before; import static org.hamcrest.Matchers.containsString; +import java.io.IOException; import java.net.InetAddress; public class IpFieldMapperTests extends ESSingleNodeTestCase { @@ -217,4 +218,55 @@ public class IpFieldMapperTests extends ESSingleNodeTestCase { fields = doc.rootDoc().getFields("_all"); assertEquals(0, fields.length); } + + public void testNullValue() throws IOException { + String mapping = XContentFactory.jsonBuilder().startObject() + .startObject("type") + .startObject("properties") + .startObject("field") + .field("type", "ip") + .endObject() + .endObject() + .endObject().endObject().string(); + + DocumentMapper mapper = parser.parse("type", new CompressedXContent(mapping)); + assertEquals(mapping, mapper.mappingSource().toString()); + + ParsedDocument doc = mapper.parse("test", "type", "1", XContentFactory.jsonBuilder() + .startObject() + .nullField("field") + .endObject() + .bytes()); + assertArrayEquals(new IndexableField[0], doc.rootDoc().getFields("field")); + + mapping = XContentFactory.jsonBuilder().startObject() + .startObject("type") + .startObject("properties") + .startObject("field") + .field("type", "ip") + .field("null_value", "::1") + .endObject() + .endObject() + .endObject().endObject().string(); + + mapper = parser.parse("type", new CompressedXContent(mapping)); + assertEquals(mapping, mapper.mappingSource().toString()); + + doc = mapper.parse("test", "type", "1", XContentFactory.jsonBuilder() + .startObject() + .nullField("field") + .endObject() + .bytes()); + IndexableField[] fields = doc.rootDoc().getFields("field"); + assertEquals(2, fields.length); + IndexableField pointField = fields[0]; + assertEquals(1, pointField.fieldType().pointDimensionCount()); + assertEquals(16, pointField.fieldType().pointNumBytes()); + assertFalse(pointField.fieldType().stored()); + assertEquals(new BytesRef(InetAddressPoint.encode(InetAddresses.forString("::1"))), pointField.binaryValue()); + IndexableField dvField = fields[1]; + assertEquals(DocValuesType.SORTED_SET, dvField.fieldType().docValuesType()); + assertEquals(new BytesRef(InetAddressPoint.encode(InetAddresses.forString("::1"))), dvField.binaryValue()); + assertFalse(dvField.fieldType().stored()); + } } diff --git a/core/src/test/java/org/elasticsearch/index/query/AbstractQueryTestCase.java b/core/src/test/java/org/elasticsearch/index/query/AbstractQueryTestCase.java index fac11ab1f78..078809b43f5 100644 --- a/core/src/test/java/org/elasticsearch/index/query/AbstractQueryTestCase.java +++ b/core/src/test/java/org/elasticsearch/index/query/AbstractQueryTestCase.java @@ -426,14 +426,14 @@ public abstract class AbstractQueryTestCase> } /** - * Subclasses can override this method and return a set of fields which should be protected from + * Subclasses can override this method and return an array of fieldnames which should be protected from * recursive random shuffling in the {@link #testFromXContent()} test case */ - protected Set shuffleProtectedFields() { - return Collections.emptySet(); + protected String[] shuffleProtectedFields() { + return new String[0]; } - protected static XContentBuilder toXContent(QueryBuilder query, XContentType contentType) throws IOException { + protected static XContentBuilder toXContent(QueryBuilder query, XContentType contentType) throws IOException { XContentBuilder builder = XContentFactory.contentBuilder(contentType); if (randomBoolean()) { builder.prettyPrint(); @@ -499,12 +499,12 @@ public abstract class AbstractQueryTestCase> /** * Parses the query provided as string argument and compares it with the expected result provided as argument as a {@link QueryBuilder} */ - protected final void assertParsedQuery(String queryAsString, QueryBuilder expectedQuery) throws IOException { + protected final void assertParsedQuery(String queryAsString, QueryBuilder expectedQuery) throws IOException { assertParsedQuery(queryAsString, expectedQuery, ParseFieldMatcher.STRICT); } - protected final void assertParsedQuery(String queryAsString, QueryBuilder expectedQuery, ParseFieldMatcher matcher) throws IOException { - QueryBuilder newQuery = parseQuery(queryAsString, matcher); + protected final void assertParsedQuery(String queryAsString, QueryBuilder expectedQuery, ParseFieldMatcher matcher) throws IOException { + QueryBuilder newQuery = parseQuery(queryAsString, matcher); assertNotSame(newQuery, expectedQuery); assertEquals(expectedQuery, newQuery); assertEquals(expectedQuery.hashCode(), newQuery.hashCode()); @@ -513,38 +513,38 @@ public abstract class AbstractQueryTestCase> /** * Parses the query provided as bytes argument and compares it with the expected result provided as argument as a {@link QueryBuilder} */ - protected final void assertParsedQuery(BytesReference queryAsBytes, QueryBuilder expectedQuery) throws IOException { + protected final void assertParsedQuery(BytesReference queryAsBytes, QueryBuilder expectedQuery) throws IOException { assertParsedQuery(queryAsBytes, expectedQuery, ParseFieldMatcher.STRICT); } - protected final void assertParsedQuery(BytesReference queryAsBytes, QueryBuilder expectedQuery, ParseFieldMatcher matcher) throws IOException { - QueryBuilder newQuery = parseQuery(queryAsBytes, matcher); + protected final void assertParsedQuery(BytesReference queryAsBytes, QueryBuilder expectedQuery, ParseFieldMatcher matcher) throws IOException { + QueryBuilder newQuery = parseQuery(queryAsBytes, matcher); assertNotSame(newQuery, expectedQuery); assertEquals(expectedQuery, newQuery); assertEquals(expectedQuery.hashCode(), newQuery.hashCode()); } - protected final QueryBuilder parseQuery(String queryAsString) throws IOException { + protected final QueryBuilder parseQuery(String queryAsString) throws IOException { return parseQuery(queryAsString, ParseFieldMatcher.STRICT); } - protected final QueryBuilder parseQuery(String queryAsString, ParseFieldMatcher matcher) throws IOException { + protected final QueryBuilder parseQuery(String queryAsString, ParseFieldMatcher matcher) throws IOException { XContentParser parser = XContentFactory.xContent(queryAsString).createParser(queryAsString); return parseQuery(parser, matcher); } - protected final QueryBuilder parseQuery(BytesReference queryAsBytes) throws IOException { + protected final QueryBuilder parseQuery(BytesReference queryAsBytes) throws IOException { return parseQuery(queryAsBytes, ParseFieldMatcher.STRICT); } - protected final QueryBuilder parseQuery(BytesReference queryAsBytes, ParseFieldMatcher matcher) throws IOException { + protected final QueryBuilder parseQuery(BytesReference queryAsBytes, ParseFieldMatcher matcher) throws IOException { XContentParser parser = XContentFactory.xContent(queryAsBytes).createParser(queryAsBytes); return parseQuery(parser, matcher); } - private QueryBuilder parseQuery(XContentParser parser, ParseFieldMatcher matcher) throws IOException { + private QueryBuilder parseQuery(XContentParser parser, ParseFieldMatcher matcher) throws IOException { QueryParseContext context = createParseContext(parser, matcher); - QueryBuilder parseInnerQueryBuilder = context.parseInnerQueryBuilder(); + QueryBuilder parseInnerQueryBuilder = context.parseInnerQueryBuilder(); assertNull(parser.nextToken()); return parseInnerQueryBuilder; } @@ -602,8 +602,8 @@ public abstract class AbstractQueryTestCase> } } - private QueryBuilder rewriteQuery(QB queryBuilder, QueryRewriteContext rewriteContext) throws IOException { - QueryBuilder rewritten = QueryBuilder.rewriteQuery(queryBuilder, rewriteContext); + private QueryBuilder rewriteQuery(QB queryBuilder, QueryRewriteContext rewriteContext) throws IOException { + QueryBuilder rewritten = QueryBuilder.rewriteQuery(queryBuilder, rewriteContext); // extra safety to fail fast - serialize the rewritten version to ensure it's serializable. assertSerialization(rewritten); return rewritten; @@ -686,7 +686,7 @@ public abstract class AbstractQueryTestCase> try (BytesStreamOutput output = new BytesStreamOutput()) { output.writeNamedWriteable(testQuery); try (StreamInput in = new NamedWriteableAwareStreamInput(StreamInput.wrap(output.bytes()), namedWriteableRegistry)) { - QueryBuilder deserializedQuery = in.readNamedWriteable(QueryBuilder.class); + QueryBuilder deserializedQuery = in.readNamedWriteable(QueryBuilder.class); assertEquals(testQuery, deserializedQuery); assertEquals(testQuery.hashCode(), deserializedQuery.hashCode()); assertNotSame(testQuery, deserializedQuery); @@ -963,7 +963,7 @@ public abstract class AbstractQueryTestCase> *
  • By now the roundtrip check for the json should be happy. * **/ - public static void checkGeneratedJson(String expected, QueryBuilder source) throws IOException { + public static void checkGeneratedJson(String expected, QueryBuilder source) throws IOException { // now assert that we actually generate the same JSON XContentBuilder builder = XContentFactory.jsonBuilder().prettyPrint(); source.toXContent(builder, ToXContent.EMPTY_PARAMS); diff --git a/core/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java index b6b97f6fbf2..a49d410fdd6 100644 --- a/core/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java @@ -113,9 +113,9 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase getBooleanClauses(List> queryBuilders, BooleanClause.Occur occur, QueryShardContext context) throws IOException { + private static List getBooleanClauses(List queryBuilders, BooleanClause.Occur occur, QueryShardContext context) throws IOException { List clauses = new ArrayList<>(); - for (QueryBuilder query : queryBuilders) { + for (QueryBuilder query : queryBuilders) { Query innerQuery = query.toQuery(context); if (innerQuery != null) { clauses.add(new BooleanClause(innerQuery, occur)); @@ -132,22 +132,22 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase 0) { - QueryBuilder must = tempQueryBuilder.must().get(0); + QueryBuilder must = tempQueryBuilder.must().get(0); contentString += "\"must\": " + must.toString() + ","; expectedQuery.must(must); } if (tempQueryBuilder.mustNot().size() > 0) { - QueryBuilder mustNot = tempQueryBuilder.mustNot().get(0); + QueryBuilder mustNot = tempQueryBuilder.mustNot().get(0); contentString += (randomBoolean() ? "\"must_not\": " : "\"mustNot\": ") + mustNot.toString() + ","; expectedQuery.mustNot(mustNot); } if (tempQueryBuilder.should().size() > 0) { - QueryBuilder should = tempQueryBuilder.should().get(0); + QueryBuilder should = tempQueryBuilder.should().get(0); contentString += "\"should\": " + should.toString() + ","; expectedQuery.should(should); } if (tempQueryBuilder.filter().size() > 0) { - QueryBuilder filter = tempQueryBuilder.filter().get(0); + QueryBuilder filter = tempQueryBuilder.filter().get(0); contentString += "\"filter\": " + filter.toString() + ","; expectedQuery.filter(filter); } @@ -366,7 +366,7 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase rewritten = boolQueryBuilder.rewrite(createShardContext()); + QueryBuilder rewritten = boolQueryBuilder.rewrite(createShardContext()); if (mustRewrite == false && boolQueryBuilder.must().isEmpty()) { // if it's empty we rewrite to match all assertEquals(rewritten, new MatchAllQueryBuilder()); @@ -398,14 +398,14 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase rewritten = boolQueryBuilder.rewrite(createShardContext()); + QueryBuilder rewritten = boolQueryBuilder.rewrite(createShardContext()); BoolQueryBuilder expected = new BoolQueryBuilder(); expected.must(new WrapperQueryBuilder(new MatchAllQueryBuilder().toString())); assertEquals(expected, rewritten); expected = new BoolQueryBuilder(); expected.must(new MatchAllQueryBuilder()); - QueryBuilder rewrittenAgain = rewritten.rewrite(createShardContext()); + QueryBuilder rewrittenAgain = rewritten.rewrite(createShardContext()); assertEquals(rewrittenAgain, expected); assertEquals(QueryBuilder.rewriteQuery(boolQueryBuilder, createShardContext()), expected); } diff --git a/core/src/test/java/org/elasticsearch/index/query/BoostingQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/BoostingQueryBuilderTests.java index 27c888aa9dd..ecdadeca923 100644 --- a/core/src/test/java/org/elasticsearch/index/query/BoostingQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/BoostingQueryBuilderTests.java @@ -108,7 +108,7 @@ public class BoostingQueryBuilderTests extends AbstractQueryTestCase rewrite = qb.rewrite(createShardContext()); + QueryBuilder rewrite = qb.rewrite(createShardContext()); if (positive instanceof MatchAllQueryBuilder && negative instanceof MatchAllQueryBuilder) { assertSame(rewrite, qb); } else { diff --git a/core/src/test/java/org/elasticsearch/index/query/ConstantScoreQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/ConstantScoreQueryBuilderTests.java index 90b692e1db2..8d2b30c9ba8 100644 --- a/core/src/test/java/org/elasticsearch/index/query/ConstantScoreQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/ConstantScoreQueryBuilderTests.java @@ -96,7 +96,7 @@ public class ConstantScoreQueryBuilderTests extends AbstractQueryTestCase new ConstantScoreQueryBuilder((QueryBuilder) null)); + expectThrows(IllegalArgumentException.class, () -> new ConstantScoreQueryBuilder((QueryBuilder) null)); } @Override diff --git a/core/src/test/java/org/elasticsearch/index/query/DisMaxQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/DisMaxQueryBuilderTests.java index 810cca0b240..b77abd280a7 100644 --- a/core/src/test/java/org/elasticsearch/index/query/DisMaxQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/DisMaxQueryBuilderTests.java @@ -74,7 +74,7 @@ public class DisMaxQueryBuilderTests extends AbstractQueryTestCase getAlternateVersions() { Map alternateVersions = new HashMap<>(); - QueryBuilder innerQuery = createTestQueryBuilder().innerQueries().get(0); + QueryBuilder innerQuery = createTestQueryBuilder().innerQueries().get(0); DisMaxQueryBuilder expectedQuery = new DisMaxQueryBuilder(); expectedQuery.add(innerQuery); String contentString = "{\n" + @@ -101,7 +101,7 @@ public class DisMaxQueryBuilderTests extends AbstractQueryTestCase innerQueryBuilder = parseQuery(queryString); + QueryBuilder innerQueryBuilder = parseQuery(queryString); DisMaxQueryBuilder disMaxBuilder = new DisMaxQueryBuilder().add(innerQueryBuilder); assertNull(disMaxBuilder.toQuery(createShardContext())); } diff --git a/core/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java index 8ba48839aba..4c6b26d6848 100644 --- a/core/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java @@ -494,7 +494,7 @@ public class GeoBoundingBoxQueryBuilderTests extends AbstractQueryTestCase parsedGeoBboxShortcut = parseQuery(json, ParseFieldMatcher.EMPTY); + QueryBuilder parsedGeoBboxShortcut = parseQuery(json, ParseFieldMatcher.EMPTY); assertThat(parsedGeoBboxShortcut, equalTo(parsed)); try { diff --git a/core/src/test/java/org/elasticsearch/index/query/GeoShapeQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/GeoShapeQueryBuilderTests.java index 08f988c2a0b..aaf804e7703 100644 --- a/core/src/test/java/org/elasticsearch/index/query/GeoShapeQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/GeoShapeQueryBuilderTests.java @@ -261,7 +261,7 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase rewrite = sqb.rewrite(createShardContext()); + QueryBuilder rewrite = sqb.rewrite(createShardContext()); GeoShapeQueryBuilder geoShapeQueryBuilder = new GeoShapeQueryBuilder(GEO_SHAPE_FIELD_NAME, indexedShapeToReturn); geoShapeQueryBuilder.strategy(sqb.strategy()); geoShapeQueryBuilder.relation(sqb.relation()); diff --git a/core/src/test/java/org/elasticsearch/index/query/HasChildQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/HasChildQueryBuilderTests.java index 36a135a9fb1..2df15592f45 100644 --- a/core/src/test/java/org/elasticsearch/index/query/HasChildQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/HasChildQueryBuilderTests.java @@ -115,7 +115,7 @@ public class HasChildQueryBuilderTests extends AbstractQueryTestCase innerQueryBuilder = queryBuilder.query(); + QueryBuilder innerQueryBuilder = queryBuilder.query(); if (innerQueryBuilder instanceof EmptyQueryBuilder) { assertNull(query); } else { @@ -140,8 +140,8 @@ public class HasChildQueryBuilderTests extends AbstractQueryTestCase query = RandomQueryBuilder.createQuery(random()); + QueryBuilder query = RandomQueryBuilder.createQuery(random()); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> QueryBuilders.hasChildQuery(null, query, ScoreMode.None)); assertEquals("[has_child] requires 'type' field", e.getMessage()); diff --git a/core/src/test/java/org/elasticsearch/index/query/HasParentQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/HasParentQueryBuilderTests.java index 59f2d9c85b7..d1b0c6ab222 100644 --- a/core/src/test/java/org/elasticsearch/index/query/HasParentQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/HasParentQueryBuilderTests.java @@ -121,8 +121,8 @@ public class HasParentQueryBuilderTests extends AbstractQueryTestCase new IndicesQueryBuilder(new MatchAllQueryBuilder(), new String[0])); IndicesQueryBuilder indicesQueryBuilder = new IndicesQueryBuilder(new MatchAllQueryBuilder(), "index"); - expectThrows(IllegalArgumentException.class, () -> indicesQueryBuilder.noMatchQuery((QueryBuilder) null)); + expectThrows(IllegalArgumentException.class, () -> indicesQueryBuilder.noMatchQuery((QueryBuilder) null)); expectThrows(IllegalArgumentException.class, () -> indicesQueryBuilder.noMatchQuery((String) null)); } diff --git a/core/src/test/java/org/elasticsearch/index/query/InnerHitBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/InnerHitBuilderTests.java index d2cbec890e8..d4ba6ca9062 100644 --- a/core/src/test/java/org/elasticsearch/index/query/InnerHitBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/InnerHitBuilderTests.java @@ -24,7 +24,6 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.sameInstance; import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -92,7 +91,7 @@ public class InnerHitBuilderTests extends ESTestCase { InnerHitBuilder innerHit = randomInnerHits(true, false); XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values())); innerHit.toXContent(builder, ToXContent.EMPTY_PARAMS); - XContentBuilder shuffled = shuffleXContent(builder, Collections.emptySet()); + XContentBuilder shuffled = shuffleXContent(builder); if (randomBoolean()) { shuffled.prettyPrint(); } @@ -221,7 +220,12 @@ public class InnerHitBuilderTests extends ESTestCase { innerHits.setTrackScores(randomBoolean()); innerHits.setFieldNames(randomListStuff(16, () -> randomAsciiOfLengthBetween(1, 16))); innerHits.setFieldDataFields(randomListStuff(16, () -> randomAsciiOfLengthBetween(1, 16))); - innerHits.setScriptFields(new HashSet<>(randomListStuff(16, InnerHitBuilderTests::randomScript))); + // Random script fields deduped on their field name. + Map scriptFields = new HashMap<>(); + for (SearchSourceBuilder.ScriptField field: randomListStuff(16, InnerHitBuilderTests::randomScript)) { + scriptFields.put(field.fieldName(), field); + } + innerHits.setScriptFields(new HashSet<>(scriptFields.values())); FetchSourceContext randomFetchSourceContext; if (randomBoolean()) { randomFetchSourceContext = new FetchSourceContext(randomBoolean()); @@ -246,7 +250,7 @@ public class InnerHitBuilderTests extends ESTestCase { } if (includeQueryTypeOrPath) { - QueryBuilder query = new MatchQueryBuilder(randomAsciiOfLengthBetween(1, 16), randomAsciiOfLengthBetween(1, 16)); + QueryBuilder query = new MatchQueryBuilder(randomAsciiOfLengthBetween(1, 16), randomAsciiOfLengthBetween(1, 16)); if (randomBoolean()) { return new InnerHitBuilder(innerHits, randomAsciiOfLength(8), query); } else { diff --git a/core/src/test/java/org/elasticsearch/index/query/NestedQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/NestedQueryBuilderTests.java index b35201f47a1..23d595107b4 100644 --- a/core/src/test/java/org/elasticsearch/index/query/NestedQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/NestedQueryBuilderTests.java @@ -105,8 +105,8 @@ public class NestedQueryBuilderTests extends AbstractQueryTestCase innerQuery = RandomQueryBuilder.createQuery(random()); + QueryBuilder innerQuery = RandomQueryBuilder.createQuery(random()); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> QueryBuilders.nestedQuery(null, innerQuery, ScoreMode.Avg)); assertThat(e.getMessage(), equalTo("[nested] requires 'path' field")); diff --git a/core/src/test/java/org/elasticsearch/index/query/PercolateQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/PercolateQueryBuilderTests.java index 59d79378caa..690b2c03a2f 100644 --- a/core/src/test/java/org/elasticsearch/index/query/PercolateQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/PercolateQueryBuilderTests.java @@ -42,15 +42,12 @@ import org.junit.BeforeClass; import java.io.IOException; import java.util.Collections; -import java.util.Set; - import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; public class PercolateQueryBuilderTests extends AbstractQueryTestCase { - private static final Set SHUFFLE_PROTECTED_FIELDS = - Collections.singleton(PercolateQueryBuilder.DOCUMENT_FIELD.getPreferredName()); + private static final String[] SHUFFLE_PROTECTED_FIELDS = new String[] { PercolateQueryBuilder.DOCUMENT_FIELD.getPreferredName()}; private static String queryField; private static String docType; @@ -105,7 +102,7 @@ public class PercolateQueryBuilderTests extends AbstractQueryTestCase shuffleProtectedFields() { + protected String[] shuffleProtectedFields() { return SHUFFLE_PROTECTED_FIELDS; } @@ -142,7 +139,7 @@ public class PercolateQueryBuilderTests extends AbstractQueryTestCase pqb.toQuery(createShardContext())); assertThat(e.getMessage(), equalTo("query builder must be rewritten first")); - QueryBuilder rewrite = pqb.rewrite(createShardContext()); + QueryBuilder rewrite = pqb.rewrite(createShardContext()); PercolateQueryBuilder geoShapeQueryBuilder = new PercolateQueryBuilder(pqb.getField(), pqb.getDocumentType(), documentSource); assertEquals(geoShapeQueryBuilder, rewrite); } diff --git a/core/src/test/java/org/elasticsearch/index/query/QueryStringQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/QueryStringQueryBuilderTests.java index a763b257afb..4de7dae8c0b 100644 --- a/core/src/test/java/org/elasticsearch/index/query/QueryStringQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/QueryStringQueryBuilderTests.java @@ -413,7 +413,7 @@ public class QueryStringQueryBuilderTests extends AbstractQueryTestCase queryBuilder = parseQuery(queryAsString); + QueryBuilder queryBuilder = parseQuery(queryAsString); assertThat(queryBuilder, instanceOf(QueryStringQueryBuilder.class)); QueryStringQueryBuilder queryStringQueryBuilder = (QueryStringQueryBuilder) queryBuilder; assertThat(queryStringQueryBuilder.timeZone(), equalTo(DateTimeZone.forID("Europe/Paris"))); diff --git a/core/src/test/java/org/elasticsearch/index/query/RandomQueryBuilder.java b/core/src/test/java/org/elasticsearch/index/query/RandomQueryBuilder.java index f99a202eb88..23ef8045cc1 100644 --- a/core/src/test/java/org/elasticsearch/index/query/RandomQueryBuilder.java +++ b/core/src/test/java/org/elasticsearch/index/query/RandomQueryBuilder.java @@ -36,7 +36,7 @@ public class RandomQueryBuilder { * @param r random seed * @return a random {@link QueryBuilder} */ - public static QueryBuilder createQuery(Random r) { + public static QueryBuilder createQuery(Random r) { switch (RandomInts.randomIntBetween(r, 0, 4)) { case 0: return new MatchAllQueryBuilderTests().createTestQueryBuilder(); @@ -61,7 +61,7 @@ public class RandomQueryBuilder { public static MultiTermQueryBuilder createMultiTermQuery(Random r) { // for now, only use String Rangequeries for MultiTerm test, numeric and date makes little sense // see issue #12123 for discussion - MultiTermQueryBuilder multiTermQueryBuilder; + MultiTermQueryBuilder multiTermQueryBuilder; switch(RandomInts.randomIntBetween(r, 0, 3)) { case 0: RangeQueryBuilder stringRangeQuery = new RangeQueryBuilder(AbstractQueryTestCase.STRING_FIELD_NAME); diff --git a/core/src/test/java/org/elasticsearch/index/query/RangeQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/RangeQueryBuilderTests.java index d242e2ecf8f..c3db90f1f6d 100644 --- a/core/src/test/java/org/elasticsearch/index/query/RangeQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/RangeQueryBuilderTests.java @@ -464,7 +464,7 @@ public class RangeQueryBuilderTests extends AbstractQueryTestCase rewritten = query.rewrite(queryShardContext); + QueryBuilder rewritten = query.rewrite(queryShardContext); assertThat(rewritten, instanceOf(RangeQueryBuilder.class)); RangeQueryBuilder rewrittenRange = (RangeQueryBuilder) rewritten; assertThat(rewrittenRange.fieldName(), equalTo(fieldName)); @@ -485,7 +485,7 @@ public class RangeQueryBuilderTests extends AbstractQueryTestCase rewritten = query.rewrite(queryShardContext); + QueryBuilder rewritten = query.rewrite(queryShardContext); assertThat(rewritten, instanceOf(MatchNoneQueryBuilder.class)); } @@ -502,7 +502,7 @@ public class RangeQueryBuilderTests extends AbstractQueryTestCase rewritten = query.rewrite(queryShardContext); + QueryBuilder rewritten = query.rewrite(queryShardContext); assertThat(rewritten, sameInstance(query)); } @@ -515,7 +515,7 @@ public class RangeQueryBuilderTests extends AbstractQueryTestCase rewritten = query.rewrite(queryShardContext); + QueryBuilder rewritten = query.rewrite(queryShardContext); assertThat(rewritten, sameInstance(query)); } } diff --git a/core/src/test/java/org/elasticsearch/index/query/SpanMultiTermQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/SpanMultiTermQueryBuilderTests.java index cb35b85d3d9..e9ac69001ef 100644 --- a/core/src/test/java/org/elasticsearch/index/query/SpanMultiTermQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/SpanMultiTermQueryBuilderTests.java @@ -59,7 +59,7 @@ public class SpanMultiTermQueryBuilderTests extends AbstractQueryTestCase new SpanMultiTermQueryBuilder((MultiTermQueryBuilder) null)); + expectThrows(IllegalArgumentException.class, () -> new SpanMultiTermQueryBuilder((MultiTermQueryBuilder) null)); } /** diff --git a/core/src/test/java/org/elasticsearch/index/query/SpanNearQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/SpanNearQueryBuilderTests.java index 11ebd431030..202623d1980 100644 --- a/core/src/test/java/org/elasticsearch/index/query/SpanNearQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/SpanNearQueryBuilderTests.java @@ -50,7 +50,7 @@ public class SpanNearQueryBuilderTests extends AbstractQueryTestCase> spanQueryBuilderIterator = queryBuilder.clauses().iterator(); + Iterator spanQueryBuilderIterator = queryBuilder.clauses().iterator(); for (SpanQuery spanQuery : spanNearQuery.getClauses()) { assertThat(spanQuery, equalTo(spanQueryBuilderIterator.next().toQuery(context))); } diff --git a/core/src/test/java/org/elasticsearch/index/query/SpanOrQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/SpanOrQueryBuilderTests.java index b7533fe4605..a9c4ec7d7dc 100644 --- a/core/src/test/java/org/elasticsearch/index/query/SpanOrQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/SpanOrQueryBuilderTests.java @@ -45,14 +45,14 @@ public class SpanOrQueryBuilderTests extends AbstractQueryTestCase> spanQueryBuilderIterator = queryBuilder.clauses().iterator(); + Iterator spanQueryBuilderIterator = queryBuilder.clauses().iterator(); for (SpanQuery spanQuery : spanOrQuery.getClauses()) { assertThat(spanQuery, equalTo(spanQueryBuilderIterator.next().toQuery(context))); } } public void testIllegalArguments() { - expectThrows(IllegalArgumentException.class, () -> new SpanOrQueryBuilder((SpanQueryBuilder) null)); + expectThrows(IllegalArgumentException.class, () -> new SpanOrQueryBuilder((SpanQueryBuilder) null)); try { SpanOrQueryBuilder spanOrBuilder = new SpanOrQueryBuilder(new SpanTermQueryBuilder("field", "value")); diff --git a/core/src/test/java/org/elasticsearch/index/query/TemplateQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/TemplateQueryBuilderTests.java index a6dc42a266e..ee6621bef5b 100644 --- a/core/src/test/java/org/elasticsearch/index/query/TemplateQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/TemplateQueryBuilderTests.java @@ -40,7 +40,7 @@ public class TemplateQueryBuilderTests extends AbstractQueryTestCase templateBase; + private static QueryBuilder templateBase; @BeforeClass public static void setupClass() { @@ -102,7 +102,7 @@ public class TemplateQueryBuilderTests extends AbstractQueryTestCase params = new HashMap<>(); params.put("template", "all"); - QueryBuilder expectedBuilder = new TemplateQueryBuilder(new Template(expectedTemplateString, ScriptType.INLINE, null, null, + QueryBuilder expectedBuilder = new TemplateQueryBuilder(new Template(expectedTemplateString, ScriptType.INLINE, null, null, params)); assertParsedQuery(query, expectedBuilder); } @@ -112,7 +112,7 @@ public class TemplateQueryBuilderTests extends AbstractQueryTestCase params = new HashMap<>(); params.put("template", "all"); - QueryBuilder expectedBuilder = new TemplateQueryBuilder(new Template(expectedTemplateString, ScriptType.INLINE, null, + QueryBuilder expectedBuilder = new TemplateQueryBuilder(new Template(expectedTemplateString, ScriptType.INLINE, null, XContentType.JSON, params)); assertParsedQuery(query, expectedBuilder); } @@ -120,7 +120,7 @@ public class TemplateQueryBuilderTests extends AbstractQueryTestCase builder = new TemplateQueryBuilder(new Template(query, ScriptType.INLINE, "mockscript", + QueryBuilder builder = new TemplateQueryBuilder(new Template(query, ScriptType.INLINE, "mockscript", XContentType.JSON, Collections.emptyMap())); try { builder.toQuery(createShardContext()); @@ -133,7 +133,7 @@ public class TemplateQueryBuilderTests extends AbstractQueryTestCase builder = new TemplateQueryBuilder(new Template(query, ScriptType.INLINE, "mockscript", + QueryBuilder builder = new TemplateQueryBuilder(new Template(query, ScriptType.INLINE, "mockscript", XContentType.JSON, Collections.emptyMap())); assertEquals(new MatchAllQueryBuilder().queryName("foobar"), builder.rewrite(createShardContext())); @@ -145,7 +145,7 @@ public class TemplateQueryBuilderTests extends AbstractQueryTestCase builder = new TemplateQueryBuilder(new Template(query.toString(), ScriptType.INLINE, "mockscript", + QueryBuilder builder = new TemplateQueryBuilder(new Template(query.toString(), ScriptType.INLINE, "mockscript", XContentType.JSON, Collections.emptyMap())); assertEquals(query, builder.rewrite(createShardContext())); diff --git a/core/src/test/java/org/elasticsearch/index/query/TermsQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/TermsQueryBuilderTests.java index a16f4e2f2ea..0b4faebe18d 100644 --- a/core/src/test/java/org/elasticsearch/index/query/TermsQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/TermsQueryBuilderTests.java @@ -291,7 +291,7 @@ public class TermsQueryBuilderTests extends AbstractQueryTestCase inShortcutParsed = parseQuery(json, ParseFieldMatcher.EMPTY); + QueryBuilder inShortcutParsed = parseQuery(json, ParseFieldMatcher.EMPTY); assertThat(inShortcutParsed, equalTo(parsed)); try { diff --git a/core/src/test/java/org/elasticsearch/index/query/WrapperQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/WrapperQueryBuilderTests.java index 749cef61c61..e2a0d551919 100644 --- a/core/src/test/java/org/elasticsearch/index/query/WrapperQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/WrapperQueryBuilderTests.java @@ -54,7 +54,7 @@ public class WrapperQueryBuilderTests extends AbstractQueryTestCase innerQuery = queryBuilder.rewrite(createShardContext()); + QueryBuilder innerQuery = queryBuilder.rewrite(createShardContext()); Query expected = rewrite(innerQuery.toQuery(context)); assertEquals(rewrite(query), expected); } @@ -138,12 +138,12 @@ public class WrapperQueryBuilderTests extends AbstractQueryTestCase rewrite = qb.rewrite(createShardContext()); + QueryBuilder rewrite = qb.rewrite(createShardContext()); assertEquals(tqb, rewrite); } public void testRewriteWithInnerName() throws IOException { - QueryBuilder builder = new WrapperQueryBuilder("{ \"match_all\" : {\"_name\" : \"foobar\"}}"); + QueryBuilder builder = new WrapperQueryBuilder("{ \"match_all\" : {\"_name\" : \"foobar\"}}"); QueryShardContext shardContext = createShardContext(); assertEquals(new MatchAllQueryBuilder().queryName("foobar"), builder.rewrite(shardContext)); builder = new WrapperQueryBuilder("{ \"match_all\" : {\"_name\" : \"foobar\"}}").queryName("outer"); @@ -153,7 +153,7 @@ public class WrapperQueryBuilderTests extends AbstractQueryTestCase builder = new WrapperQueryBuilder(query.toString()); + QueryBuilder builder = new WrapperQueryBuilder(query.toString()); QueryShardContext shardContext = createShardContext(); assertEquals(query, builder.rewrite(shardContext)); builder = new WrapperQueryBuilder(query.toString()).boost(3); diff --git a/core/src/test/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilderTests.java index 540066ba58b..0cbd80dc76c 100644 --- a/core/src/test/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/functionscore/FunctionScoreQueryBuilderTests.java @@ -240,7 +240,7 @@ public class FunctionScoreQueryBuilderTests extends AbstractQueryTestCase new FunctionScoreQueryBuilder((QueryBuilder) null)); + expectThrows(IllegalArgumentException.class, () -> new FunctionScoreQueryBuilder((QueryBuilder) null)); expectThrows(IllegalArgumentException.class, () -> new FunctionScoreQueryBuilder((ScoreFunctionBuilder) null)); expectThrows(IllegalArgumentException.class, () -> new FunctionScoreQueryBuilder((FilterFunctionBuilder[]) null)); expectThrows(IllegalArgumentException.class, () -> new FunctionScoreQueryBuilder(null, randomFunction(123))); @@ -301,7 +301,7 @@ public class FunctionScoreQueryBuilderTests extends AbstractQueryTestCase queryBuilder = parseQuery(functionScoreQuery); + QueryBuilder queryBuilder = parseQuery(functionScoreQuery); /* * given that we copy part of the decay functions as bytes, we test that fromXContent and toXContent both work no matter what the * initial format was @@ -343,7 +343,7 @@ public class FunctionScoreQueryBuilderTests extends AbstractQueryTestCase) queryBuilder).buildAsBytes(XContentType.values()[i])); + queryBuilder = parseQuery(((AbstractQueryBuilder) queryBuilder).buildAsBytes(XContentType.values()[i])); } } } @@ -369,7 +369,7 @@ public class FunctionScoreQueryBuilderTests extends AbstractQueryTestCase queryBuilder = parseQuery(functionScoreQuery); + QueryBuilder queryBuilder = parseQuery(functionScoreQuery); /* * given that we copy part of the decay functions as bytes, we test that fromXContent and toXContent both work no matter what the * initial format was @@ -395,7 +395,7 @@ public class FunctionScoreQueryBuilderTests extends AbstractQueryTestCase) queryBuilder).buildAsBytes(XContentType.values()[i])); + queryBuilder = parseQuery(((AbstractQueryBuilder) queryBuilder).buildAsBytes(XContentType.values()[i])); } } } @@ -476,7 +476,7 @@ public class FunctionScoreQueryBuilderTests extends AbstractQueryTestCase query = parseQuery(queryString); + QueryBuilder query = parseQuery(queryString); assertThat(query, instanceOf(FunctionScoreQueryBuilder.class)); FunctionScoreQueryBuilder functionScoreQueryBuilder = (FunctionScoreQueryBuilder) query; assertThat(functionScoreQueryBuilder.filterFunctionBuilders()[0].getScoreFunction(), @@ -618,9 +618,9 @@ public class FunctionScoreQueryBuilderTests extends AbstractQueryTestCase firstFunction = new WrapperQueryBuilder(new TermQueryBuilder("tq", "1").toString()); + QueryBuilder firstFunction = new WrapperQueryBuilder(new TermQueryBuilder("tq", "1").toString()); TermQueryBuilder secondFunction = new TermQueryBuilder("tq", "2"); - QueryBuilder queryBuilder = randomBoolean() ? new WrapperQueryBuilder(new TermQueryBuilder("foo", "bar").toString()) + QueryBuilder queryBuilder = randomBoolean() ? new WrapperQueryBuilder(new TermQueryBuilder("foo", "bar").toString()) : new TermQueryBuilder("foo", "bar"); FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(queryBuilder, new FunctionScoreQueryBuilder.FilterFunctionBuilder[] { diff --git a/core/src/test/java/org/elasticsearch/index/snapshots/blobstore/FileInfoTests.java b/core/src/test/java/org/elasticsearch/index/snapshots/blobstore/FileInfoTests.java index 1a31df45575..67c431135a0 100644 --- a/core/src/test/java/org/elasticsearch/index/snapshots/blobstore/FileInfoTests.java +++ b/core/src/test/java/org/elasticsearch/index/snapshots/blobstore/FileInfoTests.java @@ -32,7 +32,6 @@ import org.elasticsearch.index.store.StoreFileMetaData; import org.elasticsearch.test.ESTestCase; import java.io.IOException; - import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; @@ -53,7 +52,7 @@ public class FileInfoTests extends ESTestCase { BlobStoreIndexShardSnapshot.FileInfo info = new BlobStoreIndexShardSnapshot.FileInfo("_foobar", meta, size); XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON).prettyPrint(); BlobStoreIndexShardSnapshot.FileInfo.toXContent(info, builder, ToXContent.EMPTY_PARAMS); - byte[] xcontent = builder.bytes().toBytes(); + byte[] xcontent = shuffleXContent(builder).bytes().toBytes(); final BlobStoreIndexShardSnapshot.FileInfo parsedInfo; try (XContentParser parser = XContentFactory.xContent(XContentType.JSON).createParser(xcontent)) { diff --git a/core/src/test/java/org/elasticsearch/index/store/CorruptedFileIT.java b/core/src/test/java/org/elasticsearch/index/store/CorruptedFileIT.java index 367ecf76768..df8736b44ef 100644 --- a/core/src/test/java/org/elasticsearch/index/store/CorruptedFileIT.java +++ b/core/src/test/java/org/elasticsearch/index/store/CorruptedFileIT.java @@ -578,7 +578,7 @@ public class CorruptedFileIT extends ESIntegTestCase { } assertTrue(shardRouting.assignedToNode()); NodesStatsResponse nodeStatses = client().admin().cluster().prepareNodesStats(shardRouting.currentNodeId()).setFs(true).get(); - NodeStats nodeStats = nodeStatses.getNodes()[0]; + NodeStats nodeStats = nodeStatses.getNodes().get(0); List files = new ArrayList<>(); filesToNodes.put(nodeStats.getNode().getName(), files); for (FsInfo.Path info : nodeStats.getFs()) { @@ -615,7 +615,7 @@ public class CorruptedFileIT extends ESIntegTestCase { String nodeId = shardRouting.currentNodeId(); NodesStatsResponse nodeStatses = client().admin().cluster().prepareNodesStats(nodeId).setFs(true).get(); Set files = new TreeSet<>(); // treeset makes sure iteration order is deterministic - for (FsInfo.Path info : nodeStatses.getNodes()[0].getFs()) { + for (FsInfo.Path info : nodeStatses.getNodes().get(0).getFs()) { String path = info.getPath(); Path file = PathUtils.get(path).resolve("indices").resolve(test.getUUID()).resolve(Integer.toString(shardRouting.getId())).resolve("index"); if (Files.exists(file)) { // multi data path might only have one path in use @@ -678,9 +678,9 @@ public class CorruptedFileIT extends ESIntegTestCase { NodesStatsResponse nodeStatses = client().admin().cluster().prepareNodesStats(routing.currentNodeId()).setFs(true).get(); ClusterState state = client().admin().cluster().prepareState().get().getState(); final Index test = state.metaData().index("test").getIndex(); - assertThat(routing.toString(), nodeStatses.getNodes().length, equalTo(1)); + assertThat(routing.toString(), nodeStatses.getNodes().size(), equalTo(1)); List files = new ArrayList<>(); - for (FsInfo.Path info : nodeStatses.getNodes()[0].getFs()) { + for (FsInfo.Path info : nodeStatses.getNodes().get(0).getFs()) { String path = info.getPath(); Path file = PathUtils.get(path).resolve("indices/" + test.getUUID() + "/" + Integer.toString(routing.getId()) + "/index"); if (Files.exists(file)) { // multi data path might only have one path in use diff --git a/core/src/test/java/org/elasticsearch/index/store/CorruptedTranslogIT.java b/core/src/test/java/org/elasticsearch/index/store/CorruptedTranslogIT.java index 94ee490c729..018bce16566 100644 --- a/core/src/test/java/org/elasticsearch/index/store/CorruptedTranslogIT.java +++ b/core/src/test/java/org/elasticsearch/index/store/CorruptedTranslogIT.java @@ -121,7 +121,7 @@ public class CorruptedTranslogIT extends ESIntegTestCase { String nodeId = shardRouting.currentNodeId(); NodesStatsResponse nodeStatses = client().admin().cluster().prepareNodesStats(nodeId).setFs(true).get(); Set files = new TreeSet<>(); // treeset makes sure iteration order is deterministic - for (FsInfo.Path fsPath : nodeStatses.getNodes()[0].getFs()) { + for (FsInfo.Path fsPath : nodeStatses.getNodes().get(0).getFs()) { String path = fsPath.getPath(); final String relativeDataLocationPath = "indices/"+ test.getUUID() +"/" + Integer.toString(shardRouting.getId()) + "/translog"; Path file = PathUtils.get(path).resolve(relativeDataLocationPath); diff --git a/core/src/test/java/org/elasticsearch/index/suggest/stats/SuggestStatsIT.java b/core/src/test/java/org/elasticsearch/index/suggest/stats/SuggestStatsIT.java index 0d850632393..cb0397990ab 100644 --- a/core/src/test/java/org/elasticsearch/index/suggest/stats/SuggestStatsIT.java +++ b/core/src/test/java/org/elasticsearch/index/suggest/stats/SuggestStatsIT.java @@ -119,10 +119,9 @@ public class SuggestStatsIT extends ESIntegTestCase { assertThat(suggest.getSuggestTimeInMillis(), lessThanOrEqualTo(totalShards * (endTime - startTime))); NodesStatsResponse nodeStats = client().admin().cluster().prepareNodesStats().execute().actionGet(); - NodeStats[] nodes = nodeStats.getNodes(); Set nodeIdsWithIndex = nodeIdsWithIndex("test1", "test2"); int num = 0; - for (NodeStats stat : nodes) { + for (NodeStats stat : nodeStats.getNodes()) { SearchStats.Stats suggestStats = stat.getIndices().getSearch().getTotal(); logger.info("evaluating {}", stat.getNode()); if (nodeIdsWithIndex.contains(stat.getNode().getId())) { diff --git a/core/src/test/java/org/elasticsearch/indices/memory/breaker/CircuitBreakerServiceIT.java b/core/src/test/java/org/elasticsearch/indices/memory/breaker/CircuitBreakerServiceIT.java index 2f039f6c472..351742d9712 100644 --- a/core/src/test/java/org/elasticsearch/indices/memory/breaker/CircuitBreakerServiceIT.java +++ b/core/src/test/java/org/elasticsearch/indices/memory/breaker/CircuitBreakerServiceIT.java @@ -101,7 +101,7 @@ public class CircuitBreakerServiceIT extends ESIntegTestCase { /** Returns true if any of the nodes used a noop breaker */ private boolean noopBreakerUsed() { NodesStatsResponse stats = client().admin().cluster().prepareNodesStats().setBreaker(true).get(); - for (NodeStats nodeStats : stats) { + for (NodeStats nodeStats : stats.getNodes()) { if (nodeStats.getBreaker().getStats(CircuitBreaker.REQUEST).getLimit() == NoopCircuitBreaker.LIMIT) { return true; } @@ -230,7 +230,7 @@ public class CircuitBreakerServiceIT extends ESIntegTestCase { // We need the request limit beforehand, just from a single node because the limit should always be the same long beforeReqLimit = client.admin().cluster().prepareNodesStats().setBreaker(true).get() - .getNodes()[0].getBreaker().getStats(CircuitBreaker.REQUEST).getLimit(); + .getNodes().get(0).getBreaker().getStats(CircuitBreaker.REQUEST).getLimit(); Settings resetSettings = Settings.builder() .put(HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_LIMIT_SETTING.getKey(), "10b") diff --git a/core/src/test/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java b/core/src/test/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java index 17b1b8e7d70..77cffc20ae1 100644 --- a/core/src/test/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java +++ b/core/src/test/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java @@ -69,10 +69,10 @@ import java.util.concurrent.ExecutionException; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; -import static org.hamcrest.Matchers.arrayWithSize; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.lessThanOrEqualTo; import static org.hamcrest.Matchers.not; @@ -315,7 +315,7 @@ public class IndexRecoveryIT extends ESIntegTestCase { @Override public void run() { NodesStatsResponse statsResponse = client().admin().cluster().prepareNodesStats().clear().setIndices(new CommonStatsFlags(CommonStatsFlags.Flag.Recovery)).get(); - assertThat(statsResponse.getNodes(), arrayWithSize(2)); + assertThat(statsResponse.getNodes(), hasSize(2)); for (NodeStats nodeStats : statsResponse.getNodes()) { final RecoveryStats recoveryStats = nodeStats.getIndices().getRecoveryStats(); if (nodeStats.getNode().getName().equals(nodeA)) { @@ -344,7 +344,7 @@ public class IndexRecoveryIT extends ESIntegTestCase { validateIndexRecoveryState(recoveryStates.get(0).getIndex()); statsResponse = client().admin().cluster().prepareNodesStats().clear().setIndices(new CommonStatsFlags(CommonStatsFlags.Flag.Recovery)).get(); - assertThat(statsResponse.getNodes(), arrayWithSize(2)); + assertThat(statsResponse.getNodes(), hasSize(2)); for (NodeStats nodeStats : statsResponse.getNodes()) { final RecoveryStats recoveryStats = nodeStats.getIndices().getRecoveryStats(); assertThat(recoveryStats.currentAsSource(), equalTo(0)); @@ -363,7 +363,7 @@ public class IndexRecoveryIT extends ESIntegTestCase { ensureGreen(); statsResponse = client().admin().cluster().prepareNodesStats().clear().setIndices(new CommonStatsFlags(CommonStatsFlags.Flag.Recovery)).get(); - assertThat(statsResponse.getNodes(), arrayWithSize(2)); + assertThat(statsResponse.getNodes(), hasSize(2)); for (NodeStats nodeStats : statsResponse.getNodes()) { final RecoveryStats recoveryStats = nodeStats.getIndices().getRecoveryStats(); assertThat(recoveryStats.currentAsSource(), equalTo(0)); diff --git a/core/src/test/java/org/elasticsearch/indices/stats/IndexStatsIT.java b/core/src/test/java/org/elasticsearch/indices/stats/IndexStatsIT.java index b1513908874..4716e7dba78 100644 --- a/core/src/test/java/org/elasticsearch/indices/stats/IndexStatsIT.java +++ b/core/src/test/java/org/elasticsearch/indices/stats/IndexStatsIT.java @@ -104,7 +104,7 @@ public class IndexStatsIT extends ESIntegTestCase { client().admin().indices().prepareRefresh().execute().actionGet(); NodesStatsResponse nodesStats = client().admin().cluster().prepareNodesStats().setIndices(true).execute().actionGet(); - assertThat(nodesStats.getNodes()[0].getIndices().getFieldData().getMemorySizeInBytes() + nodesStats.getNodes()[1].getIndices().getFieldData().getMemorySizeInBytes(), equalTo(0L)); + assertThat(nodesStats.getNodes().get(0).getIndices().getFieldData().getMemorySizeInBytes() + nodesStats.getNodes().get(1).getIndices().getFieldData().getMemorySizeInBytes(), equalTo(0L)); IndicesStatsResponse indicesStats = client().admin().indices().prepareStats("test").clear().setFieldData(true).execute().actionGet(); assertThat(indicesStats.getTotal().getFieldData().getMemorySizeInBytes(), equalTo(0L)); @@ -113,7 +113,7 @@ public class IndexStatsIT extends ESIntegTestCase { client().prepareSearch().addSort("field", SortOrder.ASC).execute().actionGet(); nodesStats = client().admin().cluster().prepareNodesStats().setIndices(true).execute().actionGet(); - assertThat(nodesStats.getNodes()[0].getIndices().getFieldData().getMemorySizeInBytes() + nodesStats.getNodes()[1].getIndices().getFieldData().getMemorySizeInBytes(), greaterThan(0L)); + assertThat(nodesStats.getNodes().get(0).getIndices().getFieldData().getMemorySizeInBytes() + nodesStats.getNodes().get(1).getIndices().getFieldData().getMemorySizeInBytes(), greaterThan(0L)); indicesStats = client().admin().indices().prepareStats("test").clear().setFieldData(true).execute().actionGet(); assertThat(indicesStats.getTotal().getFieldData().getMemorySizeInBytes(), greaterThan(0L)); @@ -123,9 +123,9 @@ public class IndexStatsIT extends ESIntegTestCase { // now check the per field stats nodesStats = client().admin().cluster().prepareNodesStats().setIndices(new CommonStatsFlags().set(CommonStatsFlags.Flag.FieldData, true).fieldDataFields("*")).execute().actionGet(); - assertThat(nodesStats.getNodes()[0].getIndices().getFieldData().getMemorySizeInBytes() + nodesStats.getNodes()[1].getIndices().getFieldData().getMemorySizeInBytes(), greaterThan(0L)); - assertThat(nodesStats.getNodes()[0].getIndices().getFieldData().getFields().get("field") + nodesStats.getNodes()[1].getIndices().getFieldData().getFields().get("field"), greaterThan(0L)); - assertThat(nodesStats.getNodes()[0].getIndices().getFieldData().getFields().get("field") + nodesStats.getNodes()[1].getIndices().getFieldData().getFields().get("field"), lessThan(nodesStats.getNodes()[0].getIndices().getFieldData().getMemorySizeInBytes() + nodesStats.getNodes()[1].getIndices().getFieldData().getMemorySizeInBytes())); + assertThat(nodesStats.getNodes().get(0).getIndices().getFieldData().getMemorySizeInBytes() + nodesStats.getNodes().get(1).getIndices().getFieldData().getMemorySizeInBytes(), greaterThan(0L)); + assertThat(nodesStats.getNodes().get(0).getIndices().getFieldData().getFields().get("field") + nodesStats.getNodes().get(1).getIndices().getFieldData().getFields().get("field"), greaterThan(0L)); + assertThat(nodesStats.getNodes().get(0).getIndices().getFieldData().getFields().get("field") + nodesStats.getNodes().get(1).getIndices().getFieldData().getFields().get("field"), lessThan(nodesStats.getNodes().get(0).getIndices().getFieldData().getMemorySizeInBytes() + nodesStats.getNodes().get(1).getIndices().getFieldData().getMemorySizeInBytes())); indicesStats = client().admin().indices().prepareStats("test").clear().setFieldData(true).setFieldDataFields("*").execute().actionGet(); assertThat(indicesStats.getTotal().getFieldData().getMemorySizeInBytes(), greaterThan(0L)); @@ -134,7 +134,7 @@ public class IndexStatsIT extends ESIntegTestCase { client().admin().indices().prepareClearCache().setFieldDataCache(true).execute().actionGet(); nodesStats = client().admin().cluster().prepareNodesStats().setIndices(true).execute().actionGet(); - assertThat(nodesStats.getNodes()[0].getIndices().getFieldData().getMemorySizeInBytes() + nodesStats.getNodes()[1].getIndices().getFieldData().getMemorySizeInBytes(), equalTo(0L)); + assertThat(nodesStats.getNodes().get(0).getIndices().getFieldData().getMemorySizeInBytes() + nodesStats.getNodes().get(1).getIndices().getFieldData().getMemorySizeInBytes(), equalTo(0L)); indicesStats = client().admin().indices().prepareStats("test").clear().setFieldData(true).execute().actionGet(); assertThat(indicesStats.getTotal().getFieldData().getMemorySizeInBytes(), equalTo(0L)); @@ -152,8 +152,8 @@ public class IndexStatsIT extends ESIntegTestCase { NodesStatsResponse nodesStats = client().admin().cluster().prepareNodesStats().setIndices(true) .execute().actionGet(); - assertThat(nodesStats.getNodes()[0].getIndices().getFieldData().getMemorySizeInBytes() + nodesStats.getNodes()[1].getIndices().getFieldData().getMemorySizeInBytes(), equalTo(0L)); - assertThat(nodesStats.getNodes()[0].getIndices().getQueryCache().getMemorySizeInBytes() + nodesStats.getNodes()[1].getIndices().getQueryCache().getMemorySizeInBytes(), equalTo(0L)); + assertThat(nodesStats.getNodes().get(0).getIndices().getFieldData().getMemorySizeInBytes() + nodesStats.getNodes().get(1).getIndices().getFieldData().getMemorySizeInBytes(), equalTo(0L)); + assertThat(nodesStats.getNodes().get(0).getIndices().getQueryCache().getMemorySizeInBytes() + nodesStats.getNodes().get(1).getIndices().getQueryCache().getMemorySizeInBytes(), equalTo(0L)); IndicesStatsResponse indicesStats = client().admin().indices().prepareStats("test") .clear().setFieldData(true).setQueryCache(true) @@ -173,8 +173,8 @@ public class IndexStatsIT extends ESIntegTestCase { nodesStats = client().admin().cluster().prepareNodesStats().setIndices(true) .execute().actionGet(); - assertThat(nodesStats.getNodes()[0].getIndices().getFieldData().getMemorySizeInBytes() + nodesStats.getNodes()[1].getIndices().getFieldData().getMemorySizeInBytes(), greaterThan(0L)); - assertThat(nodesStats.getNodes()[0].getIndices().getQueryCache().getMemorySizeInBytes() + nodesStats.getNodes()[1].getIndices().getQueryCache().getMemorySizeInBytes(), greaterThan(0L)); + assertThat(nodesStats.getNodes().get(0).getIndices().getFieldData().getMemorySizeInBytes() + nodesStats.getNodes().get(1).getIndices().getFieldData().getMemorySizeInBytes(), greaterThan(0L)); + assertThat(nodesStats.getNodes().get(0).getIndices().getQueryCache().getMemorySizeInBytes() + nodesStats.getNodes().get(1).getIndices().getQueryCache().getMemorySizeInBytes(), greaterThan(0L)); indicesStats = client().admin().indices().prepareStats("test") .clear().setFieldData(true).setQueryCache(true) @@ -186,8 +186,8 @@ public class IndexStatsIT extends ESIntegTestCase { Thread.sleep(100); // Make sure the filter cache entries have been removed... nodesStats = client().admin().cluster().prepareNodesStats().setIndices(true) .execute().actionGet(); - assertThat(nodesStats.getNodes()[0].getIndices().getFieldData().getMemorySizeInBytes() + nodesStats.getNodes()[1].getIndices().getFieldData().getMemorySizeInBytes(), equalTo(0L)); - assertThat(nodesStats.getNodes()[0].getIndices().getQueryCache().getMemorySizeInBytes() + nodesStats.getNodes()[1].getIndices().getQueryCache().getMemorySizeInBytes(), equalTo(0L)); + assertThat(nodesStats.getNodes().get(0).getIndices().getFieldData().getMemorySizeInBytes() + nodesStats.getNodes().get(1).getIndices().getFieldData().getMemorySizeInBytes(), equalTo(0L)); + assertThat(nodesStats.getNodes().get(0).getIndices().getQueryCache().getMemorySizeInBytes() + nodesStats.getNodes().get(1).getIndices().getQueryCache().getMemorySizeInBytes(), equalTo(0L)); indicesStats = client().admin().indices().prepareStats("test") .clear().setFieldData(true).setQueryCache(true) diff --git a/core/src/test/java/org/elasticsearch/ingest/IngestMetadataTests.java b/core/src/test/java/org/elasticsearch/ingest/IngestMetadataTests.java index 38c1684b7ff..7924d069f2e 100644 --- a/core/src/test/java/org/elasticsearch/ingest/IngestMetadataTests.java +++ b/core/src/test/java/org/elasticsearch/ingest/IngestMetadataTests.java @@ -31,7 +31,6 @@ import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.test.ESTestCase; import java.io.IOException; -import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -57,7 +56,7 @@ public class IngestMetadataTests extends ESTestCase { builder.startObject(); ingestMetadata.toXContent(builder, ToXContent.EMPTY_PARAMS); builder.endObject(); - XContentBuilder shuffled = shuffleXContent(builder, Collections.emptySet()); + XContentBuilder shuffled = shuffleXContent(builder); final XContentParser parser = XContentFactory.xContent(shuffled.bytes()).createParser(shuffled.bytes()); MetaData.Custom custom = ingestMetadata.fromXContent(parser); assertTrue(custom instanceof IngestMetadata); diff --git a/core/src/test/java/org/elasticsearch/ingest/PipelineExecutionServiceTests.java b/core/src/test/java/org/elasticsearch/ingest/PipelineExecutionServiceTests.java index b84ba928be4..3c0de328c8c 100644 --- a/core/src/test/java/org/elasticsearch/ingest/PipelineExecutionServiceTests.java +++ b/core/src/test/java/org/elasticsearch/ingest/PipelineExecutionServiceTests.java @@ -46,11 +46,13 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; import static org.hamcrest.Matchers.equalTo; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.eq; +import static org.hamcrest.Matchers.hasKey; +import static org.hamcrest.Matchers.not; import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.argThat; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; @@ -380,6 +382,22 @@ public class PipelineExecutionServiceTests extends ESTestCase { assertThat(ingestStats.getTotalStats().getIngestCount(), equalTo(2L)); } + // issue: https://github.com/elastic/elasticsearch/issues/18126 + public void testUpdatingStatsWhenRemovingPipelineWorks() throws Exception { + Map configurationMap = new HashMap<>(); + configurationMap.put("_id1", new PipelineConfiguration("_id1", new BytesArray("{}"))); + configurationMap.put("_id2", new PipelineConfiguration("_id2", new BytesArray("{}"))); + executionService.updatePipelineStats(new IngestMetadata(configurationMap)); + assertThat(executionService.stats().getStatsPerPipeline(), hasKey("_id1")); + assertThat(executionService.stats().getStatsPerPipeline(), hasKey("_id2")); + + configurationMap = new HashMap<>(); + configurationMap.put("_id3", new PipelineConfiguration("_id3", new BytesArray("{}"))); + executionService.updatePipelineStats(new IngestMetadata(configurationMap)); + assertThat(executionService.stats().getStatsPerPipeline(), not(hasKey("_id1"))); + assertThat(executionService.stats().getStatsPerPipeline(), not(hasKey("_id2"))); + } + private IngestDocument eqID(String index, String type, String id, Map source) { return argThat(new IngestDocumentMatcher(index, type, id, source)); } diff --git a/core/src/test/java/org/elasticsearch/nodesinfo/SimpleNodesInfoIT.java b/core/src/test/java/org/elasticsearch/nodesinfo/SimpleNodesInfoIT.java index c38aeb967ef..b7dcf2872e2 100644 --- a/core/src/test/java/org/elasticsearch/nodesinfo/SimpleNodesInfoIT.java +++ b/core/src/test/java/org/elasticsearch/nodesinfo/SimpleNodesInfoIT.java @@ -54,29 +54,29 @@ public class SimpleNodesInfoIT extends ESIntegTestCase { logger.info("--> started nodes: {} and {}", server1NodeId, server2NodeId); NodesInfoResponse response = client().admin().cluster().prepareNodesInfo().execute().actionGet(); - assertThat(response.getNodes().length, is(2)); + assertThat(response.getNodes().size(), is(2)); assertThat(response.getNodesMap().get(server1NodeId), notNullValue()); assertThat(response.getNodesMap().get(server2NodeId), notNullValue()); response = client().admin().cluster().nodesInfo(nodesInfoRequest()).actionGet(); - assertThat(response.getNodes().length, is(2)); + assertThat(response.getNodes().size(), is(2)); assertThat(response.getNodesMap().get(server1NodeId), notNullValue()); assertThat(response.getNodesMap().get(server2NodeId), notNullValue()); response = client().admin().cluster().nodesInfo(nodesInfoRequest(server1NodeId)).actionGet(); - assertThat(response.getNodes().length, is(1)); + assertThat(response.getNodes().size(), is(1)); assertThat(response.getNodesMap().get(server1NodeId), notNullValue()); response = client().admin().cluster().nodesInfo(nodesInfoRequest(server1NodeId)).actionGet(); - assertThat(response.getNodes().length, is(1)); + assertThat(response.getNodes().size(), is(1)); assertThat(response.getNodesMap().get(server1NodeId), notNullValue()); response = client().admin().cluster().nodesInfo(nodesInfoRequest(server2NodeId)).actionGet(); - assertThat(response.getNodes().length, is(1)); + assertThat(response.getNodes().size(), is(1)); assertThat(response.getNodesMap().get(server2NodeId), notNullValue()); response = client().admin().cluster().nodesInfo(nodesInfoRequest(server2NodeId)).actionGet(); - assertThat(response.getNodes().length, is(1)); + assertThat(response.getNodes().size(), is(1)); assertThat(response.getNodesMap().get(server2NodeId), notNullValue()); } @@ -99,7 +99,7 @@ public class SimpleNodesInfoIT extends ESIntegTestCase { NodesInfoResponse response = client().admin().cluster().prepareNodesInfo().execute().actionGet(); - assertThat(response.getNodes().length, is(2)); + assertThat(response.getNodes().size(), is(2)); assertThat(response.getNodesMap().get(server1NodeId), notNullValue()); assertThat(response.getNodesMap().get(server2NodeId), notNullValue()); diff --git a/core/src/test/java/org/elasticsearch/rest/action/cat/RestRecoveryActionTests.java b/core/src/test/java/org/elasticsearch/rest/action/cat/RestRecoveryActionTests.java index 4e8ea3b3eb0..978d226da40 100644 --- a/core/src/test/java/org/elasticsearch/rest/action/cat/RestRecoveryActionTests.java +++ b/core/src/test/java/org/elasticsearch/rest/action/cat/RestRecoveryActionTests.java @@ -127,26 +127,29 @@ public class RestRecoveryActionTests extends ESTestCase { assertNotNull(table); List headers = table.getHeaders(); + assertThat(headers.get(0).value, equalTo("index")); assertThat(headers.get(1).value, equalTo("shard")); assertThat(headers.get(2).value, equalTo("time")); assertThat(headers.get(3).value, equalTo("type")); assertThat(headers.get(4).value, equalTo("stage")); assertThat(headers.get(5).value, equalTo("source_host")); - assertThat(headers.get(6).value, equalTo("target_host")); - assertThat(headers.get(7).value, equalTo("repository")); - assertThat(headers.get(8).value, equalTo("snapshot")); - assertThat(headers.get(9).value, equalTo("files")); - assertThat(headers.get(10).value, equalTo("files_recovered")); - assertThat(headers.get(11).value, equalTo("files_percent")); - assertThat(headers.get(12).value, equalTo("files_total")); - assertThat(headers.get(13).value, equalTo("bytes")); - assertThat(headers.get(14).value, equalTo("bytes_recovered")); - assertThat(headers.get(15).value, equalTo("bytes_percent")); - assertThat(headers.get(16).value, equalTo("bytes_total")); - assertThat(headers.get(17).value, equalTo("translog_ops")); - assertThat(headers.get(18).value, equalTo("translog_ops_recovered")); - assertThat(headers.get(19).value, equalTo("translog_ops_percent")); + assertThat(headers.get(6).value, equalTo("source_node")); + assertThat(headers.get(7).value, equalTo("target_host")); + assertThat(headers.get(8).value, equalTo("target_node")); + assertThat(headers.get(9).value, equalTo("repository")); + assertThat(headers.get(10).value, equalTo("snapshot")); + assertThat(headers.get(11).value, equalTo("files")); + assertThat(headers.get(12).value, equalTo("files_recovered")); + assertThat(headers.get(13).value, equalTo("files_percent")); + assertThat(headers.get(14).value, equalTo("files_total")); + assertThat(headers.get(15).value, equalTo("bytes")); + assertThat(headers.get(16).value, equalTo("bytes_recovered")); + assertThat(headers.get(17).value, equalTo("bytes_percent")); + assertThat(headers.get(18).value, equalTo("bytes_total")); + assertThat(headers.get(19).value, equalTo("translog_ops")); + assertThat(headers.get(20).value, equalTo("translog_ops_recovered")); + assertThat(headers.get(21).value, equalTo("translog_ops_percent")); assertThat(table.getRows().size(), equalTo(successfulShards)); for (int i = 0; i < successfulShards; i++) { @@ -158,24 +161,26 @@ public class RestRecoveryActionTests extends ESTestCase { assertThat(cells.get(3).value, equalTo(state.getType().name().toLowerCase(Locale.ROOT))); assertThat(cells.get(4).value, equalTo(state.getStage().name().toLowerCase(Locale.ROOT))); assertThat(cells.get(5).value, equalTo(state.getSourceNode() == null ? "n/a" : state.getSourceNode().getHostName())); - assertThat(cells.get(6).value, equalTo(state.getTargetNode().getHostName())); + assertThat(cells.get(6).value, equalTo(state.getSourceNode() == null ? "n/a" : state.getSourceNode().getName())); + assertThat(cells.get(7).value, equalTo(state.getTargetNode().getHostName())); + assertThat(cells.get(8).value, equalTo(state.getTargetNode().getName())); assertThat( - cells.get(7).value, + cells.get(9).value, equalTo(state.getRestoreSource() == null ? "n/a" : state.getRestoreSource().snapshotId().getRepository())); assertThat( - cells.get(8).value, + cells.get(10).value, equalTo(state.getRestoreSource() == null ? "n/a" : state.getRestoreSource().snapshotId().getSnapshot())); - assertThat(cells.get(9).value, equalTo(state.getIndex().totalRecoverFiles())); - assertThat(cells.get(10).value, equalTo(state.getIndex().recoveredFileCount())); - assertThat(cells.get(11).value, equalTo(percent(state.getIndex().recoveredFilesPercent()))); - assertThat(cells.get(12).value, equalTo(state.getIndex().totalFileCount())); - assertThat(cells.get(13).value, equalTo(state.getIndex().totalRecoverBytes())); - assertThat(cells.get(14).value, equalTo(state.getIndex().recoveredBytes())); - assertThat(cells.get(15).value, equalTo(percent(state.getIndex().recoveredBytesPercent()))); - assertThat(cells.get(16).value, equalTo(state.getIndex().totalBytes())); - assertThat(cells.get(17).value, equalTo(state.getTranslog().totalOperations())); - assertThat(cells.get(18).value, equalTo(state.getTranslog().recoveredOperations())); - assertThat(cells.get(19).value, equalTo(percent(state.getTranslog().recoveredPercent()))); + assertThat(cells.get(11).value, equalTo(state.getIndex().totalRecoverFiles())); + assertThat(cells.get(12).value, equalTo(state.getIndex().recoveredFileCount())); + assertThat(cells.get(13).value, equalTo(percent(state.getIndex().recoveredFilesPercent()))); + assertThat(cells.get(14).value, equalTo(state.getIndex().totalFileCount())); + assertThat(cells.get(15).value, equalTo(state.getIndex().totalRecoverBytes())); + assertThat(cells.get(16).value, equalTo(state.getIndex().recoveredBytes())); + assertThat(cells.get(17).value, equalTo(percent(state.getIndex().recoveredBytesPercent()))); + assertThat(cells.get(18).value, equalTo(state.getIndex().totalBytes())); + assertThat(cells.get(19).value, equalTo(state.getTranslog().totalOperations())); + assertThat(cells.get(20).value, equalTo(state.getTranslog().recoveredOperations())); + assertThat(cells.get(21).value, equalTo(percent(state.getTranslog().recoveredPercent()))); } } diff --git a/core/src/test/java/org/elasticsearch/rest/util/RestUtilsTests.java b/core/src/test/java/org/elasticsearch/rest/util/RestUtilsTests.java index 065b99ea5ae..a2f9e42fc3c 100644 --- a/core/src/test/java/org/elasticsearch/rest/util/RestUtilsTests.java +++ b/core/src/test/java/org/elasticsearch/rest/util/RestUtilsTests.java @@ -36,6 +36,10 @@ import static org.hamcrest.Matchers.nullValue; */ public class RestUtilsTests extends ESTestCase { + static char randomDelimiter() { + return randomBoolean() ? '&' : ';'; + } + public void testDecodeQueryString() { Map params = new HashMap<>(); @@ -45,7 +49,7 @@ public class RestUtilsTests extends ESTestCase { assertThat(params.get("test"), equalTo("value")); params.clear(); - uri = "something?test=value&test1=value1"; + uri = String.format(Locale.ROOT, "something?test=value%ctest1=value1", randomDelimiter()); RestUtils.decodeQueryString(uri, uri.indexOf('?') + 1, params); assertThat(params.size(), equalTo(2)); assertThat(params.get("test"), equalTo("value")); @@ -70,12 +74,12 @@ public class RestUtilsTests extends ESTestCase { assertThat(params.size(), equalTo(0)); params.clear(); - uri = "something?&"; + uri = String.format(Locale.ROOT, "something?%c", randomDelimiter()); RestUtils.decodeQueryString(uri, uri.indexOf('?') + 1, params); assertThat(params.size(), equalTo(0)); params.clear(); - uri = "something?p=v&&p1=v1"; + uri = String.format(Locale.ROOT, "something?p=v%c%cp1=v1", randomDelimiter(), randomDelimiter()); RestUtils.decodeQueryString(uri, uri.indexOf('?') + 1, params); assertThat(params.size(), equalTo(2)); assertThat(params.get("p"), equalTo("v")); @@ -87,7 +91,7 @@ public class RestUtilsTests extends ESTestCase { assertThat(params.size(), equalTo(0)); params.clear(); - uri = "something?&="; + uri = String.format(Locale.ROOT, "something?%c=", randomDelimiter()); RestUtils.decodeQueryString(uri, uri.indexOf('?') + 1, params); assertThat(params.size(), equalTo(0)); @@ -98,14 +102,14 @@ public class RestUtilsTests extends ESTestCase { assertThat(params.get("a"), equalTo("")); params.clear(); - uri = "something?p=v&a"; + uri = String.format(Locale.ROOT, "something?p=v%ca", randomDelimiter()); RestUtils.decodeQueryString(uri, uri.indexOf('?') + 1, params); assertThat(params.size(), equalTo(2)); assertThat(params.get("a"), equalTo("")); assertThat(params.get("p"), equalTo("v")); params.clear(); - uri = "something?p=v&a&p1=v1"; + uri = String.format(Locale.ROOT, "something?p=v%ca%cp1=v1", randomDelimiter(), randomDelimiter()); RestUtils.decodeQueryString(uri, uri.indexOf('?') + 1, params); assertThat(params.size(), equalTo(3)); assertThat(params.get("a"), equalTo("")); @@ -113,7 +117,7 @@ public class RestUtilsTests extends ESTestCase { assertThat(params.get("p1"), equalTo("v1")); params.clear(); - uri = "something?p=v&a&b&p1=v1"; + uri = String.format(Locale.ROOT, "something?p=v%ca%cb%cp1=v1", randomDelimiter(), randomDelimiter(), randomDelimiter()); RestUtils.decodeQueryString(uri, uri.indexOf('?') + 1, params); assertThat(params.size(), equalTo(4)); assertThat(params.get("a"), equalTo("")); @@ -139,9 +143,15 @@ public class RestUtilsTests extends ESTestCase { Map params = new HashMap<>(); // This is a valid URL - String uri = "example.com/:@-._~!$&'()*+,=;:@-._~!$&'()*+,=:@-._~!$&'()*+,==?/?:@-._~!$'()*+,;=/?:@-._~!$'()*+,;==#/?:@-._~!$&'()*+,;="; + String uri = String.format( + Locale.ROOT, + "example.com/:@-._~!$%c'()*+,=;:@-._~!$%c'()*+,=:@-._~!$%c'()*+,==?/?:@-._~!$'()*+,=/?:@-._~!$'()*+,==#/?:@-._~!$%c'()*+,;=", + randomDelimiter(), + randomDelimiter(), + randomDelimiter(), + randomDelimiter()); RestUtils.decodeQueryString(uri, uri.indexOf('?') + 1, params); - assertThat(params.get("/?:@-._~!$'()* ,;"), equalTo("/?:@-._~!$'()* ,;==")); + assertThat(params.get("/?:@-._~!$'()* ,"), equalTo("/?:@-._~!$'()* ,==")); assertThat(params.size(), equalTo(1)); } diff --git a/core/src/test/java/org/elasticsearch/script/ScriptMetaDataTests.java b/core/src/test/java/org/elasticsearch/script/ScriptMetaDataTests.java index 86c3fe561d6..c934de2dd72 100644 --- a/core/src/test/java/org/elasticsearch/script/ScriptMetaDataTests.java +++ b/core/src/test/java/org/elasticsearch/script/ScriptMetaDataTests.java @@ -34,8 +34,6 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Collections; -import java.util.HashMap; -import java.util.Map; public class ScriptMetaDataTests extends ESTestCase { @@ -79,7 +77,7 @@ public class ScriptMetaDataTests extends ESTestCase { xContentBuilder.startObject(); expected.toXContent(xContentBuilder, new ToXContent.MapParams(Collections.emptyMap())); xContentBuilder.endObject(); - xContentBuilder = shuffleXContent(xContentBuilder, Collections.emptySet()); + xContentBuilder = shuffleXContent(xContentBuilder); XContentParser parser = XContentHelper.createParser(xContentBuilder.bytes()); parser.nextToken(); diff --git a/core/src/test/java/org/elasticsearch/search/DocValueFormatTests.java b/core/src/test/java/org/elasticsearch/search/DocValueFormatTests.java index a936a315b1e..2ca255ea1a3 100644 --- a/core/src/test/java/org/elasticsearch/search/DocValueFormatTests.java +++ b/core/src/test/java/org/elasticsearch/search/DocValueFormatTests.java @@ -19,11 +19,14 @@ package org.elasticsearch.search; +import org.apache.lucene.document.InetAddressPoint; +import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.joda.Joda; +import org.elasticsearch.common.network.InetAddresses; import org.elasticsearch.test.ESTestCase; import org.joda.time.DateTimeZone; @@ -76,4 +79,65 @@ public class DocValueFormatTests extends ESTestCase { assertSame(DocValueFormat.RAW, in.readNamedWriteable(DocValueFormat.class)); } + public void testRawFormat() { + assertEquals("0", DocValueFormat.RAW.format(0)); + assertEquals("-1", DocValueFormat.RAW.format(-1)); + assertEquals("1", DocValueFormat.RAW.format(1)); + + assertEquals("0.0", DocValueFormat.RAW.format(0d)); + assertEquals("0.5", DocValueFormat.RAW.format(.5d)); + assertEquals("-1.0", DocValueFormat.RAW.format(-1d)); + + assertEquals("abc", DocValueFormat.RAW.format(new BytesRef("abc"))); + } + + public void testBooleanFormat() { + assertEquals("false", DocValueFormat.BOOLEAN.format(0)); + assertEquals("true", DocValueFormat.BOOLEAN.format(1)); + } + + public void testIpFormat() { + assertEquals("192.168.1.7", + DocValueFormat.IP.format(new BytesRef(InetAddressPoint.encode(InetAddresses.forString("192.168.1.7"))))); + assertEquals("::1", + DocValueFormat.IP.format(new BytesRef(InetAddressPoint.encode(InetAddresses.forString("::1"))))); + } + + public void testRawParse() { + assertEquals(-1L, DocValueFormat.RAW.parseLong("-1", randomBoolean(), null)); + assertEquals(1L, DocValueFormat.RAW.parseLong("1", randomBoolean(), null)); + // not checking exception messages as they could depend on the JVM + expectThrows(IllegalArgumentException.class, () -> DocValueFormat.RAW.parseLong("", randomBoolean(), null)); + expectThrows(IllegalArgumentException.class, () -> DocValueFormat.RAW.parseLong("abc", randomBoolean(), null)); + + assertEquals(-1d, DocValueFormat.RAW.parseDouble("-1", randomBoolean(), null), 0d); + assertEquals(1d, DocValueFormat.RAW.parseDouble("1", randomBoolean(), null), 0d); + assertEquals(.5, DocValueFormat.RAW.parseDouble("0.5", randomBoolean(), null), 0d); + // not checking exception messages as they could depend on the JVM + expectThrows(IllegalArgumentException.class, () -> DocValueFormat.RAW.parseLong("", randomBoolean(), null)); + expectThrows(IllegalArgumentException.class, () -> DocValueFormat.RAW.parseLong("abc", randomBoolean(), null)); + + assertEquals(new BytesRef("abc"), DocValueFormat.RAW.parseBytesRef("abc")); + } + + public void testBooleanParse() { + assertEquals(0L, DocValueFormat.BOOLEAN.parseLong("false", randomBoolean(), null)); + assertEquals(1L, DocValueFormat.BOOLEAN.parseLong("true", randomBoolean(), null)); + IllegalArgumentException e = expectThrows(IllegalArgumentException.class, + () -> DocValueFormat.BOOLEAN.parseLong("", randomBoolean(), null)); + assertEquals("Cannot parse boolean [], expected either [true] or [false]", e.getMessage()); + e = expectThrows(IllegalArgumentException.class, + () -> DocValueFormat.BOOLEAN.parseLong("0", randomBoolean(), null)); + assertEquals("Cannot parse boolean [0], expected either [true] or [false]", e.getMessage()); + e = expectThrows(IllegalArgumentException.class, + () -> DocValueFormat.BOOLEAN.parseLong("False", randomBoolean(), null)); + assertEquals("Cannot parse boolean [False], expected either [true] or [false]", e.getMessage()); + } + + public void testIPParse() { + assertEquals(new BytesRef(InetAddressPoint.encode(InetAddresses.forString("192.168.1.7"))), + DocValueFormat.IP.parseBytesRef("192.168.1.7")); + assertEquals(new BytesRef(InetAddressPoint.encode(InetAddresses.forString("::1"))), + DocValueFormat.IP.parseBytesRef("::1")); + } } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/BaseAggregationTestCase.java b/core/src/test/java/org/elasticsearch/search/aggregations/BaseAggregationTestCase.java index 329b90058e4..4af87c982e1 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/BaseAggregationTestCase.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/BaseAggregationTestCase.java @@ -223,7 +223,7 @@ public abstract class BaseAggregationTestCase> builder.prettyPrint(); } factoriesBuilder.toXContent(builder, ToXContent.EMPTY_PARAMS); - XContentBuilder shuffled = shuffleXContent(builder, Collections.emptySet()); + XContentBuilder shuffled = shuffleXContent(builder); XContentParser parser = XContentFactory.xContent(shuffled.bytes()).createParser(shuffled.bytes()); QueryParseContext parseContext = new QueryParseContext(queriesRegistry, parser, parseFieldMatcher); assertSame(XContentParser.Token.START_OBJECT, parser.nextToken()); diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/BasePipelineAggregationTestCase.java b/core/src/test/java/org/elasticsearch/search/aggregations/BasePipelineAggregationTestCase.java index daee1782f4b..2acbd919484 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/BasePipelineAggregationTestCase.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/BasePipelineAggregationTestCase.java @@ -225,7 +225,7 @@ public abstract class BasePipelineAggregationTestCase emptyFilter = new BoolQueryBuilder(); + QueryBuilder emptyFilter = new BoolQueryBuilder(); SearchResponse response = client().prepareSearch("idx").addAggregation(filter("tag1", emptyFilter)).execute().actionGet(); assertSearchResponse(response); @@ -120,7 +120,7 @@ public class FilterIT extends ESIntegTestCase { } public void testEmptyFilter() throws Exception { - QueryBuilder emptyFilter = new EmptyQueryBuilder(); + QueryBuilder emptyFilter = new EmptyQueryBuilder(); SearchResponse response = client().prepareSearch("idx").addAggregation(filter("tag1", emptyFilter)).execute().actionGet(); assertSearchResponse(response); diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/FiltersIT.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/FiltersIT.java index 2f076a34eac..fd4db82f2db 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/FiltersIT.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/FiltersIT.java @@ -138,7 +138,7 @@ public class FiltersIT extends ESIntegTestCase { // See NullPointer issue when filters are empty: // https://github.com/elastic/elasticsearch/issues/8438 public void testEmptyFilterDeclarations() throws Exception { - QueryBuilder emptyFilter = new BoolQueryBuilder(); + QueryBuilder emptyFilter = new BoolQueryBuilder(); SearchResponse response = client().prepareSearch("idx") .addAggregation(filters("tags", randomOrder(new KeyedFilter("all", emptyFilter), new KeyedFilter("tag1", termQuery("tag", "tag1"))))) @@ -207,7 +207,7 @@ public class FiltersIT extends ESIntegTestCase { } public void testEmptyFilter() throws Exception { - QueryBuilder emptyFilter = new EmptyQueryBuilder(); + QueryBuilder emptyFilter = new EmptyQueryBuilder(); SearchResponse response = client().prepareSearch("idx").addAggregation(filters("tag1", emptyFilter)).execute().actionGet(); assertSearchResponse(response); @@ -219,7 +219,7 @@ public class FiltersIT extends ESIntegTestCase { } public void testEmptyKeyedFilter() throws Exception { - QueryBuilder emptyFilter = new EmptyQueryBuilder(); + QueryBuilder emptyFilter = new EmptyQueryBuilder(); SearchResponse response = client().prepareSearch("idx").addAggregation(filters("tag1", new KeyedFilter("foo", emptyFilter))) .execute().actionGet(); diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/FiltersTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/FiltersTests.java index 43b76f74ca3..cd2dae53327 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/FiltersTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/FiltersTests.java @@ -42,7 +42,7 @@ public class FiltersTests extends BaseAggregationTestCase[] filters = new QueryBuilder[size]; + QueryBuilder[] filters = new QueryBuilder[size]; for (int i = 0; i < size; i++) { filters[i] = QueryBuilders.termQuery(randomAsciiOfLengthBetween(5, 20), randomAsciiOfLengthBetween(5, 20)); } diff --git a/core/src/test/java/org/elasticsearch/search/functionscore/DecayFunctionScoreIT.java b/core/src/test/java/org/elasticsearch/search/functionscore/DecayFunctionScoreIT.java index 23860883186..83e62072683 100644 --- a/core/src/test/java/org/elasticsearch/search/functionscore/DecayFunctionScoreIT.java +++ b/core/src/test/java/org/elasticsearch/search/functionscore/DecayFunctionScoreIT.java @@ -78,7 +78,7 @@ public class DecayFunctionScoreIT extends ESIntegTestCase { return pluginList(InternalSettingsPlugin.class); // uses index.version.created } - private final QueryBuilder baseQuery = constantScoreQuery(termQuery("test", "value")); + private final QueryBuilder baseQuery = constantScoreQuery(termQuery("test", "value")); public void testDistanceScoreGeoLinGaussExp() throws Exception { assertAcked(prepareCreate("test").addMapping( diff --git a/core/src/test/java/org/elasticsearch/search/functionscore/QueryRescorerIT.java b/core/src/test/java/org/elasticsearch/search/functionscore/QueryRescorerIT.java index f6ef6175530..14d0fc959c3 100644 --- a/core/src/test/java/org/elasticsearch/search/functionscore/QueryRescorerIT.java +++ b/core/src/test/java/org/elasticsearch/search/functionscore/QueryRescorerIT.java @@ -583,7 +583,7 @@ public class QueryRescorerIT extends ESIntegTestCase { String[] intToEnglish = new String[] { English.intToEnglish(i), English.intToEnglish(i + 1), English.intToEnglish(i + 2), English.intToEnglish(i + 3) }; - QueryBuilder query = boolQuery().disableCoord(true) + QueryBuilder query = boolQuery().disableCoord(true) .should(functionScoreQuery(termQuery("field1", intToEnglish[0]), weightFactorFunction(2.0f)).boostMode(REPLACE)) .should(functionScoreQuery(termQuery("field1", intToEnglish[1]), weightFactorFunction(3.0f)).boostMode(REPLACE)) .should(functionScoreQuery(termQuery("field1", intToEnglish[2]), weightFactorFunction(5.0f)).boostMode(REPLACE)) diff --git a/core/src/test/java/org/elasticsearch/search/highlight/HighlightBuilderTests.java b/core/src/test/java/org/elasticsearch/search/highlight/HighlightBuilderTests.java index 5e706d1f509..d5c6bf98835 100644 --- a/core/src/test/java/org/elasticsearch/search/highlight/HighlightBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/search/highlight/HighlightBuilderTests.java @@ -59,7 +59,6 @@ import org.junit.BeforeClass; import java.io.IOException; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -150,7 +149,7 @@ public class HighlightBuilderTests extends ESTestCase { builder.prettyPrint(); } highlightBuilder.toXContent(builder, ToXContent.EMPTY_PARAMS); - XContentBuilder shuffled = shuffleXContent(builder, Collections.emptySet()); + XContentBuilder shuffled = shuffleXContent(builder); XContentParser parser = XContentHelper.createParser(shuffled.bytes()); QueryParseContext context = new QueryParseContext(indicesQueriesRegistry, parser, ParseFieldMatcher.EMPTY); diff --git a/core/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchIT.java b/core/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchIT.java index b56588e1759..869182cb51a 100644 --- a/core/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchIT.java +++ b/core/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchIT.java @@ -19,10 +19,11 @@ package org.elasticsearch.search.highlight; import com.carrotsearch.randomizedtesting.generators.RandomPicks; - +import org.elasticsearch.Version; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings.Builder; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -36,15 +37,18 @@ import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.search.MatchQuery; import org.elasticsearch.index.search.MatchQuery.Type; +import org.elasticsearch.plugins.Plugin; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.highlight.HighlightBuilder.Field; import org.elasticsearch.test.ESIntegTestCase; +import org.elasticsearch.test.InternalSettingsPlugin; import org.hamcrest.Matcher; import org.hamcrest.Matchers; import java.io.IOException; +import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -85,6 +89,12 @@ import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.startsWith; public class HighlighterSearchIT extends ESIntegTestCase { + + @Override + protected Collection> nodePlugins() { + return pluginList(InternalSettingsPlugin.class); + } + public void testHighlightingWithWildcardName() throws IOException { // test the kibana case with * as fieldname that will try highlight all fields including meta fields XContentBuilder mappings = jsonBuilder(); @@ -2542,4 +2552,90 @@ public class HighlighterSearchIT extends ESIntegTestCase { response = search.setQuery(boostingQuery(phrase, terms).boost(1).negativeBoost(1/boost)).get(); assertHighlight(response, 0, "field1", 0, 1, highlightedMatcher); } + + public void testGeoFieldHighlighting() throws IOException { + // check that we do not get an exception for geo_point fields in case someone tries to highlight + // it accidential with a wildcard + // see https://github.com/elastic/elasticsearch/issues/17537 + XContentBuilder mappings = jsonBuilder(); + mappings.startObject(); + mappings.startObject("type") + .startObject("properties") + .startObject("geo_point") + .field("type", "geo_point") + .endObject() + .endObject() + .endObject(); + mappings.endObject(); + assertAcked(prepareCreate("test") + .addMapping("type", mappings)); + ensureYellow(); + + client().prepareIndex("test", "type", "1") + .setSource(jsonBuilder().startObject().field("geo_point", "60.12,100.34").endObject()) + .get(); + refresh(); + SearchResponse search = client().prepareSearch().setSource( + new SearchSourceBuilder().query(QueryBuilders.geoBoundingBoxQuery("geo_point").setCorners(61.10078883158897, -170.15625, + -64.92354174306496, 118.47656249999999)).highlighter(new HighlightBuilder().field("*"))).get(); + assertNoFailures(search); + assertThat(search.getHits().totalHits(), equalTo(1L)); + } + + public void testKeywordFieldHighlighting() throws IOException { + // check that keyword highlighting works + XContentBuilder mappings = jsonBuilder(); + mappings.startObject(); + mappings.startObject("type") + .startObject("properties") + .startObject("keyword_field") + .field("type", "keyword") + .endObject() + .endObject() + .endObject(); + mappings.endObject(); + assertAcked(prepareCreate("test") + .addMapping("type", mappings)); + ensureYellow(); + + client().prepareIndex("test", "type", "1") + .setSource(jsonBuilder().startObject().field("keyword_field", "some text").endObject()) + .get(); + refresh(); + SearchResponse search = client().prepareSearch().setSource( + new SearchSourceBuilder().query(QueryBuilders.matchQuery("keyword_field", "some text")).highlighter(new HighlightBuilder().field("*"))) + .get(); + assertNoFailures(search); + assertThat(search.getHits().totalHits(), equalTo(1L)); + assertThat(search.getHits().getAt(0).getHighlightFields().get("keyword_field").getFragments()[0].string(), equalTo("some text")); + } + + public void testStringFieldHighlighting() throws IOException { + // check that string field highlighting on old indexes works + XContentBuilder mappings = jsonBuilder(); + mappings.startObject(); + mappings.startObject("type") + .startObject("properties") + .startObject("string_field") + .field("type", "string") + .endObject() + .endObject() + .endObject(); + mappings.endObject(); + assertAcked(prepareCreate("test") + .addMapping("type", mappings) + .setSettings(Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_2_3_2))); + ensureYellow(); + + client().prepareIndex("test", "type", "1") + .setSource(jsonBuilder().startObject().field("string_field", "some text").endObject()) + .get(); + refresh(); + SearchResponse search = client().prepareSearch().setSource( + new SearchSourceBuilder().query(QueryBuilders.matchQuery("string_field", "some text")).highlighter(new HighlightBuilder().field("*"))) + .get(); + assertNoFailures(search); + assertThat(search.getHits().totalHits(), equalTo(1L)); + assertThat(search.getHits().getAt(0).getHighlightFields().get("string_field").getFragments()[0].string(), equalTo("some text")); + } } diff --git a/core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java b/core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java index fde0b08974f..d0f2c0492da 100644 --- a/core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java @@ -54,8 +54,6 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import java.io.IOException; -import java.util.Collections; - import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.not; @@ -137,7 +135,7 @@ public class QueryRescoreBuilderTests extends ESTestCase { builder.prettyPrint(); } rescoreBuilder.toXContent(builder, ToXContent.EMPTY_PARAMS); - XContentBuilder shuffled = shuffleXContent(builder, Collections.emptySet()); + XContentBuilder shuffled = shuffleXContent(builder); XContentParser parser = XContentHelper.createParser(shuffled.bytes()); @@ -314,7 +312,7 @@ public class QueryRescoreBuilderTests extends ESTestCase { * create random shape that is put under test */ public static QueryRescorerBuilder randomRescoreBuilder() { - QueryBuilder queryBuilder = new MatchAllQueryBuilder().boost(randomFloat()) + QueryBuilder queryBuilder = new MatchAllQueryBuilder().boost(randomFloat()) .queryName(randomAsciiOfLength(20)); org.elasticsearch.search.rescore.QueryRescorerBuilder rescorer = new org.elasticsearch.search.rescore.QueryRescorerBuilder(queryBuilder); diff --git a/core/src/test/java/org/elasticsearch/search/searchafter/SearchAfterBuilderTests.java b/core/src/test/java/org/elasticsearch/search/searchafter/SearchAfterBuilderTests.java index 14bf8eac7e6..3c675926328 100644 --- a/core/src/test/java/org/elasticsearch/search/searchafter/SearchAfterBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/search/searchafter/SearchAfterBuilderTests.java @@ -41,7 +41,6 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import java.io.IOException; - import static org.hamcrest.Matchers.equalTo; public class SearchAfterBuilderTests extends ESTestCase { @@ -220,8 +219,8 @@ public class SearchAfterBuilderTests extends ESTestCase { builder.startObject(); searchAfterBuilder.innerToXContent(builder); builder.endObject(); - XContentParser parser = XContentHelper.createParser(builder.bytes()); - QueryParseContext context = new QueryParseContext(indicesQueriesRegistry, parser, ParseFieldMatcher.STRICT); + XContentParser parser = XContentHelper.createParser(shuffleXContent(builder).bytes()); + new QueryParseContext(indicesQueriesRegistry, parser, ParseFieldMatcher.STRICT); parser.nextToken(); parser.nextToken(); parser.nextToken(); diff --git a/core/src/test/java/org/elasticsearch/search/searchafter/SearchAfterIT.java b/core/src/test/java/org/elasticsearch/search/searchafter/SearchAfterIT.java index 13c99944959..08c661a130b 100644 --- a/core/src/test/java/org/elasticsearch/search/searchafter/SearchAfterIT.java +++ b/core/src/test/java/org/elasticsearch/search/searchafter/SearchAfterIT.java @@ -25,7 +25,6 @@ import org.elasticsearch.action.search.SearchPhaseExecutionException; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.UUIDs; -import org.elasticsearch.common.text.Text; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.search.SearchContextException; import org.elasticsearch.search.SearchHit; @@ -189,11 +188,11 @@ public class SearchAfterIT extends ESIntegTestCase { values.add(randomDouble()); break; case 6: - values.add(new Text(randomAsciiOfLengthBetween(5, 20))); + values.add(randomAsciiOfLengthBetween(5, 20)); break; } } - values.add(new Text(UUIDs.randomBase64UUID())); + values.add(UUIDs.randomBase64UUID()); documents.add(values); } int reqSize = randomInt(NUM_DOCS-1); @@ -296,7 +295,7 @@ public class SearchAfterIT extends ESIntegTestCase { } else if (type == Boolean.class) { mappings.add("field" + Integer.toString(i)); mappings.add("type=boolean"); - } else if (types.get(i) instanceof Text) { + } else if (types.get(i) instanceof String) { mappings.add("field" + Integer.toString(i)); mappings.add("type=keyword"); } else { diff --git a/core/src/test/java/org/elasticsearch/search/sort/AbstractSortTestCase.java b/core/src/test/java/org/elasticsearch/search/sort/AbstractSortTestCase.java index 76d5eba12f9..3f2bd6e9a56 100644 --- a/core/src/test/java/org/elasticsearch/search/sort/AbstractSortTestCase.java +++ b/core/src/test/java/org/elasticsearch/search/sort/AbstractSortTestCase.java @@ -62,6 +62,7 @@ import org.elasticsearch.script.ScriptEngineRegistry; import org.elasticsearch.script.ScriptService; import org.elasticsearch.script.ScriptServiceTests.TestEngineService; import org.elasticsearch.script.ScriptSettings; +import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.SearchModule; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.IndexSettingsModule; @@ -136,7 +137,7 @@ public abstract class AbstractSortTestCase> extends EST builder.prettyPrint(); } testItem.toXContent(builder, ToXContent.EMPTY_PARAMS); - XContentBuilder shuffled = shuffleXContent(builder, Collections.emptySet()); + XContentBuilder shuffled = shuffleXContent(builder); XContentParser itemParser = XContentHelper.createParser(shuffled.bytes()); itemParser.nextToken(); @@ -163,12 +164,12 @@ public abstract class AbstractSortTestCase> extends EST QueryShardContext mockShardContext = createMockShardContext(); for (int runs = 0; runs < NUMBER_OF_TESTBUILDERS; runs++) { T sortBuilder = createTestItem(); - SortField sortField = sortBuilder.build(mockShardContext); - sortFieldAssertions(sortBuilder, sortField); + SortFieldAndFormat sortField = sortBuilder.build(mockShardContext); + sortFieldAssertions(sortBuilder, sortField.field, sortField.format); } } - protected abstract void sortFieldAssertions(T builder, SortField sortField) throws IOException; + protected abstract void sortFieldAssertions(T builder, SortField sortField, DocValueFormat format) throws IOException; /** * Test serialization and deserialization of the test sort. @@ -256,7 +257,7 @@ public abstract class AbstractSortTestCase> extends EST return doubleFieldType; } - protected static QueryBuilder randomNestedFilter() { + protected static QueryBuilder randomNestedFilter() { int id = randomIntBetween(0, 2); switch(id) { case 0: return (new MatchAllQueryBuilder()).boost(randomFloat()); diff --git a/core/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java b/core/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java index 4b6eb82304a..baaf3ac5d3c 100644 --- a/core/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java @@ -25,6 +25,7 @@ import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.query.QueryParseContext; +import org.elasticsearch.search.DocValueFormat; import java.io.IOException; import java.util.Arrays; @@ -110,7 +111,7 @@ public class FieldSortBuilderTests extends AbstractSortTestCase shuffleProtectedFields() { - return Collections.emptySet(); + protected String[] shuffleProtectedFields() { + return new String[0]; } private SB mutate(SB firstBuilder) throws IOException { diff --git a/core/src/test/java/org/elasticsearch/search/suggest/completion/CompletionSuggesterBuilderTests.java b/core/src/test/java/org/elasticsearch/search/suggest/completion/CompletionSuggesterBuilderTests.java index af728647212..04412d47065 100644 --- a/core/src/test/java/org/elasticsearch/search/suggest/completion/CompletionSuggesterBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/search/suggest/completion/CompletionSuggesterBuilderTests.java @@ -37,14 +37,11 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Set; - import static org.hamcrest.Matchers.containsString; public class CompletionSuggesterBuilderTests extends AbstractSuggestionBuilderTestCase { - private static final Set SHUFFLE_PROTECTED_FIELDS = - Collections.singleton(CompletionSuggestionBuilder.CONTEXTS_FIELD.getPreferredName()); + private static final String[] SHUFFLE_PROTECTED_FIELDS = new String[] {CompletionSuggestionBuilder.CONTEXTS_FIELD.getPreferredName()}; @Override protected CompletionSuggestionBuilder randomSuggestionBuilder() { @@ -113,7 +110,7 @@ public class CompletionSuggesterBuilderTests extends AbstractSuggestionBuilderTe * the equals() test will fail because their {@link BytesReference} representation isn't the same */ @Override - protected Set shuffleProtectedFields() { + protected String[] shuffleProtectedFields() { return SHUFFLE_PROTECTED_FIELDS; } diff --git a/core/src/test/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorTests.java b/core/src/test/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorTests.java index a3a5ea01c33..3fd3850b98a 100644 --- a/core/src/test/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorTests.java +++ b/core/src/test/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorTests.java @@ -35,7 +35,6 @@ import org.elasticsearch.search.suggest.phrase.PhraseSuggestionContext.DirectCan import org.elasticsearch.test.ESTestCase; import java.io.IOException; - import static org.hamcrest.Matchers.equalTo; public class DirectCandidateGeneratorTests extends ESTestCase{ @@ -117,8 +116,7 @@ public class DirectCandidateGeneratorTests extends ESTestCase{ builder.prettyPrint(); } generator.toXContent(builder, ToXContent.EMPTY_PARAMS); - - XContentParser parser = XContentHelper.createParser(builder.bytes()); + XContentParser parser = XContentHelper.createParser(shuffleXContent(builder).bytes()); QueryParseContext context = new QueryParseContext(mockRegistry, parser, ParseFieldMatcher.STRICT); parser.nextToken(); DirectCandidateGeneratorBuilder secondGenerator = DirectCandidateGeneratorBuilder.fromXContent(context); diff --git a/core/src/test/java/org/elasticsearch/search/suggest/phrase/SmoothingModelTestCase.java b/core/src/test/java/org/elasticsearch/search/suggest/phrase/SmoothingModelTestCase.java index 1731ddd7c4f..f167eefa43d 100644 --- a/core/src/test/java/org/elasticsearch/search/suggest/phrase/SmoothingModelTestCase.java +++ b/core/src/test/java/org/elasticsearch/search/suggest/phrase/SmoothingModelTestCase.java @@ -100,7 +100,7 @@ public abstract class SmoothingModelTestCase extends ESTestCase { contentBuilder.startObject(); testModel.innerToXContent(contentBuilder, ToXContent.EMPTY_PARAMS); contentBuilder.endObject(); - XContentParser parser = XContentHelper.createParser(contentBuilder.bytes()); + XContentParser parser = XContentHelper.createParser(shuffleXContent(contentBuilder).bytes()); QueryParseContext context = new QueryParseContext(new IndicesQueriesRegistry(), parser, ParseFieldMatcher.STRICT); parser.nextToken(); // go to start token, real parsing would do that in the outer element parser SmoothingModel parsedModel = fromXContent(context); diff --git a/core/src/test/java/org/elasticsearch/threadpool/SimpleThreadPoolIT.java b/core/src/test/java/org/elasticsearch/threadpool/SimpleThreadPoolIT.java index 95a931d1d54..baf017bc7b9 100644 --- a/core/src/test/java/org/elasticsearch/threadpool/SimpleThreadPoolIT.java +++ b/core/src/test/java/org/elasticsearch/threadpool/SimpleThreadPoolIT.java @@ -168,8 +168,8 @@ public class SimpleThreadPoolIT extends ESIntegTestCase { // Check that node info is correct NodesInfoResponse nodesInfoResponse = client().admin().cluster().prepareNodesInfo().all().execute().actionGet(); - for (int i = 0; i < 2; i++) { - NodeInfo nodeInfo = nodesInfoResponse.getNodes()[i]; + assertEquals(2, nodesInfoResponse.getNodes().size()); + for (NodeInfo nodeInfo : nodesInfoResponse.getNodes()) { boolean found = false; for (ThreadPool.Info info : nodeInfo.getThreadPool()) { if (info.getName().equals(Names.SEARCH)) { diff --git a/core/src/test/java/org/elasticsearch/transport/AbstractSimpleTransportTestCase.java b/core/src/test/java/org/elasticsearch/transport/AbstractSimpleTransportTestCase.java index 45966606d31..f285a1db52e 100644 --- a/core/src/test/java/org/elasticsearch/transport/AbstractSimpleTransportTestCase.java +++ b/core/src/test/java/org/elasticsearch/transport/AbstractSimpleTransportTestCase.java @@ -22,7 +22,6 @@ package org.elasticsearch.transport; import org.elasticsearch.Version; import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.ClusterSettings; @@ -1179,7 +1178,7 @@ public abstract class AbstractSimpleTransportTestCase extends ESTestCase { } try { - serviceB.connectToNodeLight(nodeA, 100); + serviceB.connectToNodeLightAndHandshake(nodeA, 100); fail("exception should be thrown"); } catch (ConnectTransportException e) { // all is well @@ -1239,7 +1238,7 @@ public abstract class AbstractSimpleTransportTestCase extends ESTestCase { } try { - serviceB.connectToNodeLight(nodeA, 100); + serviceB.connectToNodeLightAndHandshake(nodeA, 100); fail("exception should be thrown"); } catch (ConnectTransportException e) { // all is well diff --git a/core/src/test/java/org/elasticsearch/transport/NettyTransportServiceHandshakeTests.java b/core/src/test/java/org/elasticsearch/transport/NettyTransportServiceHandshakeTests.java index b376a55af73..2b0ff6e0c1a 100644 --- a/core/src/test/java/org/elasticsearch/transport/NettyTransportServiceHandshakeTests.java +++ b/core/src/test/java/org/elasticsearch/transport/NettyTransportServiceHandshakeTests.java @@ -109,7 +109,7 @@ public class NettyTransportServiceHandshakeTests extends ESTestCase { test); DiscoveryNode connectedNode = - handleA.transportService.connectToNodeLight( + handleA.transportService.connectToNodeLightAndHandshake( new DiscoveryNode( "", handleB.discoveryNode.getAddress(), @@ -131,7 +131,7 @@ public class NettyTransportServiceHandshakeTests extends ESTestCase { NetworkHandle handleB = startServices("TS_B", settings, Version.CURRENT, new ClusterName("b")); try { - handleA.transportService.connectToNodeLight( + handleA.transportService.connectToNodeLightAndHandshake( new DiscoveryNode( "", handleB.discoveryNode.getAddress(), @@ -154,7 +154,7 @@ public class NettyTransportServiceHandshakeTests extends ESTestCase { startServices("TS_B", settings, VersionUtils.getPreviousVersion(Version.CURRENT.minimumCompatibilityVersion()), test); try { - handleA.transportService.connectToNodeLight( + handleA.transportService.connectToNodeLightAndHandshake( new DiscoveryNode( "", handleB.discoveryNode.getAddress(), @@ -180,7 +180,7 @@ public class NettyTransportServiceHandshakeTests extends ESTestCase { new ClusterName("b") ); - DiscoveryNode connectedNode = handleA.transportService.connectToNodeLight( + DiscoveryNode connectedNode = handleA.transportService.connectToNodeLightAndHandshake( new DiscoveryNode( "", handleB.discoveryNode.getAddress(), diff --git a/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportPublishAddressIT.java b/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportPublishAddressIT.java index 0fceda31664..75faa8c49b4 100644 --- a/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportPublishAddressIT.java +++ b/core/src/test/java/org/elasticsearch/transport/netty/NettyTransportPublishAddressIT.java @@ -67,7 +67,7 @@ public class NettyTransportPublishAddressIT extends ESIntegTestCase { logger.info("--> checking if boundAddress matching publishAddress has same port"); NodesInfoResponse nodesInfoResponse = client().admin().cluster().prepareNodesInfo().get(); - for (NodeInfo nodeInfo : nodesInfoResponse) { + for (NodeInfo nodeInfo : nodesInfoResponse.getNodes()) { BoundTransportAddress boundTransportAddress = nodeInfo.getTransport().getAddress(); if (nodeInfo.getNode().getName().equals(ipv4OnlyNode)) { assertThat(boundTransportAddress.boundAddresses().length, equalTo(1)); diff --git a/distribution/build.gradle b/distribution/build.gradle index bb4cc167f10..2fab35229be 100644 --- a/distribution/build.gradle +++ b/distribution/build.gradle @@ -335,12 +335,13 @@ configure(subprojects.findAll { ['deb', 'rpm'].contains(it.name) }) { configurationFile '/etc/elasticsearch/elasticsearch.yml' configurationFile '/etc/elasticsearch/jvm.options' configurationFile '/etc/elasticsearch/logging.yml' - into('/etc') { - from "${packagingFiles}/etc" + into('/etc/elasticsearch') { fileMode 0750 permissionGroup 'elasticsearch' includeEmptyDirs true createDirectoryEntry true + fileType CONFIG | NOREPLACE + from "${packagingFiles}/etc/elasticsearch" } into('/usr/lib/tmpfiles.d') { @@ -348,21 +349,25 @@ configure(subprojects.findAll { ['deb', 'rpm'].contains(it.name) }) { } configurationFile '/usr/lib/systemd/system/elasticsearch.service' into('/usr/lib/systemd/system') { + fileType CONFIG | NOREPLACE from "${packagingFiles}/systemd/elasticsearch.service" } into('/usr/lib/sysctl.d') { + fileType CONFIG | NOREPLACE from "${packagingFiles}/systemd/sysctl/elasticsearch.conf" } configurationFile '/etc/init.d/elasticsearch' into('/etc/init.d') { - from "${packagingFiles}/init.d/elasticsearch" fileMode 0755 + fileType CONFIG | NOREPLACE + from "${packagingFiles}/init.d/elasticsearch" } configurationFile project.expansions['path.env'] into(new File(project.expansions['path.env']).getParent()) { - from "${project.packagingFiles}/env/elasticsearch" fileMode 0644 dirMode 0755 + fileType CONFIG | NOREPLACE + from "${project.packagingFiles}/env/elasticsearch" } /** diff --git a/distribution/rpm/build.gradle b/distribution/rpm/build.gradle index 0d9f658f488..72ed58e52c3 100644 --- a/distribution/rpm/build.gradle +++ b/distribution/rpm/build.gradle @@ -40,6 +40,7 @@ task buildRpm(type: Rpm) { vendor 'Elasticsearch' dirMode 0755 fileMode 0644 + addParentDirs false // TODO ospackage doesn't support icon but we used to have one } diff --git a/distribution/src/main/packaging/scripts/postrm b/distribution/src/main/packaging/scripts/postrm index d4104845249..2fa42678d96 100644 --- a/distribution/src/main/packaging/scripts/postrm +++ b/distribution/src/main/packaging/scripts/postrm @@ -55,6 +55,7 @@ LOG_DIR="/var/log/elasticsearch" PLUGINS_DIR="/usr/share/elasticsearch/plugins" PID_DIR="/var/run/elasticsearch" DATA_DIR="/var/lib/elasticsearch" +CONF_DIR="/etc/elasticsearch" # Source the default env file if [ "$SOURCE_ENV_FILE" = "true" ]; then @@ -102,6 +103,12 @@ if [ "$REMOVE_DIRS" = "true" ]; then if [ -d "$DATA_DIR" ]; then rmdir --ignore-fail-on-non-empty "$DATA_DIR" fi + + # delete the conf directory if and only if empty + if [ -d "$CONF_DIR" ]; then + rmdir --ignore-fail-on-non-empty "$CONF_DIR" + fi + fi if [ "$REMOVE_USER_AND_GROUP" = "true" ]; then diff --git a/distribution/src/main/packaging/scripts/prerm b/distribution/src/main/packaging/scripts/prerm index 07f39759aee..79523629f77 100644 --- a/distribution/src/main/packaging/scripts/prerm +++ b/distribution/src/main/packaging/scripts/prerm @@ -64,4 +64,10 @@ if [ "$STOP_REQUIRED" = "true" ]; then echo " OK" fi +SCRIPTS_DIR="/etc/elasticsearch/scripts" +# delete the scripts directory if and only if empty +if [ -d "$SCRIPTS_DIR" ]; then + rmdir --ignore-fail-on-non-empty "$SCRIPTS_DIR" +fi + ${scripts.footer} diff --git a/distribution/src/main/resources/bin/elasticsearch b/distribution/src/main/resources/bin/elasticsearch index 2f62223cfe9..0101a108d4b 100755 --- a/distribution/src/main/resources/bin/elasticsearch +++ b/distribution/src/main/resources/bin/elasticsearch @@ -72,7 +72,7 @@ if test -n "$ES_MIN_MEM" || echo "Error: encountered environment variables that are no longer supported" echo "Use jvm.options or ES_JAVA_OPTS to configure the JVM" unsupported_environment_variable "$ES_MIN_MEM" ES_MIN_MEM "set -Xms$ES_MIN_MEM in jvm.options or add \"-Xms$ES_MIN_MEM\" to ES_JAVA_OPTS" - unsupported_environment_variable "$ES_MAX_MEM" ES_MAX_MEM "set -Xms$ES_MAX_MEM in jvm.options or add \"-Xms$ES_MAX_MEM\" to ES_JAVA_OPTS" + unsupported_environment_variable "$ES_MAX_MEM" ES_MAX_MEM "set -Xmx$ES_MAX_MEM in jvm.options or add \"-Xmx$ES_MAX_MEM\" to ES_JAVA_OPTS" unsupported_environment_variable "$ES_HEAP_SIZE" ES_HEAP_SIZE "set -Xms$ES_HEAP_SIZE and -Xmx$ES_HEAP_SIZE in jvm.options or add \"-Xms$ES_HEAP_SIZE -Xmx$ES_HEAP_SIZE\" to ES_JAVA_OPTS" unsupported_environment_variable "$ES_HEAP_NEWSIZE" ES_HEAP_NEWSIZE "set -Xmn$ES_HEAP_NEWSIZE in jvm.options or add \"-Xmn$ES_HEAP_SIZE\" to ES_JAVA_OPTS" unsupported_environment_variable "$ES_DIRECT_SIZE" ES_DIRECT_SIZE "set -XX:MaxDirectMemorySize=$ES_DIRECT_SIZE in jvm.options or add \"-XX:MaxDirectMemorySize=$ES_DIRECT_SIZE\" to ES_JAVA_OPTS" diff --git a/distribution/src/main/resources/bin/elasticsearch.bat b/distribution/src/main/resources/bin/elasticsearch.bat index 3a9d561e2e3..9f1d871d0a2 100644 --- a/distribution/src/main/resources/bin/elasticsearch.bat +++ b/distribution/src/main/resources/bin/elasticsearch.bat @@ -19,7 +19,7 @@ if %bad_env_var% == 1 ( echo Error: encountered environment variables that are no longer supported echo Use jvm.options or ES_JAVA_OPTS to configure the JVM if not "%ES_MIN_MEM%" == "" echo ES_MIN_MEM=%ES_MIN_MEM%: set -Xms%ES_MIN_MEM% in jvm.options or add "-Xms%ES_MIN_MEM%" to ES_JAVA_OPTS - if not "%ES_MAX_MEM%" == "" echo ES_MAX_MEM=%ES_MAX_MEM%: set -Xms%ES_MAX_MEM% in jvm.options or add "-Xmx%ES_MAX_MEM%" to ES_JAVA_OPTS + if not "%ES_MAX_MEM%" == "" echo ES_MAX_MEM=%ES_MAX_MEM%: set -Xmx%ES_MAX_MEM% in jvm.options or add "-Xmx%ES_MAX_MEM%" to ES_JAVA_OPTS if not "%ES_HEAP_SIZE%" == "" echo ES_HEAP_SIZE=%ES_HEAP_SIZE%: set -Xms%ES_HEAP_SIZE% and -Xmx%ES_HEAP_SIZE% in jvm.options or add "-Xms%ES_HEAP_SIZE% -Xmx%ES_HEAP_SIZE%" to ES_JAVA_OPTS if not "%ES_HEAP_NEWSIZE%" == "" echo ES_HEAP_NEWSIZE=%ES_HEAP_NEWSIZE%: set -Xmn%ES_HEAP_NEWSIZE% in jvm.options or add "-Xmn%ES_HEAP_SIZE%" to ES_JAVA_OPTS if not "%ES_DIRECT_SIZE%" == "" echo ES_DIRECT_SIZE=%ES_DIRECT_SIZE%: set -XX:MaxDirectMemorySize=%ES_DIRECT_SIZE% in jvm.options or add "-XX:MaxDirectMemorySize=%ES_DIRECT_SIZE%" to ES_JAVA_OPTS diff --git a/docs/reference/cat/recovery.asciidoc b/docs/reference/cat/recovery.asciidoc index b9a16b2913d..6fe748096d1 100644 --- a/docs/reference/cat/recovery.asciidoc +++ b/docs/reference/cat/recovery.asciidoc @@ -15,12 +15,12 @@ are no shards in transit from one node to another: [source,sh] ---------------------------------------------------------------------------- > curl -XGET 'localhost:9200/_cat/recovery?v' -index shard time type stage source_host target_host repository snapshot files files_percent bytes bytes_percent total_files total_bytes translog translog_percent total_translog -index 0 87ms store done 127.0.0.1 127.0.0.1 n/a n/a 0 0.0% 0 0.0% 0 0 0 100.0% 0 -index 1 97ms store done 127.0.0.1 127.0.0.1 n/a n/a 0 0.0% 0 0.0% 0 0 0 100.0% 0 -index 2 93ms store done 127.0.0.1 127.0.0.1 n/a n/a 0 0.0% 0 0.0% 0 0 0 100.0% 0 -index 3 90ms store done 127.0.0.1 127.0.0.1 n/a n/a 0 0.0% 0 0.0% 0 0 0 100.0% 0 -index 4 9ms store done 127.0.0.1 127.0.0.1 n/a n/a 0 0.0% 0 0.0% 0 0 0 100.0% 0 +index shard time type stage source_host source_node target_host target_node repository snapshot files files_percent bytes bytes_percent total_files total_bytes translog translog_percent total_translog +index 0 87ms store done 127.0.0.1 Athena 127.0.0.1 Athena n/a n/a 0 0.0% 0 0.0% 0 0 0 100.0% 0 +index 1 97ms store done 127.0.0.1 Athena 127.0.0.1 Athena n/a n/a 0 0.0% 0 0.0% 0 0 0 100.0% 0 +index 2 93ms store done 127.0.0.1 Athena 127.0.0.1 Athena n/a n/a 0 0.0% 0 0.0% 0 0 0 100.0% 0 +index 3 90ms store done 127.0.0.1 Athena 127.0.0.1 Athena n/a n/a 0 0.0% 0 0.0% 0 0 0 100.0% 0 +index 4 9ms store done 127.0.0.1 Athena 127.0.0.1 Athena n/a n/a 0 0.0% 0 0.0% 0 0 0 100.0% 0 --------------------------------------------------------------------------- In the above case, the source and target nodes are the same because the recovery diff --git a/docs/reference/mapping/fields/parent-field.asciidoc b/docs/reference/mapping/fields/parent-field.asciidoc index c15a7bcd3b9..78ce1ebfd00 100644 --- a/docs/reference/mapping/fields/parent-field.asciidoc +++ b/docs/reference/mapping/fields/parent-field.asciidoc @@ -81,7 +81,7 @@ GET my_index/_search }, "script_fields": { "parent": { - "script": "doc['_parent']" <4> + "script": "doc['_parent']" <3> } } } diff --git a/docs/reference/mapping/fields/routing-field.asciidoc b/docs/reference/mapping/fields/routing-field.asciidoc index 496d8dcf56e..c90a52aab37 100644 --- a/docs/reference/mapping/fields/routing-field.asciidoc +++ b/docs/reference/mapping/fields/routing-field.asciidoc @@ -42,7 +42,7 @@ GET my_index/_search }, "script_fields": { "Routing value": { - "script": "doc['_routing']" <4> + "script": "doc['_routing']" <2> } } } diff --git a/docs/reference/mapping/fields/type-field.asciidoc b/docs/reference/mapping/fields/type-field.asciidoc index 8a569d22f53..a1d48129f5d 100644 --- a/docs/reference/mapping/fields/type-field.asciidoc +++ b/docs/reference/mapping/fields/type-field.asciidoc @@ -1,4 +1,4 @@ -\[[mapping-type-field]] +[[mapping-type-field]] === `_type` field Each document indexed is associated with a <> (see diff --git a/docs/reference/mapping/params/analyzer.asciidoc b/docs/reference/mapping/params/analyzer.asciidoc index 5f564f9a668..b2138794546 100644 --- a/docs/reference/mapping/params/analyzer.asciidoc +++ b/docs/reference/mapping/params/analyzer.asciidoc @@ -41,7 +41,7 @@ in the field mapping, as follows: [source,js] -------------------------------------------------- -PUT my_index +PUT /my_index { "mappings": { "my_type": { @@ -60,6 +60,8 @@ PUT my_index } } +GET _cluster/health?wait_for_status=yellow + GET my_index/_analyze?field=text <3> { "text": "The quick Brown Foxes." diff --git a/docs/reference/migration/migrate_5_0/java.asciidoc b/docs/reference/migration/migrate_5_0/java.asciidoc index d2bdf5528ac..cdc471d19f2 100644 --- a/docs/reference/migration/migrate_5_0/java.asciidoc +++ b/docs/reference/migration/migrate_5_0/java.asciidoc @@ -270,6 +270,10 @@ at call time which results in much clearer errors. All `extraSource` methods have been removed. +==== SearchResponse + +Sort values for `string` fields are now return as `java.lang.String` objects rather than `org.elasticsearch.common.text.Text`. + ==== AggregationBuilder All methods which take an `XContentBuilder`, `BytesReference` `Map` or `bytes[]` have been removed in favor of providing the @@ -279,20 +283,20 @@ requests can now be validated at call time which results in much clearer errors. ==== ValidateQueryRequest `source(QuerySourceBuilder)`, `source(Map)`, `source(XContentBuilder)`, `source(String)`, `source(byte[])`, `source(byte[], int, int)`, -`source(BytesReference)` and `source()` have been removed in favor of using `query(QueryBuilder)` and `query()` +`source(BytesReference)` and `source()` have been removed in favor of using `query(QueryBuilder)` and `query()` ==== ValidateQueryRequestBuilder -`setSource()` methods have been removed in favor of using `setQuery(QueryBuilder)` +`setSource()` methods have been removed in favor of using `setQuery(QueryBuilder)` ==== ExplainRequest `source(QuerySourceBuilder)`, `source(Map)`, `source(BytesReference)` and `source()` have been removed in favor of using -`query(QueryBuilder)` and `query()` +`query(QueryBuilder)` and `query()` ==== ExplainRequestBuilder -The `setQuery(BytesReference)` method have been removed in favor of using `setQuery(QueryBuilder)` +The `setQuery(BytesReference)` method have been removed in favor of using `setQuery(QueryBuilder)` === ClusterStatsResponse diff --git a/docs/reference/modules/scripting/groovy.asciidoc b/docs/reference/modules/scripting/groovy.asciidoc index 60b64e0131a..0c7f4676d2c 100644 --- a/docs/reference/modules/scripting/groovy.asciidoc +++ b/docs/reference/modules/scripting/groovy.asciidoc @@ -31,9 +31,6 @@ on the underlying field type): `doc['field_name'].empty`:: A boolean indicating if the field has no values within the doc. -`doc['field_name'].multiValued`:: - A boolean indicating that the field has several values within the corpus. - `doc['field_name'].lat`:: The latitude of a geo point type, or `null`. diff --git a/docs/reference/modules/scripting/painless.asciidoc b/docs/reference/modules/scripting/painless.asciidoc index 98cb052d7a3..b8c4c2cc81f 100644 --- a/docs/reference/modules/scripting/painless.asciidoc +++ b/docs/reference/modules/scripting/painless.asciidoc @@ -115,9 +115,8 @@ GET hockey/_search ---------------------------------------------------------------- // AUTOSENSE -You must always specify the index of the field value you want, even if there's only a single item in the field. -All fields in Elasticsearch are multi-valued and Painless does not provide a `.value` shortcut. The following example uses a Painless script to sort the players by their combined first and last names. The names are accessed using -`input.doc['first'].0` and `input.doc['last'].0`. +The following example uses a Painless script to sort the players by their combined first and last names. The names are accessed using +`input.doc['first'].value` and `input.doc['last'].value`. [source,js] ---------------------------------------------------------------- @@ -132,7 +131,7 @@ GET hockey/_search "order": "asc", "script": { "lang": "painless", - "inline": "input.doc['first'].0 + ' ' + input.doc['last'].0" + "inline": "input.doc['first'].value + ' ' + input.doc['last'].value" } } } @@ -218,7 +217,7 @@ GET hockey/_search "full_name_dynamic": { "script": { "lang": "painless", - "inline": "def first = input.doc['first'].0; def last = input.doc['last'].0; return first + ' ' + last;" + "inline": "def first = input.doc['first'].value; def last = input.doc['last'].value; return first + ' ' + last;" } }, "full_name_static": { diff --git a/docs/reference/search/request/highlighting.asciidoc b/docs/reference/search/request/highlighting.asciidoc index bce9f13ab26..53d6e23fa80 100644 --- a/docs/reference/search/request/highlighting.asciidoc +++ b/docs/reference/search/request/highlighting.asciidoc @@ -35,7 +35,10 @@ be used for highlighting if it mapped to have `store` set to `true`. ================================== The field name supports wildcard notation. For example, using `comment_*` -will cause all fields that match the expression to be highlighted. +will cause all <> and <> fields (and <> +from versions before 5.0) that match the expression to be highlighted. +Note that all other fields will not be highlighted. If you use a custom mapper and want to +highlight on a field anyway, you have to provide the field name explicitly. [[plain-highlighter]] ==== Plain highlighter diff --git a/docs/reference/setup/install/deb.asciidoc b/docs/reference/setup/install/deb.asciidoc index b327dc4a85f..9c7a043bdd5 100644 --- a/docs/reference/setup/install/deb.asciidoc +++ b/docs/reference/setup/install/deb.asciidoc @@ -33,7 +33,7 @@ Save the repository definition to +/etc/apt/sources.list.d/elasticsearch-{major ["source","sh",subs="attributes,callouts"] -------------------------------------------------- -echo "deb http://packages.elastic.co/elasticsearch/{major-version}/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-{major-version}.list +echo "deb https://packages.elastic.co/elasticsearch/{major-version}/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-{major-version}.list -------------------------------------------------- [WARNING] @@ -63,7 +63,7 @@ If two entries exist for the same Elasticsearch repository, you will see an erro ["literal",subs="attributes,callouts"] -Duplicate sources.list entry http://packages.elastic.co/elasticsearch/{major-version}/debian/ ...` +Duplicate sources.list entry https://packages.elastic.co/elasticsearch/{major-version}/debian/ ...` Examine +/etc/apt/sources.list.d/elasticsearch-{major-version}.list+ for the duplicate entry or locate the duplicate entry amongst the files in `/etc/apt/sources.list.d/` and the `/etc/apt/sources.list` file. ================================================== @@ -188,4 +188,4 @@ locations for a Debian-based system: |======================================================================= -include::next-steps.asciidoc[] \ No newline at end of file +include::next-steps.asciidoc[] diff --git a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/MinDocCountTests.java b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/MinDocCountTests.java index e00ac3320d1..1c17c1966e5 100644 --- a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/MinDocCountTests.java +++ b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/MinDocCountTests.java @@ -68,7 +68,7 @@ public class MinDocCountTests extends AbstractTermsTestCase { return Collections.singleton(GroovyPlugin.class); } - private static final QueryBuilder QUERY = QueryBuilders.termQuery("match", true); + private static final QueryBuilder QUERY = QueryBuilders.termQuery("match", true); private static int cardinality; diff --git a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SearchStatsTests.java b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SearchStatsTests.java index 95a2691d1c4..52b2f5af797 100644 --- a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SearchStatsTests.java +++ b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SearchStatsTests.java @@ -130,10 +130,10 @@ public class SearchStatsTests extends ESIntegTestCase { assertThat(indicesStats.getTotal().getSearch().getGroupStats().get("group1").getFetchCount(), greaterThan(0L)); assertThat(indicesStats.getTotal().getSearch().getGroupStats().get("group1").getFetchTimeInMillis(), greaterThan(0L)); NodesStatsResponse nodeStats = client().admin().cluster().prepareNodesStats().execute().actionGet(); - NodeStats[] nodes = nodeStats.getNodes(); + Set nodeIdsWithIndex = nodeIdsWithIndex("test1", "test2"); int num = 0; - for (NodeStats stat : nodes) { + for (NodeStats stat : nodeStats.getNodes()) { Stats total = stat.getIndices().getSearch().getTotal(); if (nodeIdsWithIndex.contains(stat.getNode().getId())) { assertThat(total.getQueryCount(), greaterThan(0L)); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java index 4e170c93e49..136746026fa 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java @@ -19,6 +19,7 @@ package org.elasticsearch.painless; +import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.painless.Definition.Cast; import org.elasticsearch.painless.Definition.Field; import org.elasticsearch.painless.Definition.Method; @@ -119,9 +120,22 @@ public class Def { @SuppressWarnings("rawtypes") public static Object fieldLoad(final Object owner, final String name, final Definition definition) { - if (owner.getClass().isArray() && "length".equals(name)) { + final Class clazz = owner.getClass(); + if (clazz.isArray() && "length".equals(name)) { return Array.getLength(owner); } else { + // TODO: remove this fast-path, once we speed up dynamics some more + if ("value".equals(name) && owner instanceof ScriptDocValues) { + if (clazz == ScriptDocValues.Doubles.class) { + return ((ScriptDocValues.Doubles)owner).getValue(); + } else if (clazz == ScriptDocValues.Longs.class) { + return ((ScriptDocValues.Longs)owner).getValue(); + } else if (clazz == ScriptDocValues.Strings.class) { + return ((ScriptDocValues.Strings)owner).getValue(); + } else if (clazz == ScriptDocValues.GeoPoints.class) { + return ((ScriptDocValues.GeoPoints)owner).getValue(); + } + } final Field field = getField(owner, name, definition); MethodHandle handle; @@ -143,7 +157,7 @@ public class Def { } } else { throw new IllegalArgumentException("Unable to find dynamic field [" + name + "] " + - "for class [" + owner.getClass().getCanonicalName() + "]."); + "for class [" + clazz.getCanonicalName() + "]."); } } else { handle = field.getter; @@ -151,13 +165,13 @@ public class Def { if (handle == null) { throw new IllegalArgumentException( - "Unable to read from field [" + name + "] with owner class [" + owner.getClass() + "]."); + "Unable to read from field [" + name + "] with owner class [" + clazz + "]."); } else { try { return handle.invoke(owner); } catch (final Throwable throwable) { throw new IllegalArgumentException("Error loading value from " + - "field [" + name + "] with owner class [" + owner.getClass() + "].", throwable); + "field [" + name + "] with owner class [" + clazz + "].", throwable); } } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java index 450f2aa6fa4..5a0e0c1e636 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java @@ -33,6 +33,9 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.elasticsearch.common.geo.GeoPoint; +import org.elasticsearch.index.fielddata.ScriptDocValues; + class Definition { enum Sort { VOID( void.class , 0 , true , false , false , false ), @@ -393,6 +396,14 @@ class Definition { final Type iargexcepType; final Type istateexceptType; final Type nfexcepType; + + // docvalues accessors + final Type geoPointType; + final Type stringsType; + // TODO: add ReadableDateTime? or don't expose the joda stuff? + final Type longsType; + final Type doublesType; + final Type geoPointsType; public Definition() { structs = new HashMap<>(); @@ -471,6 +482,12 @@ class Definition { istateexceptType = getType("IllegalStateException"); nfexcepType = getType("NumberFormatException"); + geoPointType = getType("GeoPoint"); + stringsType = getType("Strings"); + longsType = getType("Longs"); + doublesType = getType("Doubles"); + geoPointsType = getType("GeoPoints"); + addDefaultElements(); copyDefaultStructs(); addDefaultTransforms(); @@ -564,6 +581,12 @@ class Definition { iargexcepType = definition.iargexcepType; istateexceptType = definition.istateexceptType; nfexcepType = definition.nfexcepType; + + geoPointType = definition.geoPointType; + stringsType = definition.stringsType; + longsType = definition.longsType; + doublesType = definition.doublesType; + geoPointsType = definition.geoPointsType; } private void addDefaultStructs() { @@ -634,6 +657,12 @@ class Definition { addStruct( "IllegalArgumentException" , IllegalArgumentException.class); addStruct( "IllegalStateException" , IllegalStateException.class); addStruct( "NumberFormatException" , NumberFormatException.class); + + addStruct( "GeoPoint" , GeoPoint.class); + addStruct( "Strings" , ScriptDocValues.Strings.class); + addStruct( "Longs" , ScriptDocValues.Longs.class); + addStruct( "Doubles" , ScriptDocValues.Doubles.class); + addStruct( "GeoPoints" , ScriptDocValues.GeoPoints.class); } private void addDefaultClasses() { @@ -670,6 +699,12 @@ class Definition { addClass("HashMap"); addClass("Exception"); + + addClass("GeoPoint"); + addClass("Strings"); + addClass("Longs"); + addClass("Doubles"); + addClass("GeoPoints"); } private void addDefaultElements() { @@ -1032,6 +1067,61 @@ class Definition { addConstructor("IllegalStateException", "new", new Type[] {stringType}, null); addConstructor("NumberFormatException", "new", new Type[] {stringType}, null); + + addMethod("GeoPoint", "getLat", null, false, doubleType, new Type[] {}, null, null); + addMethod("GeoPoint", "getLon", null, false, doubleType, new Type[] {}, null, null); + addMethod("Strings", "getValue", null, false, stringType, new Type[] {}, null, null); + addMethod("Strings", "getValues", null, false, slistType, new Type[] {}, null, null); + addMethod("Longs", "getValue", null, false, longType, new Type[] {}, null, null); + addMethod("Longs", "getValues", null, false, olistType, new Type[] {}, null, null); + // TODO: add better date support for Longs here? (carefully?) + addMethod("Doubles", "getValue", null, false, doubleType, new Type[] {}, null, null); + addMethod("Doubles", "getValues", null, false, olistType, new Type[] {}, null, null); + addMethod("GeoPoints", "getValue", null, false, geoPointType, new Type[] {}, null, null); + addMethod("GeoPoints", "getValues", null, false, olistType, new Type[] {}, null, null); + addMethod("GeoPoints", "getLat", null, false, doubleType, new Type[] {}, null, null); + addMethod("GeoPoints", "getLon", null, false, doubleType, new Type[] {}, null, null); + addMethod("GeoPoints", "getLats", null, false, getType(doubleType.struct, 1), new Type[] {}, null, null); + addMethod("GeoPoints", "getLons", null, false, getType(doubleType.struct, 1), new Type[] {}, null, null); + // geo distance functions... so many... + addMethod("GeoPoints", "factorDistance", null, false, doubleType, + new Type[] { doubleType, doubleType }, null, null); + addMethod("GeoPoints", "factorDistanceWithDefault", null, false, doubleType, + new Type[] { doubleType, doubleType, doubleType }, null, null); + addMethod("GeoPoints", "factorDistance02", null, false, doubleType, + new Type[] { doubleType, doubleType }, null, null); + addMethod("GeoPoints", "factorDistance13", null, false, doubleType, + new Type[] { doubleType, doubleType }, null, null); + addMethod("GeoPoints", "arcDistance", null, false, doubleType, + new Type[] { doubleType, doubleType }, null, null); + addMethod("GeoPoints", "arcDistanceWithDefault", null, false, doubleType, + new Type[] { doubleType, doubleType, doubleType }, null, null); + addMethod("GeoPoints", "arcDistanceInKm", null, false, doubleType, + new Type[] { doubleType, doubleType }, null, null); + addMethod("GeoPoints", "arcDistanceInKmWithDefault", null, false, doubleType, + new Type[] { doubleType, doubleType, doubleType }, null, null); + addMethod("GeoPoints", "arcDistanceInMiles", null, false, doubleType, + new Type[] { doubleType, doubleType }, null, null); + addMethod("GeoPoints", "arcDistanceInMilesWithDefault", null, false, doubleType, + new Type[] { doubleType, doubleType, doubleType }, null, null); + addMethod("GeoPoints", "distance", null, false, doubleType, + new Type[] { doubleType, doubleType }, null, null); + addMethod("GeoPoints", "distanceWithDefault", null, false, doubleType, + new Type[] { doubleType, doubleType, doubleType }, null, null); + addMethod("GeoPoints", "distanceInKm", null, false, doubleType, + new Type[] { doubleType, doubleType }, null, null); + addMethod("GeoPoints", "distanceInKmWithDefault", null, false, doubleType, + new Type[] { doubleType, doubleType, doubleType }, null, null); + addMethod("GeoPoints", "distanceInMiles", null, false, doubleType, + new Type[] { doubleType, doubleType }, null, null); + addMethod("GeoPoints", "distanceInMilesWithDefault", null, false, doubleType, + new Type[] { doubleType, doubleType, doubleType }, null, null); + addMethod("GeoPoints", "geohashDistance", null, false, doubleType, + new Type[] { stringType }, null, null); + addMethod("GeoPoints", "geohashDistanceInKm", null, false, doubleType, + new Type[] { stringType }, null, null); + addMethod("GeoPoints", "geohashDistanceInMiles", null, false, doubleType, + new Type[] { stringType }, null, null); } private void copyDefaultStructs() { @@ -1079,6 +1169,12 @@ class Definition { copyStruct("IllegalArgumentException", "Exception", "Object"); copyStruct("IllegalStateException", "Exception", "Object"); copyStruct("NumberFormatException", "Exception", "Object"); + + copyStruct("GeoPoint", "Object"); + copyStruct("Strings", "List", "Collection", "Object"); + copyStruct("Longs", "List", "Collection", "Object"); + copyStruct("Doubles", "List", "Collection", "Object"); + copyStruct("GeoPoints", "List", "Collection", "Object"); } private void addDefaultTransforms() { diff --git a/modules/lang-painless/src/test/resources/rest-api-spec/test/plan_a/20_scriptfield.yaml b/modules/lang-painless/src/test/resources/rest-api-spec/test/plan_a/20_scriptfield.yaml index d53306b5d47..a1087f17d4e 100644 --- a/modules/lang-painless/src/test/resources/rest-api-spec/test/plan_a/20_scriptfield.yaml +++ b/modules/lang-painless/src/test/resources/rest-api-spec/test/plan_a/20_scriptfield.yaml @@ -28,7 +28,7 @@ setup: script_fields: bar: script: - inline: "input.doc['foo'].0 + input.x;" + inline: "input.doc['foo'].value + input.x;" lang: painless params: x: "bbb" diff --git a/modules/lang-painless/src/test/resources/rest-api-spec/test/plan_a/30_search.yaml b/modules/lang-painless/src/test/resources/rest-api-spec/test/plan_a/30_search.yaml index 2dd1a6004ff..4a1ec86a267 100644 --- a/modules/lang-painless/src/test/resources/rest-api-spec/test/plan_a/30_search.yaml +++ b/modules/lang-painless/src/test/resources/rest-api-spec/test/plan_a/30_search.yaml @@ -29,12 +29,12 @@ query: script: script: - inline: "input.doc['num1'].0 > 1;" + inline: "input.doc['num1'].value > 1;" lang: painless script_fields: sNum1: script: - inline: "input.doc['num1'].0;" + inline: "input.doc['num1'].value;" lang: painless sort: num1: @@ -51,7 +51,7 @@ query: script: script: - inline: "input.doc['num1'].0 > input.param1;" + inline: "input.doc['num1'].value > input.param1;" lang: painless params: param1: 1 @@ -59,7 +59,7 @@ script_fields: sNum1: script: - inline: "return input.doc['num1'].0;" + inline: "return input.doc['num1'].value;" lang: painless sort: num1: @@ -76,7 +76,7 @@ query: script: script: - inline: "input.doc['num1'].0 > input.param1;" + inline: "input.doc['num1'].value > input.param1;" lang: painless params: param1: -1 @@ -84,7 +84,7 @@ script_fields: sNum1: script: - inline: "input.doc['num1'].0;" + inline: "input.doc['num1'].value;" lang: painless sort: num1: diff --git a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/AbstractBulkByScrollRequestBuilder.java b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/AbstractBulkByScrollRequestBuilder.java index e93a7ba7e42..c158a7669d2 100644 --- a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/AbstractBulkByScrollRequestBuilder.java +++ b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/AbstractBulkByScrollRequestBuilder.java @@ -62,7 +62,7 @@ public abstract class AbstractBulkByScrollRequestBuilder< * Set the query that will filter the source. Just a convenience method for * easy chaining. */ - public Self filter(QueryBuilder filter) { + public Self filter(QueryBuilder filter) { source.setQuery(filter); return self(); } diff --git a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexParentChildTests.java b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexParentChildTests.java index c2f0b5625d8..45bacbcf13a 100644 --- a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexParentChildTests.java +++ b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexParentChildTests.java @@ -32,9 +32,9 @@ import static org.hamcrest.Matchers.equalTo; * Index-by-search tests for parent/child. */ public class ReindexParentChildTests extends ReindexTestCase { - QueryBuilder findsCountry; - QueryBuilder findsCity; - QueryBuilder findsNeighborhood; + QueryBuilder findsCountry; + QueryBuilder findsCity; + QueryBuilder findsNeighborhood; public void testParentChild() throws Exception { createParentChildIndex("source"); diff --git a/plugins/delete-by-query/src/main/java/org/elasticsearch/action/deletebyquery/DeleteByQueryRequest.java b/plugins/delete-by-query/src/main/java/org/elasticsearch/action/deletebyquery/DeleteByQueryRequest.java index 145ef690dc3..682fec46c3b 100644 --- a/plugins/delete-by-query/src/main/java/org/elasticsearch/action/deletebyquery/DeleteByQueryRequest.java +++ b/plugins/delete-by-query/src/main/java/org/elasticsearch/action/deletebyquery/DeleteByQueryRequest.java @@ -69,7 +69,7 @@ public class DeleteByQueryRequest extends ActionRequest im private String[] types = Strings.EMPTY_ARRAY; - private QueryBuilder query; + private QueryBuilder query; private String routing; @@ -132,11 +132,11 @@ public class DeleteByQueryRequest extends ActionRequest im return this; } - public QueryBuilder query() { + public QueryBuilder query() { return query; } - public DeleteByQueryRequest query(QueryBuilder queryBuilder) { + public DeleteByQueryRequest query(QueryBuilder queryBuilder) { this.query = queryBuilder; return this; } diff --git a/plugins/delete-by-query/src/main/java/org/elasticsearch/action/deletebyquery/DeleteByQueryRequestBuilder.java b/plugins/delete-by-query/src/main/java/org/elasticsearch/action/deletebyquery/DeleteByQueryRequestBuilder.java index 7560e1e8b11..dc5ba3a15fb 100644 --- a/plugins/delete-by-query/src/main/java/org/elasticsearch/action/deletebyquery/DeleteByQueryRequestBuilder.java +++ b/plugins/delete-by-query/src/main/java/org/elasticsearch/action/deletebyquery/DeleteByQueryRequestBuilder.java @@ -55,7 +55,7 @@ public class DeleteByQueryRequestBuilder extends ActionRequestBuilder queryBuilder) { + public DeleteByQueryRequestBuilder setQuery(QueryBuilder queryBuilder) { request.query(queryBuilder); return this; } diff --git a/plugins/delete-by-query/src/main/java/org/elasticsearch/rest/action/deletebyquery/RestDeleteByQueryAction.java b/plugins/delete-by-query/src/main/java/org/elasticsearch/rest/action/deletebyquery/RestDeleteByQueryAction.java index a7146c2a768..2b537d1cf8a 100644 --- a/plugins/delete-by-query/src/main/java/org/elasticsearch/rest/action/deletebyquery/RestDeleteByQueryAction.java +++ b/plugins/delete-by-query/src/main/java/org/elasticsearch/rest/action/deletebyquery/RestDeleteByQueryAction.java @@ -66,7 +66,7 @@ public class RestDeleteByQueryAction extends BaseRestHandler { if (RestActions.hasBodyContent(request)) { delete.query(RestActions.getQueryContent(RestActions.getRestContent(request), indicesQueriesRegistry, parseFieldMatcher)); } else { - QueryBuilder queryBuilder = RestActions.urlParamsToQueryBuilder(request); + QueryBuilder queryBuilder = RestActions.urlParamsToQueryBuilder(request); if (queryBuilder != null) { delete.query(queryBuilder); } diff --git a/plugins/discovery-azure/src/test/java/org/elasticsearch/cloud/azure/AbstractAzureComputeServiceTestCase.java b/plugins/discovery-azure/src/test/java/org/elasticsearch/cloud/azure/AbstractAzureComputeServiceTestCase.java index 3f78b1f6683..0c57ec3f16e 100644 --- a/plugins/discovery-azure/src/test/java/org/elasticsearch/cloud/azure/AbstractAzureComputeServiceTestCase.java +++ b/plugins/discovery-azure/src/test/java/org/elasticsearch/cloud/azure/AbstractAzureComputeServiceTestCase.java @@ -65,6 +65,6 @@ public abstract class AbstractAzureComputeServiceTestCase extends ESIntegTestCas NodesInfoResponse nodeInfos = client().admin().cluster().prepareNodesInfo().execute().actionGet(); assertNotNull(nodeInfos); assertNotNull(nodeInfos.getNodes()); - assertEquals(expected, nodeInfos.getNodes().length); + assertEquals(expected, nodeInfos.getNodes().size()); } } diff --git a/qa/backwards-5.0/build.gradle b/qa/backwards-5.0/build.gradle index 164f0e53d52..93d361c989c 100644 --- a/qa/backwards-5.0/build.gradle +++ b/qa/backwards-5.0/build.gradle @@ -18,6 +18,6 @@ integTest { cluster { numNodes = 2 numBwcNodes = 1 - bwcVersion = "5.0.0-alpha2-SNAPSHOT" // this is the same as the current version until we released the first RC + bwcVersion = "5.0.0-SNAPSHOT" // this is the same as the current version until we released the first RC } } diff --git a/qa/vagrant/src/test/resources/packaging/scripts/40_rpm_package.bats b/qa/vagrant/src/test/resources/packaging/scripts/40_rpm_package.bats index 064439cdd5a..0d3170cafeb 100644 --- a/qa/vagrant/src/test/resources/packaging/scripts/40_rpm_package.bats +++ b/qa/vagrant/src/test/resources/packaging/scripts/40_rpm_package.bats @@ -116,7 +116,7 @@ setup() { assert_file_not_exist "/etc/elasticsearch" assert_file_not_exist "/etc/elasticsearch/elasticsearch.yml" - assert_file_not_exist "/etc/elasticsearch/jvm.options" + assert_file_not_exist "/etc/elasticsearch/jvm.options" assert_file_not_exist "/etc/elasticsearch/logging.yml" assert_file_not_exist "/etc/init.d/elasticsearch" @@ -125,7 +125,6 @@ setup() { assert_file_not_exist "/etc/sysconfig/elasticsearch" } - @test "[RPM] reinstall package" { rpm -i elasticsearch-$(cat version).rpm } @@ -134,12 +133,46 @@ setup() { rpm -qe 'elasticsearch' } -@test "[RPM] verify package reinstallation" { - verify_package_installation +@test "[RPM] reremove package" { + echo "# ping" >> "/etc/elasticsearch/elasticsearch.yml" + echo "# ping" >> "/etc/elasticsearch/jvm.options" + echo "# ping" >> "/etc/elasticsearch/logging.yml" + echo "# ping" >> "/etc/elasticsearch/scripts/script" + rpm -e 'elasticsearch' } -@test "[RPM] reremove package" { - rpm -e 'elasticsearch' +@test "[RPM] verify preservation" { + # The removal must disable the service + # see prerm file + if is_systemd; then + run systemctl is-enabled elasticsearch.service + [ "$status" -eq 1 ] + fi + + # Those directories are deleted when removing the package + # see postrm file + assert_file_not_exist "/var/log/elasticsearch" + assert_file_not_exist "/usr/share/elasticsearch/plugins" + assert_file_not_exist "/var/run/elasticsearch" + + assert_file_not_exist "/etc/elasticsearch/elasticsearch.yml" + assert_file_exist "/etc/elasticsearch/elasticsearch.yml.rpmsave" + assert_file_not_exist "/etc/elasticsearch/jvm.options" + assert_file_exist "/etc/elasticsearch/jvm.options.rpmsave" + assert_file_not_exist "/etc/elasticsearch/logging.yml" + assert_file_exist "/etc/elasticsearch/logging.yml.rpmsave" + assert_file_exist "/etc/elasticsearch/scripts.rpmsave" + assert_file_exist "/etc/elasticsearch/scripts.rpmsave/script" + + assert_file_not_exist "/etc/init.d/elasticsearch" + assert_file_not_exist "/usr/lib/systemd/system/elasticsearch.service" + + assert_file_not_exist "/etc/sysconfig/elasticsearch" +} + +@test "[RPM] finalize package removal" { + # cleanup + rm -rf /etc/elasticsearch } @test "[RPM] package has been removed again" { diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/cat.recovery/10_basic.yaml b/rest-api-spec/src/main/resources/rest-api-spec/test/cat.recovery/10_basic.yaml index effc4c20313..fc596dd5792 100755 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/cat.recovery/10_basic.yaml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/cat.recovery/10_basic.yaml @@ -19,7 +19,8 @@ cluster.health: wait_for_status: yellow - do: - cat.recovery: {} + cat.recovery: + h: i,s,t,ty,st,shost,thost,rep,snap,f,fr,fp,tf,b,br,bp,tb,to,tor,top - match: $body: | @@ -48,3 +49,33 @@ \n )+ $/ + + - do: + cat.recovery: + h: shard,source_node,bytes + + - match: + $body: | + /^ + ( + \d \s+ # shard + ((\S+\s?){1,10})\s+ # source_node + \d+ # bytes + \n + )+ + $/ + + - do: + cat.recovery: + h: shard,target_node,bytes + + - match: + $body: | + /^ + ( + \d \s+ # shard + ((\S+\s?){1,10})\s+ # target_node + \d+ # bytes + \n + )+ + $/ diff --git a/test/framework/src/main/java/org/elasticsearch/cluster/MockInternalClusterInfoService.java b/test/framework/src/main/java/org/elasticsearch/cluster/MockInternalClusterInfoService.java index d66b1f9fc9e..ef8857475b3 100644 --- a/test/framework/src/main/java/org/elasticsearch/cluster/MockInternalClusterInfoService.java +++ b/test/framework/src/main/java/org/elasticsearch/cluster/MockInternalClusterInfoService.java @@ -38,6 +38,8 @@ import org.elasticsearch.monitor.fs.FsInfo; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.threadpool.ThreadPool; +import java.util.Arrays; +import java.util.Collections; import java.util.concurrent.CountDownLatch; import static java.util.Collections.emptyMap; @@ -107,7 +109,7 @@ public class MockInternalClusterInfoService extends InternalClusterInfoService { @Override public CountDownLatch updateNodeStats(final ActionListener listener) { - NodesStatsResponse response = new NodesStatsResponse(clusterName, stats); + NodesStatsResponse response = new NodesStatsResponse(clusterName, Arrays.asList(stats), Collections.emptyList()); listener.onResponse(response); return new CountDownLatch(0); } diff --git a/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java index a31ef76272e..247a340d8c4 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java @@ -2046,8 +2046,8 @@ public abstract class ESIntegTestCase extends ESTestCase { protected HttpRequestBuilder httpClient(CloseableHttpClient httpClient) { final NodesInfoResponse nodeInfos = client().admin().cluster().prepareNodesInfo().get(); - final NodeInfo[] nodes = nodeInfos.getNodes(); - assertTrue(nodes.length > 0); + final List nodes = nodeInfos.getNodes(); + assertFalse(nodeInfos.hasFailures()); TransportAddress publishAddress = randomFrom(nodes).getHttp().address().publishAddress(); assertEquals(1, publishAddress.uniqueAddressTypeId()); InetSocketAddress address = ((InetSocketTransportAddress) publishAddress).address(); diff --git a/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java index 01f0d5b8151..3dbbf25e202 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java @@ -414,7 +414,7 @@ public abstract class ESTestCase extends LuceneTestCase { if (input != null) { return randomValueOtherThanMany(input::equals, randomSupplier); } - + return(randomSupplier.get()); } @@ -634,25 +634,29 @@ public abstract class ESTestCase extends LuceneTestCase { * recursive shuffling behavior can be made by passing in the names of fields which * internally should stay untouched. */ - public static XContentBuilder shuffleXContent(XContentBuilder builder, Set exceptFieldNames) throws IOException { + public static XContentBuilder shuffleXContent(XContentBuilder builder, String... exceptFieldNames) throws IOException { BytesReference bytes = builder.bytes(); XContentParser parser = XContentFactory.xContent(bytes).createParser(bytes); // use ordered maps for reproducibility - Map shuffledMap = shuffleMap(parser.mapOrdered(), exceptFieldNames); - XContentBuilder jsonBuilder = XContentFactory.contentBuilder(builder.contentType()); - return jsonBuilder.map(shuffledMap); + Map shuffledMap = shuffleMap(parser.mapOrdered(), new HashSet<>(Arrays.asList(exceptFieldNames))); + XContentBuilder xContentBuilder = XContentFactory.contentBuilder(builder.contentType()); + if (builder.isPrettyPrint()) { + xContentBuilder.prettyPrint(); + } + return xContentBuilder.map(shuffledMap); } - private static Map shuffleMap(Map map, Set exceptFieldNames) { + private static Map shuffleMap(Map map, Set exceptFields) { List keys = new ArrayList<>(map.keySet()); + // even though we shuffle later, we need this to make tests reproduce on different jvms Collections.sort(keys); Map targetMap = new TreeMap<>(); Collections.shuffle(keys, random()); for (String key : keys) { Object value = map.get(key); - if (value instanceof Map && exceptFieldNames.contains(key) == false) { - targetMap.put(key, shuffleMap((Map) value, exceptFieldNames)); + if (value instanceof Map && exceptFields.contains(key) == false) { + targetMap.put(key, shuffleMap((Map) value, exceptFields)); } else { targetMap.put(key, value); } diff --git a/test/framework/src/main/java/org/elasticsearch/test/ExternalNode.java b/test/framework/src/main/java/org/elasticsearch/test/ExternalNode.java index 296f34637dd..4625aa77e25 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/ExternalNode.java +++ b/test/framework/src/main/java/org/elasticsearch/test/ExternalNode.java @@ -154,8 +154,7 @@ final class ExternalNode implements Closeable { static boolean waitForNode(final Client client, final String name) throws InterruptedException { return ESTestCase.awaitBusy(() -> { final NodesInfoResponse nodeInfos = client.admin().cluster().prepareNodesInfo().get(); - final NodeInfo[] nodes = nodeInfos.getNodes(); - for (NodeInfo info : nodes) { + for (NodeInfo info : nodeInfos.getNodes()) { if (name.equals(info.getNode().getName())) { return true; } @@ -166,8 +165,7 @@ final class ExternalNode implements Closeable { static NodeInfo nodeInfo(final Client client, final String nodeName) { final NodesInfoResponse nodeInfos = client.admin().cluster().prepareNodesInfo().get(); - final NodeInfo[] nodes = nodeInfos.getNodes(); - for (NodeInfo info : nodes) { + for (NodeInfo info : nodeInfos.getNodes()) { if (nodeName.equals(info.getNode().getName())) { return info; } diff --git a/test/framework/src/main/java/org/elasticsearch/test/ExternalTestCluster.java b/test/framework/src/main/java/org/elasticsearch/test/ExternalTestCluster.java index 17c3e3d0805..5372c319dae 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/ExternalTestCluster.java +++ b/test/framework/src/main/java/org/elasticsearch/test/ExternalTestCluster.java @@ -87,12 +87,12 @@ public final class ExternalTestCluster extends TestCluster { try { client.addTransportAddresses(transportAddresses); NodesInfoResponse nodeInfos = client.admin().cluster().prepareNodesInfo().clear().setSettings(true).setHttp(true).get(); - httpAddresses = new InetSocketAddress[nodeInfos.getNodes().length]; + httpAddresses = new InetSocketAddress[nodeInfos.getNodes().size()]; this.clusterName = nodeInfos.getClusterName().value(); int dataNodes = 0; int masterAndDataNodes = 0; - for (int i = 0; i < nodeInfos.getNodes().length; i++) { - NodeInfo nodeInfo = nodeInfos.getNodes()[i]; + for (int i = 0; i < nodeInfos.getNodes().size(); i++) { + NodeInfo nodeInfo = nodeInfos.getNodes().get(i); httpAddresses[i] = ((InetSocketTransportAddress) nodeInfo.getHttp().address().publishAddress()).address(); if (DiscoveryNode.isDataNode(nodeInfo.getSettings())) { dataNodes++; diff --git a/test/framework/src/main/java/org/elasticsearch/test/TestSearchContext.java b/test/framework/src/main/java/org/elasticsearch/test/TestSearchContext.java index 60a660ead42..5cac904df35 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/TestSearchContext.java +++ b/test/framework/src/main/java/org/elasticsearch/test/TestSearchContext.java @@ -18,16 +18,13 @@ */ package org.elasticsearch.test; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import org.apache.lucene.search.Collector; import org.apache.lucene.search.FieldDoc; import org.apache.lucene.search.Query; -import org.apache.lucene.search.Sort; import org.apache.lucene.util.Counter; import org.elasticsearch.action.search.SearchType; import org.elasticsearch.cache.recycler.PageCacheRecycler; @@ -65,13 +62,10 @@ import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.profile.Profilers; import org.elasticsearch.search.query.QuerySearchResult; import org.elasticsearch.search.rescore.RescoreSearchContext; +import org.elasticsearch.search.sort.SortAndFormats; import org.elasticsearch.search.suggest.SuggestionSearchContext; import org.elasticsearch.threadpool.ThreadPool; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - public class TestSearchContext extends SearchContext { final PageCacheRecycler pageCacheRecycler; @@ -365,12 +359,12 @@ public class TestSearchContext extends SearchContext { } @Override - public SearchContext sort(Sort sort) { + public SearchContext sort(SortAndFormats sort) { return null; } @Override - public Sort sort() { + public SortAndFormats sort() { return null; } diff --git a/test/framework/src/test/java/org/elasticsearch/test/test/ESTestCaseTests.java b/test/framework/src/test/java/org/elasticsearch/test/test/ESTestCaseTests.java index 714354cc24c..005cd643480 100644 --- a/test/framework/src/test/java/org/elasticsearch/test/test/ESTestCaseTests.java +++ b/test/framework/src/test/java/org/elasticsearch/test/test/ESTestCaseTests.java @@ -29,11 +29,9 @@ import org.elasticsearch.test.ESTestCase; import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import static org.hamcrest.Matchers.greaterThan; @@ -71,7 +69,7 @@ public class ESTestCaseTests extends ESTestCase { Map randomStringObjectMap = randomStringObjectMap(5); XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values())); builder.map(randomStringObjectMap); - XContentBuilder shuffleXContent = shuffleXContent(builder, Collections.emptySet()); + XContentBuilder shuffleXContent = shuffleXContent(builder); XContentParser parser = XContentFactory.xContent(shuffleXContent.bytes()).createParser(shuffleXContent.bytes()); Map resultMap = parser.map(); assertEquals("both maps should contain the same mappings", randomStringObjectMap, resultMap);