EQL: Allow requests with size 0 (#62537)

The purpose for this change is to allow validation of queries without
having to actually execute them. The optimizer already picks up this
case.

Fix #62494

(cherry picked from commit 675889559b2f96a0c1faa6fc84fd537148ba2cce)
This commit is contained in:
Costin Leau 2020-09-18 11:22:44 +03:00 committed by Costin Leau
parent 5190b0961d
commit 81f2f84177
5 changed files with 27 additions and 18 deletions

View File

@ -157,10 +157,10 @@ public class EqlSearchRequest implements Validatable, ToXContentObject {
} }
public EqlSearchRequest size(int size) { public EqlSearchRequest size(int size) {
this.size = size; if (size < 0) {
if (fetchSize <= 0) { throw new IllegalArgumentException("size must be greater than or equal to 0");
throw new IllegalArgumentException("size must be greater than 0");
} }
this.size = size;
return this; return this;
} }
@ -169,10 +169,10 @@ public class EqlSearchRequest implements Validatable, ToXContentObject {
} }
public EqlSearchRequest fetchSize(int fetchSize) { public EqlSearchRequest fetchSize(int fetchSize) {
this.fetchSize = fetchSize;
if (fetchSize < 2) { if (fetchSize < 2) {
throw new IllegalArgumentException("fetch size must be greater than 1"); throw new IllegalArgumentException("fetch size must be greater than 1");
} }
this.fetchSize = fetchSize;
return this; return this;
} }
@ -226,6 +226,8 @@ public class EqlSearchRequest implements Validatable, ToXContentObject {
Arrays.equals(indices, that.indices) && Arrays.equals(indices, that.indices) &&
Objects.equals(indicesOptions, that.indicesOptions) && Objects.equals(indicesOptions, that.indicesOptions) &&
Objects.equals(filter, that.filter) && Objects.equals(filter, that.filter) &&
Objects.equals(size, that.size) &&
Objects.equals(fetchSize, that.fetchSize) &&
Objects.equals(timestampField, that.timestampField) && Objects.equals(timestampField, that.timestampField) &&
Objects.equals(tiebreakerField, that.tiebreakerField) && Objects.equals(tiebreakerField, that.tiebreakerField) &&
Objects.equals(eventCategoryField, that.eventCategoryField) && Objects.equals(eventCategoryField, that.eventCategoryField) &&

View File

@ -35,30 +35,33 @@ public class EqlSearchRequestTests extends AbstractRequestTestCase<EqlSearchRequ
@Override @Override
protected EqlSearchRequest createClientTestInstance() { protected EqlSearchRequest createClientTestInstance() {
EqlSearchRequest EqlSearchRequest = new EqlSearchRequest("testindex", randomAlphaOfLength(40)); EqlSearchRequest eqlSearchRequest = new EqlSearchRequest("testindex", randomAlphaOfLength(40));
if (randomBoolean()) { if (randomBoolean()) {
EqlSearchRequest.fetchSize(randomIntBetween(1, Integer.MAX_VALUE)); eqlSearchRequest.fetchSize(randomIntBetween(1, Integer.MAX_VALUE));
} }
if (randomBoolean()) { if (randomBoolean()) {
EqlSearchRequest.eventCategoryField(randomAlphaOfLength(10)); eqlSearchRequest.size(randomInt(Integer.MAX_VALUE));
} }
if (randomBoolean()) { if (randomBoolean()) {
EqlSearchRequest.query(randomAlphaOfLength(10)); eqlSearchRequest.eventCategoryField(randomAlphaOfLength(10));
} }
if (randomBoolean()) { if (randomBoolean()) {
EqlSearchRequest.timestampField(randomAlphaOfLength(10)); eqlSearchRequest.query(randomAlphaOfLength(10));
} }
if (randomBoolean()) { if (randomBoolean()) {
EqlSearchRequest.tiebreakerField(randomAlphaOfLength(10)); eqlSearchRequest.timestampField(randomAlphaOfLength(10));
}
if (randomBoolean()) {
eqlSearchRequest.tiebreakerField(randomAlphaOfLength(10));
} }
if (randomBoolean()) { if (randomBoolean()) {
if (randomBoolean()) { if (randomBoolean()) {
EqlSearchRequest.filter(QueryBuilders.matchAllQuery()); eqlSearchRequest.filter(QueryBuilders.matchAllQuery());
} else { } else {
EqlSearchRequest.filter(QueryBuilders.termQuery(randomAlphaOfLength(10), randomInt(100))); eqlSearchRequest.filter(QueryBuilders.termQuery(randomAlphaOfLength(10), randomInt(100)));
} }
} }
return EqlSearchRequest; return eqlSearchRequest;
} }
@Override @Override
@ -77,6 +80,7 @@ public class EqlSearchRequestTests extends AbstractRequestTestCase<EqlSearchRequ
assertThat(serverInstance.indicesOptions(), equalTo(clientTestInstance.indicesOptions())); assertThat(serverInstance.indicesOptions(), equalTo(clientTestInstance.indicesOptions()));
assertThat(serverInstance.indices(), equalTo(clientTestInstance.indices())); assertThat(serverInstance.indices(), equalTo(clientTestInstance.indices()));
assertThat(serverInstance.fetchSize(), equalTo(clientTestInstance.fetchSize())); assertThat(serverInstance.fetchSize(), equalTo(clientTestInstance.fetchSize()));
assertThat(serverInstance.size(), equalTo(clientTestInstance.size()));
} }
@Override @Override

View File

@ -29,7 +29,7 @@ import static org.hamcrest.Matchers.not;
public abstract class CommonEqlRestTestCase extends ESRestTestCase { public abstract class CommonEqlRestTestCase extends ESRestTestCase {
private static final String defaultValidationIndexName = "eql_search_validation_test"; private static final String defaultValidationIndexName = "eql_search_validation_test";
private static final String validQuery = "process where user = 'SYSTEM'"; private static final String validQuery = "process where user = \\\"SYSTEM\\\"";
@After @After
public void checkSearchContent() throws Exception { public void checkSearchContent() throws Exception {
@ -42,8 +42,7 @@ public abstract class CommonEqlRestTestCase extends ESRestTestCase {
{"{\"query\": \"\"}", "query is null or empty"}, {"{\"query\": \"\"}", "query is null or empty"},
{"{\"query\": \"" + validQuery + "\", \"timestamp_field\": \"\"}", "timestamp field is null or empty"}, {"{\"query\": \"" + validQuery + "\", \"timestamp_field\": \"\"}", "timestamp field is null or empty"},
{"{\"query\": \"" + validQuery + "\", \"event_category_field\": \"\"}", "event category field is null or empty"}, {"{\"query\": \"" + validQuery + "\", \"event_category_field\": \"\"}", "event category field is null or empty"},
{"{\"query\": \"" + validQuery + "\", \"size\": 0}", "size must be greater than 0"}, {"{\"query\": \"" + validQuery + "\", \"size\": -1}", "size must be greater than or equal to 0"},
{"{\"query\": \"" + validQuery + "\", \"size\": -1}", "size must be greater than 0"},
{"{\"query\": \"" + validQuery + "\", \"filter\": null}", "filter doesn't support values of type: VALUE_NULL"}, {"{\"query\": \"" + validQuery + "\", \"filter\": null}", "filter doesn't support values of type: VALUE_NULL"},
{"{\"query\": \"" + validQuery + "\", \"filter\": {}}", "query malformed, empty clause found"} {"{\"query\": \"" + validQuery + "\", \"filter\": {}}", "query malformed, empty clause found"}
}; };

View File

@ -137,8 +137,8 @@ public class EqlSearchRequest extends ActionRequest implements IndicesRequest.Re
validationException = addValidationError("event category field is null or empty", validationException); validationException = addValidationError("event category field is null or empty", validationException);
} }
if (size <= 0) { if (size < 0) {
validationException = addValidationError("size must be greater than 0", validationException); validationException = addValidationError("size must be greater than or equal to 0", validationException);
} }
if (fetchSize < 2) { if (fetchSize < 2) {
@ -329,6 +329,8 @@ public class EqlSearchRequest extends ActionRequest implements IndicesRequest.Re
Arrays.equals(indices, that.indices) && Arrays.equals(indices, that.indices) &&
Objects.equals(indicesOptions, that.indicesOptions) && Objects.equals(indicesOptions, that.indicesOptions) &&
Objects.equals(filter, that.filter) && Objects.equals(filter, that.filter) &&
Objects.equals(size, that.size) &&
Objects.equals(fetchSize, that.fetchSize) &&
Objects.equals(timestampField, that.timestampField) && Objects.equals(timestampField, that.timestampField) &&
Objects.equals(tiebreakerField, that.tiebreakerField) && Objects.equals(tiebreakerField, that.tiebreakerField) &&
Objects.equals(eventCategoryField, that.eventCategoryField) && Objects.equals(eventCategoryField, that.eventCategoryField) &&
@ -338,6 +340,7 @@ public class EqlSearchRequest extends ActionRequest implements IndicesRequest.Re
Objects.equals(isCaseSensitive, that.isCaseSensitive); Objects.equals(isCaseSensitive, that.isCaseSensitive);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash( return Objects.hash(

View File

@ -62,6 +62,7 @@ public class EqlSearchRequestTests extends AbstractSerializingTestCase<EqlSearch
.timestampField(randomAlphaOfLength(10)) .timestampField(randomAlphaOfLength(10))
.eventCategoryField(randomAlphaOfLength(10)) .eventCategoryField(randomAlphaOfLength(10))
.fetchSize(randomIntBetween(1, 50)) .fetchSize(randomIntBetween(1, 50))
.size(randomInt(50))
.query(randomAlphaOfLength(10)); .query(randomAlphaOfLength(10));
return request; return request;