Skip to content

Commit 5de1b5d

Browse files
committed
Add logs and headers
For pipeline creation when name is invalid
1 parent 98c9a70 commit 5de1b5d

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

server/src/main/java/org/elasticsearch/common/Strings.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ private static String changeFirstCharacterCase(String str, boolean capitalize) {
285285
static final Set<Character> INVALID_CHARS = Set.of('\\', '/', '*', '?', '"', '<', '>', '|', ' ', ',');
286286

287287
public static final String INVALID_FILENAME_CHARS = INVALID_CHARS.stream()
288+
.sorted()
288289
.map(c -> "'" + c + "'")
289290
.collect(Collectors.joining(",", "[", "]"));
290291

server/src/main/java/org/elasticsearch/ingest/IngestService.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,16 @@
3939
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
4040
import org.elasticsearch.cluster.metadata.IndexTemplateMetadata;
4141
import org.elasticsearch.cluster.metadata.Metadata;
42+
import org.elasticsearch.cluster.metadata.MetadataCreateIndexService;
4243
import org.elasticsearch.cluster.metadata.MetadataIndexTemplateService;
4344
import org.elasticsearch.cluster.node.DiscoveryNode;
4445
import org.elasticsearch.cluster.service.ClusterService;
4546
import org.elasticsearch.cluster.service.MasterServiceTaskQueue;
4647
import org.elasticsearch.common.Priority;
4748
import org.elasticsearch.common.TriConsumer;
4849
import org.elasticsearch.common.bytes.BytesReference;
50+
import org.elasticsearch.common.logging.DeprecationCategory;
51+
import org.elasticsearch.common.logging.DeprecationLogger;
4952
import org.elasticsearch.common.regex.Regex;
5053
import org.elasticsearch.common.settings.Settings;
5154
import org.elasticsearch.common.util.CollectionUtils;
@@ -55,6 +58,7 @@
5558
import org.elasticsearch.core.Releasable;
5659
import org.elasticsearch.core.TimeValue;
5760
import org.elasticsearch.core.Tuple;
61+
import org.elasticsearch.core.UpdateForV10;
5862
import org.elasticsearch.env.Environment;
5963
import org.elasticsearch.gateway.GatewayService;
6064
import org.elasticsearch.grok.MatcherWatchdog;
@@ -97,6 +101,7 @@
97101
import java.util.stream.Collectors;
98102

99103
import static org.elasticsearch.core.Strings.format;
104+
import static org.elasticsearch.core.UpdateForV10.Owner.DATA_MANAGEMENT;
100105

101106
/**
102107
* Holder class for several ingest related services.
@@ -108,6 +113,7 @@ public class IngestService implements ClusterStateApplier, ReportingService<Inge
108113
public static final String INGEST_ORIGIN = "ingest";
109114

110115
private static final Logger logger = LogManager.getLogger(IngestService.class);
116+
private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(IngestService.class);
111117

112118
private final MasterServiceTaskQueue<PipelineClusterStateUpdateTask> taskQueue;
113119
private final ClusterService clusterService;
@@ -652,12 +658,24 @@ public IngestMetadata execute(IngestMetadata currentIngestMetadata, Collection<I
652658
}
653659
}
654660

661+
@UpdateForV10(owner = DATA_MANAGEMENT) // Change deprecation log for special characters in name to a failure
655662
void validatePipeline(Map<DiscoveryNode, IngestInfo> ingestInfos, String pipelineId, Map<String, Object> pipelineConfig)
656663
throws Exception {
657664
if (ingestInfos.isEmpty()) {
658665
throw new IllegalStateException("Ingest info is empty");
659666
}
660667

668+
try {
669+
MetadataCreateIndexService.validateIndexOrAliasName(
670+
pipelineId,
671+
(pipelineName, error) -> new IllegalArgumentException(
672+
"Pipeline name [" + pipelineName + "] will be disallowed in a future version for the following reason: " + error
673+
)
674+
);
675+
} catch (IllegalArgumentException e) {
676+
deprecationLogger.critical(DeprecationCategory.API, "pipeline_name_special_chars", e.getMessage());
677+
}
678+
661679
Pipeline pipeline = Pipeline.create(pipelineId, pipelineConfig, processorFactories, scriptService);
662680
List<Exception> exceptions = new ArrayList<>();
663681
for (Processor processor : pipeline.flattenAllProcessors()) {

server/src/test/java/org/elasticsearch/ingest/IngestServiceTests.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.elasticsearch.action.ingest.DeletePipelineRequest;
2525
import org.elasticsearch.action.ingest.PutPipelineRequest;
2626
import org.elasticsearch.action.support.ActionTestUtils;
27+
import org.elasticsearch.action.support.master.AcknowledgedRequest;
2728
import org.elasticsearch.action.support.master.AcknowledgedResponse;
2829
import org.elasticsearch.action.update.UpdateRequest;
2930
import org.elasticsearch.client.internal.Client;
@@ -48,6 +49,7 @@
4849
import org.elasticsearch.common.util.concurrent.EsExecutors;
4950
import org.elasticsearch.common.xcontent.XContentHelper;
5051
import org.elasticsearch.core.Strings;
52+
import org.elasticsearch.core.TimeValue;
5153
import org.elasticsearch.core.Tuple;
5254
import org.elasticsearch.index.IndexSettings;
5355
import org.elasticsearch.index.IndexVersion;
@@ -1067,6 +1069,32 @@ public void extraValidation() throws Exception {
10671069
assertEquals("fail_extra_validation", e.getMetadata("es.processor_type").get(0));
10681070
}
10691071

1072+
public void testValidatePipelineName() throws Exception {
1073+
IngestService ingestService = createWithProcessors();
1074+
for (Character badChar : List.of('\\', '/', '*', '?', '"', '<', '>', '|', ' ', ',')) {
1075+
PutPipelineRequest putRequest = new PutPipelineRequest(
1076+
TimeValue.timeValueSeconds(10),
1077+
AcknowledgedRequest.DEFAULT_ACK_TIMEOUT,
1078+
"_id",
1079+
new BytesArray("""
1080+
{"description":"test processor","processors":[{"set":{"field":"_field","value":"_value"}}]}"""),
1081+
XContentType.JSON
1082+
);
1083+
var pipelineConfig = XContentHelper.convertToMap(putRequest.getSource(), false, putRequest.getXContentType()).v2();
1084+
DiscoveryNode node1 = DiscoveryNodeUtils.create("_node_id1", buildNewFakeTransportAddress(), Map.of(), Set.of());
1085+
Map<DiscoveryNode, IngestInfo> ingestInfos = new HashMap<>();
1086+
ingestInfos.put(node1, new IngestInfo(List.of(new ProcessorInfo("set"))));
1087+
final String name = randomAlphaOfLength(5) + badChar + randomAlphaOfLength(5);
1088+
ingestService.validatePipeline(ingestInfos, name, pipelineConfig);
1089+
assertCriticalWarnings(
1090+
"Pipeline name ["
1091+
+ name
1092+
+ "] will be disallowed in a future version for the following reason: must not contain the following characters"
1093+
+ " [' ','\"','*',',','/','<','>','?','\\','|']"
1094+
);
1095+
}
1096+
}
1097+
10701098
public void testExecuteIndexPipelineExistsButFailedParsing() {
10711099
IngestService ingestService = createWithProcessors(
10721100
Map.of("mock", (factories, tag, description, config) -> new AbstractProcessor("mock", "description") {

0 commit comments

Comments
 (0)