diff --git a/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/action/PutAutoFollowPatternRequestTests.java b/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/action/PutAutoFollowPatternRequestTests.java index 47da4aee167..59d00a328e5 100644 --- a/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/action/PutAutoFollowPatternRequestTests.java +++ b/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/action/PutAutoFollowPatternRequestTests.java @@ -123,4 +123,65 @@ public class PutAutoFollowPatternRequestTests extends AbstractSerializingTestCas validationException = request.validate(); assertThat(validationException, nullValue()); } + + public void testValidateName() { + PutAutoFollowPatternAction.Request request = new PutAutoFollowPatternAction.Request(); + request.setRemoteCluster("_alias"); + request.setLeaderIndexPatterns(Collections.singletonList("logs-*")); + + request.setName("name"); + ActionRequestValidationException validationException = request.validate(); + assertThat(validationException, nullValue()); + } + + public void testValidateNameComma() { + PutAutoFollowPatternAction.Request request = new PutAutoFollowPatternAction.Request(); + request.setRemoteCluster("_alias"); + request.setLeaderIndexPatterns(Collections.singletonList("logs-*")); + + request.setName("name1,name2"); + ActionRequestValidationException validationException = request.validate(); + assertThat(validationException, notNullValue()); + assertThat(validationException.getMessage(), containsString("name must not contain a ','")); + } + + public void testValidateNameLeadingUnderscore() { + PutAutoFollowPatternAction.Request request = new PutAutoFollowPatternAction.Request(); + request.setRemoteCluster("_alias"); + request.setLeaderIndexPatterns(Collections.singletonList("logs-*")); + + request.setName("_name"); + ActionRequestValidationException validationException = request.validate(); + assertThat(validationException, notNullValue()); + assertThat(validationException.getMessage(), containsString("name must not start with '_'")); + } + + public void testValidateNameUnderscores() { + PutAutoFollowPatternAction.Request request = new PutAutoFollowPatternAction.Request(); + request.setRemoteCluster("_alias"); + request.setLeaderIndexPatterns(Collections.singletonList("logs-*")); + + request.setName("n_a_m_e_"); + ActionRequestValidationException validationException = request.validate(); + assertThat(validationException, nullValue()); + } + + public void testValidateNameTooLong() { + PutAutoFollowPatternAction.Request request = new PutAutoFollowPatternAction.Request(); + request.setRemoteCluster("_alias"); + request.setLeaderIndexPatterns(Collections.singletonList("logs-*")); + + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < 256; i++) { + stringBuilder.append('x'); + } + request.setName(stringBuilder.toString()); + ActionRequestValidationException validationException = request.validate(); + assertThat(validationException, notNullValue()); + assertThat(validationException.getMessage(), containsString("name is too long (256 > 255)")); + + request.setName("name"); + validationException = request.validate(); + assertThat(validationException, nullValue()); + } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/PutAutoFollowPatternAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/PutAutoFollowPatternAction.java index 58ecd170404..d0969850705 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/PutAutoFollowPatternAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/PutAutoFollowPatternAction.java @@ -21,6 +21,7 @@ import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.xpack.core.ccr.AutoFollowMetadata.AutoFollowPattern; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Objects; @@ -44,8 +45,8 @@ public class PutAutoFollowPatternAction extends Action { public static class Request extends AcknowledgedRequest implements ToXContentObject { private static final ObjectParser PARSER = new ObjectParser<>("put_auto_follow_pattern_request", Request::new); - private static final ParseField NAME_FIELD = new ParseField("name"); + private static final int MAX_NAME_BYTES = 255; static { PARSER.declareString(Request::setName, NAME_FIELD); @@ -119,6 +120,21 @@ public class PutAutoFollowPatternAction extends Action { if (name == null) { validationException = addValidationError("[" + NAME_FIELD.getPreferredName() + "] is missing", validationException); } + if (name != null) { + if (name.contains(",")) { + validationException = addValidationError("[" + NAME_FIELD.getPreferredName() + "] name must not contain a ','", + validationException); + } + if (name.startsWith("_")) { + validationException = addValidationError("[" + NAME_FIELD.getPreferredName() + "] name must not start with '_'", + validationException); + } + int byteCount = name.getBytes(StandardCharsets.UTF_8).length; + if (byteCount > MAX_NAME_BYTES) { + validationException = addValidationError("[" + NAME_FIELD.getPreferredName() + "] name is too long (" + + byteCount + " > " + MAX_NAME_BYTES + ")", validationException); + } + } if (remoteCluster == null) { validationException = addValidationError("[" + REMOTE_CLUSTER_FIELD.getPreferredName() + "] is missing", validationException);