diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java b/server/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java index 43125823e0e20..33c9bfba9fe6e 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java @@ -1340,4 +1340,28 @@ static String resolveExpression(String expression, final Context context) { return beforePlaceHolderSb.toString(); } } + + /** + * This is a context for the DateMathExpressionResolver which does not require {@code IndicesOptions} or {@code ClusterState} + * since it uses only the start time to resolve expressions. + */ + public static final class ResolverContext extends Context { + public ResolverContext() { + this(System.currentTimeMillis()); + } + + public ResolverContext(long startTime) { + super(null, null, startTime, false, false, false, false, SystemIndexAccessLevel.ALL, name -> false, name -> false); + } + + @Override + public ClusterState getState() { + throw new UnsupportedOperationException("should never be called"); + } + + @Override + public IndicesOptions getOptions() { + throw new UnsupportedOperationException("should never be called"); + } + } } diff --git a/server/src/main/java/org/elasticsearch/ingest/IngestService.java b/server/src/main/java/org/elasticsearch/ingest/IngestService.java index 4985836d110dc..87f83472f52f7 100644 --- a/server/src/main/java/org/elasticsearch/ingest/IngestService.java +++ b/server/src/main/java/org/elasticsearch/ingest/IngestService.java @@ -28,6 +28,7 @@ import org.elasticsearch.cluster.ClusterStateApplier; import org.elasticsearch.cluster.metadata.IndexAbstraction; import org.elasticsearch.cluster.metadata.IndexMetadata; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.metadata.IndexTemplateMetadata; import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.metadata.MetadataIndexTemplateService; @@ -75,6 +76,8 @@ public class IngestService implements ClusterStateApplier, ReportingService processorFactories(List originalRequest, final IndexRequest indexRequest, - final Metadata metadata) { + final Metadata metadata) { + return resolvePipelines(originalRequest, indexRequest, metadata, System.currentTimeMillis()); + } + + public static boolean resolvePipelines(final DocWriteRequest originalRequest, final IndexRequest indexRequest, + final Metadata metadata, final long epochMillis) { if (indexRequest.isPipelineResolved() == false) { final String requestPipeline = indexRequest.getPipeline(); indexRequest.setPipeline(NOOP_PIPELINE_NAME); @@ -133,7 +141,7 @@ public static boolean resolvePipelines(final DocWriteRequest originalRequest, IndexMetadata indexMetadata = null; // start to look for default or final pipelines via settings found in the index meta data if (originalRequest != null) { - indexMetadata = metadata.indices().get(originalRequest.index()); + indexMetadata = metadata.indices().get(resolveIndexName(originalRequest.index(), epochMillis)); } // check the alias for the index request (this is how normal index requests are modeled) if (indexMetadata == null && indexRequest.index() != null) { @@ -219,12 +227,20 @@ public static boolean resolvePipelines(final DocWriteRequest originalRequest, indexRequest.isPipelineResolved(true); } - // return whether this index request has a pipeline return NOOP_PIPELINE_NAME.equals(indexRequest.getPipeline()) == false || NOOP_PIPELINE_NAME.equals(indexRequest.getFinalPipeline()) == false; } + private static String resolveIndexName(final String unresolvedIndexName, final long epochMillis) { + List resolvedNames = DATE_MATH_EXPRESSION_RESOLVER.resolve( + new IndexNameExpressionResolver.ResolverContext(epochMillis), + org.elasticsearch.core.List.of(unresolvedIndexName) + ); + assert resolvedNames.size() == 1; + return resolvedNames.get(0); + } + public ClusterService getClusterService() { return clusterService; } diff --git a/server/src/test/java/org/elasticsearch/ingest/IngestServiceTests.java b/server/src/test/java/org/elasticsearch/ingest/IngestServiceTests.java index b461c44f8198c..6d84852049dec 100644 --- a/server/src/test/java/org/elasticsearch/ingest/IngestServiceTests.java +++ b/server/src/test/java/org/elasticsearch/ingest/IngestServiceTests.java @@ -37,6 +37,7 @@ import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.time.DateFormatter; import org.elasticsearch.common.util.concurrent.EsExecutors; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentType; @@ -1399,6 +1400,24 @@ public void testResolveFinalPipeline() { assertThat(indexRequest.getFinalPipeline(), equalTo("final-pipeline")); } + public void testResolveFinalPipelineWithDateMathExpression() { + final long epochMillis = randomLongBetween(1, System.currentTimeMillis()); + final DateFormatter dateFormatter = DateFormatter.forPattern("uuuu.MM.dd"); + IndexMetadata.Builder builder = IndexMetadata.builder("idx-" + dateFormatter.formatMillis(epochMillis)) + .settings(settings(Version.CURRENT).put(IndexSettings.FINAL_PIPELINE.getKey(), "final-pipeline")) + .numberOfShards(1) + .numberOfReplicas(0); + Metadata metadata = Metadata.builder().put(builder).build(); + + // index name matches with IDM: + IndexRequest indexRequest = new IndexRequest(""); + boolean result = IngestService.resolvePipelines(indexRequest, indexRequest, metadata, epochMillis); + assertThat(result, is(true)); + assertThat(indexRequest.isPipelineResolved(), is(true)); + assertThat(indexRequest.getPipeline(), equalTo("_none")); + assertThat(indexRequest.getFinalPipeline(), equalTo("final-pipeline")); + } + public void testResolveRequestOrDefaultPipelineAndFinalPipeline() { // no pipeline: { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/GenerateSnapshotNameStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/GenerateSnapshotNameStep.java index d05a77d980e91..63686014ba354 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/GenerateSnapshotNameStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/GenerateSnapshotNameStep.java @@ -9,7 +9,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.action.ActionRequestValidationException; -import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; @@ -18,7 +17,6 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.UUIDs; import org.elasticsearch.index.Index; -import org.elasticsearch.indices.SystemIndices.SystemIndexAccessLevel; import java.util.Collections; import java.util.List; @@ -117,7 +115,7 @@ public boolean equals(Object obj) { * still result in unique snapshot names. */ public static String generateSnapshotName(String name) { - return generateSnapshotName(name, new ResolverContext()); + return generateSnapshotName(name, new IndexNameExpressionResolver.ResolverContext()); } public static String generateSnapshotName(String name, IndexNameExpressionResolver.Context context) { @@ -129,31 +127,6 @@ public static String generateSnapshotName(String name, IndexNameExpressionResolv return candidates.get(0) + "-" + UUIDs.randomBase64UUID().toLowerCase(Locale.ROOT); } - /** - * This is a context for the DateMathExpressionResolver, which does not require - * {@code IndicesOptions} or {@code ClusterState} since it only uses the start - * time to resolve expressions - */ - public static final class ResolverContext extends IndexNameExpressionResolver.Context { - public ResolverContext() { - this(System.currentTimeMillis()); - } - - public ResolverContext(long startTime) { - super(null, null, startTime, false, false, false, false, SystemIndexAccessLevel.ALL, name -> false, name -> false); - } - - @Override - public ClusterState getState() { - throw new UnsupportedOperationException("should never be called"); - } - - @Override - public IndicesOptions getOptions() { - throw new UnsupportedOperationException("should never be called"); - } - } - @Nullable public static ActionRequestValidationException validateGeneratedSnapshotName(String snapshotPrefix, String snapshotName) { ActionRequestValidationException err = new ActionRequestValidationException(); diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/GenerateSnapshotNameStepTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/GenerateSnapshotNameStepTests.java index 3cbf4276e2e7c..9c292e4863b79 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/GenerateSnapshotNameStepTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/GenerateSnapshotNameStepTests.java @@ -10,6 +10,7 @@ import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.IndexMetadata; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.common.Strings; @@ -86,7 +87,7 @@ public void testNameGeneration() { assertThat(generateSnapshotName("name"), startsWith("name-")); assertThat(generateSnapshotName("name").length(), greaterThan("name-".length())); - GenerateSnapshotNameStep.ResolverContext resolverContext = new GenerateSnapshotNameStep.ResolverContext(time); + IndexNameExpressionResolver.ResolverContext resolverContext = new IndexNameExpressionResolver.ResolverContext(time); assertThat(generateSnapshotName("", resolverContext), startsWith("name-2019.03.15-")); assertThat(generateSnapshotName("", resolverContext).length(), greaterThan("name-2019.03.15-".length()));