EQL: Remove unused classes from reponse API (#62134)

Remove Count class and related artifacts since that functionality is not
(yet) available.
Update parser name for better error reporting.

Fix #62131

(cherry picked from commit 060f500346788c4c5d0b3b9c045facec5d677d3d)
This commit is contained in:
Costin Leau 2020-09-30 15:02:38 +03:00 committed by Costin Leau
parent f221349593
commit a6b903b783
9 changed files with 42 additions and 311 deletions

View File

@ -138,7 +138,7 @@ public class EqlSearchResponse {
public int hashCode() {
return Objects.hash(hits, tookInMillis, isTimeout);
}
// Event
public static class Event {
@ -181,7 +181,7 @@ public class EqlSearchResponse {
public static Event fromXContent(XContentParser parser) throws IOException {
return PARSER.apply(parser, null);
}
public String index() {
return index;
}
@ -216,11 +216,11 @@ public class EqlSearchResponse {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
EqlSearchResponse.Event other = (EqlSearchResponse.Event) obj;
return Objects.equals(index, other.index)
&& Objects.equals(id, other.id)
@ -292,114 +292,34 @@ public class EqlSearchResponse {
}
}
// Count
public static class Count {
private static final class Fields {
static final String COUNT = "_count";
static final String KEYS = "_keys";
static final String PERCENT = "_percent";
}
private final int count;
private final List<Object> keys;
private final float percent;
private static final ParseField COUNT = new ParseField(Fields.COUNT);
private static final ParseField KEYS = new ParseField(Fields.KEYS);
private static final ParseField PERCENT = new ParseField(Fields.PERCENT);
private static final ConstructingObjectParser<EqlSearchResponse.Count, Void> PARSER =
new ConstructingObjectParser<>("eql/search_response_count", true,
args -> {
int i = 0;
int count = (int) args[i++];
@SuppressWarnings("unchecked") List<Object> joinKeys = (List<Object>) args[i++];
float percent = (float) args[i];
return new EqlSearchResponse.Count(count, joinKeys, percent);
});
static {
PARSER.declareInt(ConstructingObjectParser.constructorArg(), COUNT);
PARSER.declareFieldArray(constructorArg(), (p, c) -> XContentParserUtils.parseFieldsValue(p), KEYS,
ObjectParser.ValueType.VALUE_ARRAY);
PARSER.declareFloat(ConstructingObjectParser.constructorArg(), PERCENT);
}
public Count(int count, List<Object> keys, float percent) {
this.count = count;
this.keys = keys == null ? Collections.emptyList() : keys;
this.percent = percent;
}
public static Count fromXContent(XContentParser parser) {
return PARSER.apply(parser, null);
}
public int count() {
return count;
}
public List<Object> keys() {
return keys;
}
public float percent() {
return percent;
}
@Override
public int hashCode() {
return Objects.hash(count, keys, percent);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Count that = (Count) o;
return Objects.equals(count, that.count)
&& Objects.equals(keys, that.keys)
&& Objects.equals(percent, that.percent);
}
}
// Hits
public static class Hits {
public static final Hits EMPTY = new Hits(null, null, null, null);
public static final Hits EMPTY = new Hits(null, null, null);
private final List<Event> events;
private final List<Sequence> sequences;
private final List<Count> counts;
private final TotalHits totalHits;
private static final class Fields {
static final String TOTAL = "total";
static final String EVENTS = "events";
static final String SEQUENCES = "sequences";
static final String COUNTS = "counts";
}
public Hits(@Nullable List<Event> events, @Nullable List<Sequence> sequences, @Nullable List<Count> counts,
@Nullable TotalHits totalHits) {
public Hits(@Nullable List<Event> events, @Nullable List<Sequence> sequences, @Nullable TotalHits totalHits) {
this.events = events;
this.sequences = sequences;
this.counts = counts;
this.totalHits = totalHits;
}
private static final ConstructingObjectParser<EqlSearchResponse.Hits, Void> PARSER =
new ConstructingObjectParser<>("eql/search_response_count", true,
new ConstructingObjectParser<>("eql/search_response_hits", true,
args -> {
int i = 0;
@SuppressWarnings("unchecked") List<Event> events = (List<Event>) args[i++];
@SuppressWarnings("unchecked") List<Sequence> sequences = (List<Sequence>) args[i++];
@SuppressWarnings("unchecked") List<Count> counts = (List<Count>) args[i++];
TotalHits totalHits = (TotalHits) args[i];
return new EqlSearchResponse.Hits(events, sequences, counts, totalHits);
return new EqlSearchResponse.Hits(events, sequences, totalHits);
});
static {
@ -407,8 +327,6 @@ public class EqlSearchResponse {
new ParseField(Fields.EVENTS));
PARSER.declareObjectArray(ConstructingObjectParser.optionalConstructorArg(), Sequence.PARSER,
new ParseField(Fields.SEQUENCES));
PARSER.declareObjectArray(ConstructingObjectParser.optionalConstructorArg(), Count.PARSER,
new ParseField(Fields.COUNTS));
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> SearchHits.parseTotalHitsFragment(p),
new ParseField(Fields.TOTAL));
}
@ -425,17 +343,13 @@ public class EqlSearchResponse {
return this.sequences;
}
public List<Count> counts() {
return this.counts;
}
public TotalHits totalHits() {
return this.totalHits;
}
@Override
public int hashCode() {
return Objects.hash(events, sequences, counts, totalHits);
return Objects.hash(events, sequences, totalHits);
}
@Override
@ -449,7 +363,6 @@ public class EqlSearchResponse {
Hits that = (Hits) o;
return Objects.equals(events, that.events)
&& Objects.equals(sequences, that.sequences)
&& Objects.equals(counts, that.counts)
&& Objects.equals(totalHits, that.totalHits);
}
}

View File

@ -96,7 +96,6 @@ public class EqlIT extends ESRestHighLevelClientTestCase {
assertFalse(response.isTimeout());
assertNotNull(response.hits());
assertNull(response.hits().sequences());
assertNull(response.hits().counts());
assertNotNull(response.hits().events());
assertThat(response.hits().events().size(), equalTo(count));
}

View File

@ -106,7 +106,7 @@ public class EqlSearchResponseTests extends AbstractResponseTestCase<org.elastic
public static org.elasticsearch.xpack.eql.action.EqlSearchResponse createRandomEventsResponse(TotalHits totalHits, XContentType xType) {
org.elasticsearch.xpack.eql.action.EqlSearchResponse.Hits hits = null;
if (randomBoolean()) {
hits = new org.elasticsearch.xpack.eql.action.EqlSearchResponse.Hits(randomEvents(xType), null, null, totalHits);
hits = new org.elasticsearch.xpack.eql.action.EqlSearchResponse.Hits(randomEvents(xType), null, totalHits);
}
if (randomBoolean()) {
return new org.elasticsearch.xpack.eql.action.EqlSearchResponse(hits, randomIntBetween(0, 1001), randomBoolean());
@ -133,7 +133,7 @@ public class EqlSearchResponseTests extends AbstractResponseTestCase<org.elastic
}
org.elasticsearch.xpack.eql.action.EqlSearchResponse.Hits hits = null;
if (randomBoolean()) {
hits = new org.elasticsearch.xpack.eql.action.EqlSearchResponse.Hits(null, seq, null, totalHits);
hits = new org.elasticsearch.xpack.eql.action.EqlSearchResponse.Hits(null, seq, totalHits);
}
if (randomBoolean()) {
return new org.elasticsearch.xpack.eql.action.EqlSearchResponse(hits, randomIntBetween(0, 1001), randomBoolean());
@ -153,41 +153,13 @@ public class EqlSearchResponseTests extends AbstractResponseTestCase<org.elastic
return randoms;
}
public static org.elasticsearch.xpack.eql.action.EqlSearchResponse createRandomCountResponse(TotalHits totalHits) {
int size = randomIntBetween(1, 10);
List<org.elasticsearch.xpack.eql.action.EqlSearchResponse.Count> cn = null;
if (randomBoolean()) {
List<Supplier<Object[]>> randoms = getKeysGenerators();
cn = new ArrayList<>();
for (int i = 0; i < size; i++) {
List<Object> keys = null;
if (randomBoolean()) {
keys = Arrays.asList(randomFrom(randoms).get());
}
cn.add(new org.elasticsearch.xpack.eql.action.EqlSearchResponse.Count(randomIntBetween(0, 41), keys, randomFloat()));
}
}
org.elasticsearch.xpack.eql.action.EqlSearchResponse.Hits hits = null;
if (randomBoolean()) {
hits = new org.elasticsearch.xpack.eql.action.EqlSearchResponse.Hits(null, null, cn, totalHits);
}
if (randomBoolean()) {
return new org.elasticsearch.xpack.eql.action.EqlSearchResponse(hits, randomIntBetween(0, 1001), randomBoolean());
} else {
return new org.elasticsearch.xpack.eql.action.EqlSearchResponse(hits, randomIntBetween(0, 1001), randomBoolean(),
randomAlphaOfLength(10), randomBoolean(), randomBoolean());
}
}
public static org.elasticsearch.xpack.eql.action.EqlSearchResponse createRandomInstance(TotalHits totalHits, XContentType xType) {
int type = between(0, 2);
int type = between(0, 1);
switch (type) {
case 0:
return createRandomEventsResponse(totalHits, xType);
case 1:
return createRandomSequencesResponse(totalHits, xType);
case 2:
return createRandomCountResponse(totalHits);
default:
return null;
}
@ -213,16 +185,6 @@ public class EqlSearchResponseTests extends AbstractResponseTestCase<org.elastic
assertThat(serverTestInstance.took(), is(clientInstance.took()));
assertThat(serverTestInstance.isTimeout(), is(clientInstance.isTimeout()));
assertThat(serverTestInstance.hits().totalHits(), is(clientInstance.hits().totalHits()));
if (serverTestInstance.hits().counts() == null) {
assertNull(clientInstance.hits().counts());
} else {
assertThat(serverTestInstance.hits().counts().size(), equalTo(clientInstance.hits().counts().size()));
for (int i = 0; i < serverTestInstance.hits().counts().size(); i++) {
assertThat(serverTestInstance.hits().counts().get(i).count(), is(clientInstance.hits().counts().get(i).count()));
assertThat(serverTestInstance.hits().counts().get(i).keys(), is(clientInstance.hits().counts().get(i).keys()));
assertThat(serverTestInstance.hits().counts().get(i).percent(), is(clientInstance.hits().counts().get(i).percent()));
}
}
if (serverTestInstance.hits().events() == null) {
assertNull(clientInstance.hits().events());
} else {

View File

@ -6,6 +6,7 @@
package org.elasticsearch.xpack.eql.action;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.Version;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
@ -380,111 +381,11 @@ public class EqlSearchResponse extends ActionResponse implements ToXContentObjec
}
}
// Count
public static class Count implements ToXContentObject, Writeable {
private static final class Fields {
static final String COUNT = "_count";
static final String KEYS = "_keys";
static final String PERCENT = "_percent";
}
private final int count;
private final List<Object> keys;
private final float percent;
private static final ParseField COUNT = new ParseField(Fields.COUNT);
private static final ParseField KEYS = new ParseField(Fields.KEYS);
private static final ParseField PERCENT = new ParseField(Fields.PERCENT);
private static final ConstructingObjectParser<EqlSearchResponse.Count, Void> PARSER =
new ConstructingObjectParser<>("eql/search_response_count", true,
args -> {
int i = 0;
int count = (int) args[i++];
@SuppressWarnings("unchecked") List<Object> joinKeys = (List<Object>) args[i++];
float percent = (float) args[i];
return new EqlSearchResponse.Count(count, joinKeys, percent);
});
static {
PARSER.declareInt(constructorArg(), COUNT);
PARSER.declareFieldArray(constructorArg(), (p, c) -> XContentParserUtils.parseFieldsValue(p), KEYS,
ObjectParser.ValueType.VALUE_ARRAY);
PARSER.declareFloat(constructorArg(), PERCENT);
}
public Count(int count, List<Object> keys, float percent) {
this.count = count;
this.keys = keys == null ? Collections.emptyList() : keys;
this.percent = percent;
}
@SuppressWarnings("unchecked")
public Count(StreamInput in) throws IOException {
count = in.readVInt();
keys = (List<Object>) in.readGenericValue();
percent = in.readFloat();
}
public static Count fromXContent(XContentParser parser) {
return PARSER.apply(parser, null);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVInt(count);
out.writeGenericValue(keys);
out.writeFloat(percent);
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field(Fields.COUNT, count);
builder.field(Fields.KEYS, keys);
builder.field(Fields.PERCENT, percent);
builder.endObject();
return builder;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Count that = (Count) o;
return Objects.equals(count, that.count)
&& Objects.equals(keys, that.keys)
&& Objects.equals(percent, that.percent);
}
@Override
public int hashCode() {
return Objects.hash(count, keys, percent);
}
public int count() {
return count;
}
public List<Object> keys() {
return keys;
}
public float percent() {
return percent;
}
}
public static class Hits implements Writeable, ToXContentFragment {
public static final Hits EMPTY = new Hits(null, null, null, null);
public static final Hits EMPTY = new Hits(null, null, null);
private final List<Event> events;
private final List<Sequence> sequences;
private final List<Count> counts;
private final TotalHits totalHits;
private static final class Fields {
@ -492,14 +393,11 @@ public class EqlSearchResponse extends ActionResponse implements ToXContentObjec
static final String TOTAL = "total";
static final String EVENTS = "events";
static final String SEQUENCES = "sequences";
static final String COUNTS = "counts";
}
public Hits(@Nullable List<Event> events, @Nullable List<Sequence> sequences, @Nullable List<Count> counts,
@Nullable TotalHits totalHits) {
public Hits(@Nullable List<Event> events, @Nullable List<Sequence> sequences, @Nullable TotalHits totalHits) {
this.events = events;
this.sequences = sequences;
this.counts = counts;
this.totalHits = totalHits;
}
@ -512,7 +410,19 @@ public class EqlSearchResponse extends ActionResponse implements ToXContentObjec
}
events = in.readBoolean() ? in.readList(Event::new) : null;
sequences = in.readBoolean() ? in.readList(Sequence::new) : null;
counts = in.readBoolean() ? in.readList(Count::new) : null;
// compatibility with 7.9 experimental release
if (in.getVersion().before(Version.V_7_10_0)) {
if (in.readBoolean()) {
// old read count
in.readList(input -> {
input.readVInt();
input.readGenericValue();
input.readFloat();
return null;
});
}
}
}
@Override
@ -534,23 +444,21 @@ public class EqlSearchResponse extends ActionResponse implements ToXContentObjec
} else {
out.writeBoolean(false);
}
if (counts != null) {
out.writeBoolean(true);
out.writeList(counts);
} else {
// compatibility with 7.9 experimental release
if (out.getVersion().before(Version.V_7_10_0)) {
// no counts
out.writeBoolean(false);
}
}
private static final ConstructingObjectParser<EqlSearchResponse.Hits, Void> PARSER =
new ConstructingObjectParser<>("eql/search_response_count", true,
new ConstructingObjectParser<>("eql/search_response_hits", true,
args -> {
int i = 0;
@SuppressWarnings("unchecked") List<Event> events = (List<Event>) args[i++];
@SuppressWarnings("unchecked") List<Sequence> sequences = (List<Sequence>) args[i++];
@SuppressWarnings("unchecked") List<Count> counts = (List<Count>) args[i++];
TotalHits totalHits = (TotalHits) args[i];
return new EqlSearchResponse.Hits(events, sequences, counts, totalHits);
return new EqlSearchResponse.Hits(events, sequences, totalHits);
});
static {
@ -558,8 +466,6 @@ public class EqlSearchResponse extends ActionResponse implements ToXContentObjec
new ParseField(Fields.EVENTS));
PARSER.declareObjectArray(ConstructingObjectParser.optionalConstructorArg(), Sequence.PARSER,
new ParseField(Fields.SEQUENCES));
PARSER.declareObjectArray(ConstructingObjectParser.optionalConstructorArg(), Count.PARSER,
new ParseField(Fields.COUNTS));
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> SearchHits.parseTotalHitsFragment(p),
new ParseField(Fields.TOTAL));
}
@ -587,9 +493,6 @@ public class EqlSearchResponse extends ActionResponse implements ToXContentObjec
if (sequences != null) {
builder.field(Fields.SEQUENCES, sequences);
}
if (counts != null) {
builder.field(Fields.COUNTS, counts);
}
builder.endObject();
return builder;
@ -606,13 +509,12 @@ public class EqlSearchResponse extends ActionResponse implements ToXContentObjec
Hits that = (Hits) o;
return Objects.equals(events, that.events)
&& Objects.equals(sequences, that.sequences)
&& Objects.equals(counts, that.counts)
&& Objects.equals(totalHits, that.totalHits);
}
@Override
public int hashCode() {
return Objects.hash(events, sequences, counts, totalHits);
return Objects.hash(events, sequences, totalHits);
}
public List<Event> events() {
@ -623,10 +525,6 @@ public class EqlSearchResponse extends ActionResponse implements ToXContentObjec
return this.sequences;
}
public List<Count> counts() {
return this.counts;
}
public TotalHits totalHits() {
return this.totalHits;
}

View File

@ -125,8 +125,7 @@ public class TransportEqlSearchAction extends HandledTransportAction<EqlSearchRe
}
static EqlSearchResponse createResponse(Results results, AsyncExecutionId id) {
EqlSearchResponse.Hits hits = new EqlSearchResponse.Hits(results.events(), results.sequences(), results.counts(), results
.totalHits());
EqlSearchResponse.Hits hits = new EqlSearchResponse.Hits(results.events(), results.sequences(), results.totalHits());
if (id != null) {
return new EqlSearchResponse(hits, results.tookTime().getMillis(), results.timedOut(), id.getEncoded(), false, false);
} else {

View File

@ -17,10 +17,9 @@ public interface Payload {
enum Type {
EVENT,
SEQUENCE,
COUNT;
SEQUENCE;
}
Type resultType();
boolean timedOut();

View File

@ -9,7 +9,6 @@ package org.elasticsearch.xpack.eql.session;
import org.apache.lucene.search.TotalHits;
import org.apache.lucene.search.TotalHits.Relation;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.xpack.eql.action.EqlSearchResponse.Count;
import org.elasticsearch.xpack.eql.action.EqlSearchResponse.Event;
import org.elasticsearch.xpack.eql.action.EqlSearchResponse.Sequence;
import org.elasticsearch.xpack.eql.session.Payload.Type;
@ -28,7 +27,7 @@ public class Results {
List<?> values = payload.values();
return new Results(new TotalHits(values.size(), Relation.EQUAL_TO), payload.timeTook(), false, values, payload.resultType());
}
Results(TotalHits totalHits, TimeValue tookTime, boolean timedOut, List<?> results, Type type) {
this.totalHits = totalHits;
this.tookTime = tookTime;
@ -51,11 +50,6 @@ public class Results {
return type == Type.SEQUENCE ? (List<Sequence>) results : null;
}
@SuppressWarnings("unchecked")
public List<Count> counts() {
return type == Type.COUNT ? (List<Count>) results : null;
}
public TimeValue tookTime() {
return tookTime;
}
@ -63,4 +57,4 @@ public class Results {
public boolean timedOut() {
return timedOut;
}
}
}

View File

@ -112,7 +112,7 @@ public class EqlSearchResponseTests extends AbstractSerializingTestCase<EqlSearc
public static EqlSearchResponse createRandomEventsResponse(TotalHits totalHits, XContentType xType) {
EqlSearchResponse.Hits hits = null;
if (randomBoolean()) {
hits = new EqlSearchResponse.Hits(randomEvents(xType), null, null, totalHits);
hits = new EqlSearchResponse.Hits(randomEvents(xType), null, totalHits);
}
if (randomBoolean()) {
return new EqlSearchResponse(hits, randomIntBetween(0, 1001), randomBoolean());
@ -138,7 +138,7 @@ public class EqlSearchResponseTests extends AbstractSerializingTestCase<EqlSearc
}
EqlSearchResponse.Hits hits = null;
if (randomBoolean()) {
hits = new EqlSearchResponse.Hits(null, seq, null, totalHits);
hits = new EqlSearchResponse.Hits(null, seq, totalHits);
}
if (randomBoolean()) {
return new EqlSearchResponse(hits, randomIntBetween(0, 1001), randomBoolean());
@ -158,41 +158,13 @@ public class EqlSearchResponseTests extends AbstractSerializingTestCase<EqlSearc
return randoms;
}
public static EqlSearchResponse createRandomCountResponse(TotalHits totalHits) {
int size = randomIntBetween(1, 10);
List<EqlSearchResponse.Count> cn = null;
if (randomBoolean()) {
List<Supplier<Object[]>> randoms = getKeysGenerators();
cn = new ArrayList<>();
for (int i = 0; i < size; i++) {
List<Object> keys = null;
if (randomBoolean()) {
keys = Arrays.asList(randomFrom(randoms).get());
}
cn.add(new EqlSearchResponse.Count(randomIntBetween(0, 41), keys, randomFloat()));
}
}
EqlSearchResponse.Hits hits = null;
if (randomBoolean()) {
hits = new EqlSearchResponse.Hits(null, null, cn, totalHits);
}
if (randomBoolean()) {
return new EqlSearchResponse(hits, randomIntBetween(0, 1001), randomBoolean());
} else {
return new EqlSearchResponse(hits, randomIntBetween(0, 1001), randomBoolean(),
randomAlphaOfLength(10), randomBoolean(), randomBoolean());
}
}
public static EqlSearchResponse createRandomInstance(TotalHits totalHits, XContentType xType) {
int type = between(0, 2);
int type = between(0, 1);
switch(type) {
case 0:
return createRandomEventsResponse(totalHits, xType);
case 1:
return createRandomSequencesResponse(totalHits, xType);
case 2:
return createRandomCountResponse(totalHits);
default:
return null;
}

View File

@ -69,7 +69,6 @@ import static org.elasticsearch.xpack.ql.type.DataTypes.INTEGER;
public class OptimizerTests extends ESTestCase {
private static final String INDEX_NAME = "test";
private EqlParser parser = new EqlParser();
private IndexResolution index = loadIndexResolution("mapping-default.json");
@ -363,7 +362,6 @@ public class OptimizerTests extends ESTestCase {
* \filter X
*/
public void testKeySameConstraints() {
ZoneId zd = randomZone();
Attribute a = key("a");
Expression keyCondition = gtExpression(a);
@ -436,7 +434,6 @@ public class OptimizerTests extends ESTestCase {
* \filter b == 1
*/
public void testDifferentOneKeyConstraints() {
ZoneId zd = randomZone();
Attribute a = key("a");
Attribute b = key("b");
@ -525,7 +522,6 @@ public class OptimizerTests extends ESTestCase {
* same
*/
public void testSkipKeySameWithDisjunctionConstraints() {
ZoneId zd = randomZone();
Attribute a = key("a");
Expression keyCondition = gtExpression(a);
@ -560,7 +556,6 @@ public class OptimizerTests extends ESTestCase {
* \filter x == 1
*/
public void testExtractKeySameFromDisjunction() {
ZoneId zd = randomZone();
Attribute a = key("a");
Expression keyCondition = gtExpression(a);