[7.16][Transform] Improve transform upgrader (#79601) (#79700)

* [Transform] Improve transform upgrader (#79601)

This changes fixes some issues with the upgrader. It inlines the index name resolver as wildcard
deletes are not supported if action.destructive_requires_name is set to true(default). It changes
response to always return all counters in order to avoid an empty response. After documentation has
been created, it switches the deprecation URL to the upgrade API docs.

* change url to 7.16 specific one

* fix 7.x specific test

* fix put mapping call
This commit is contained in:
Hendrik Muhs 2021-10-25 13:49:08 +02:00 committed by GitHub
parent 3bf295490a
commit 6405fea8e4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 188 additions and 63 deletions

View file

@ -37,15 +37,9 @@ public class UpgradeTransformsResponseTests extends ESTestCase {
private static void toXContent(UpgradeTransformsResponse response, XContentBuilder builder) throws IOException { private static void toXContent(UpgradeTransformsResponse response, XContentBuilder builder) throws IOException {
builder.startObject(); builder.startObject();
if (response.getUpdated() != 0) { builder.field("updated", response.getUpdated());
builder.field("updated", response.getUpdated()); builder.field("no_action", response.getNoAction());
} builder.field("needs_update", response.getNeedsUpdate());
if (response.getNoAction() != 0) {
builder.field("no_action", response.getNoAction());
}
if (response.getNeedsUpdate() != 0) {
builder.field("needs_update", response.getNeedsUpdate());
}
builder.endObject(); builder.endObject();
} }

View file

@ -8,6 +8,10 @@
package org.elasticsearch.xpack.core.transform; package org.elasticsearch.xpack.core.transform;
public class TransformDeprecations { public class TransformDeprecations {
public static final String UPGRADE_TRANSFORM_URL = "https://ela.st/es-7-upgrade-transforms";
// breaking changes base url for the _next_ major release
public static final String BREAKING_CHANGES_BASE_URL = public static final String BREAKING_CHANGES_BASE_URL =
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-8.0.html"; "https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-8.0.html";
@ -15,5 +19,10 @@ public class TransformDeprecations {
public static final String AGGS_BREAKING_CHANGES_URL = BREAKING_CHANGES_BASE_URL + "#breaking_80_aggregations_changes"; public static final String AGGS_BREAKING_CHANGES_URL = BREAKING_CHANGES_BASE_URL + "#breaking_80_aggregations_changes";
public static final String ACTION_UPGRADE_TRANSFORMS_API = "Use the upgrade transforms API to fix your transforms.";
public static final String ACTION_MAX_PAGE_SEARCH_SIZE_IS_DEPRECATED =
"[max_page_search_size] is deprecated inside pivot. Use settings instead.";
private TransformDeprecations() {} private TransformDeprecations() {}
} }

View file

@ -125,15 +125,9 @@ public class UpgradeTransformsAction extends ActionType<UpgradeTransformsAction.
@Override @Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(); builder.startObject();
if (updated != 0L) { builder.field("updated", updated);
builder.field("updated", updated); builder.field("no_action", noAction);
} builder.field("needs_update", needsUpdate);
if (noAction != 0L) {
builder.field("no_action", noAction);
}
if (needsUpdate != 0L) {
builder.field("needs_update", needsUpdate);
}
builder.endObject(); builder.endObject();
return builder; return builder;
} }

View file

@ -14,6 +14,8 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.xcontent.ConstructingObjectParser; import org.elasticsearch.xcontent.ConstructingObjectParser;
import org.elasticsearch.xcontent.NamedXContentRegistry; import org.elasticsearch.xcontent.NamedXContentRegistry;
import org.elasticsearch.xcontent.ObjectParser; import org.elasticsearch.xcontent.ObjectParser;
@ -21,8 +23,6 @@ import org.elasticsearch.xcontent.ParseField;
import org.elasticsearch.xcontent.ToXContentObject; import org.elasticsearch.xcontent.ToXContentObject;
import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xcontent.XContentParser; import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.xpack.core.common.time.TimeUtils; import org.elasticsearch.xpack.core.common.time.TimeUtils;
import org.elasticsearch.xpack.core.common.validation.SourceDestValidator; import org.elasticsearch.xpack.core.common.validation.SourceDestValidator;
import org.elasticsearch.xpack.core.common.validation.SourceDestValidator.SourceDestValidation; import org.elasticsearch.xpack.core.common.validation.SourceDestValidator.SourceDestValidation;
@ -402,8 +402,8 @@ public class TransformConfig extends AbstractDiffable<TransformConfig> implement
new DeprecationIssue( new DeprecationIssue(
Level.CRITICAL, Level.CRITICAL,
"Transform [" + id + "] is too old", "Transform [" + id + "] is too old",
TransformDeprecations.BREAKING_CHANGES_BASE_URL, TransformDeprecations.UPGRADE_TRANSFORM_URL,
"The configuration uses an old format, you can use [_update] or [_upgrade] to update", TransformDeprecations.ACTION_UPGRADE_TRANSFORMS_API,
false, false,
null null
) )

View file

@ -13,13 +13,13 @@ import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.logging.DeprecationCategory; import org.elasticsearch.common.logging.DeprecationCategory;
import org.elasticsearch.common.logging.DeprecationLogger; import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.search.aggregations.MultiBucketConsumerService;
import org.elasticsearch.xcontent.ConstructingObjectParser; import org.elasticsearch.xcontent.ConstructingObjectParser;
import org.elasticsearch.xcontent.NamedXContentRegistry; import org.elasticsearch.xcontent.NamedXContentRegistry;
import org.elasticsearch.xcontent.ToXContentObject; import org.elasticsearch.xcontent.ToXContentObject;
import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xcontent.XContentParser; import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.search.aggregations.MultiBucketConsumerService;
import org.elasticsearch.xpack.core.deprecation.DeprecationIssue; import org.elasticsearch.xpack.core.deprecation.DeprecationIssue;
import org.elasticsearch.xpack.core.deprecation.DeprecationIssue.Level; import org.elasticsearch.xpack.core.deprecation.DeprecationIssue.Level;
import org.elasticsearch.xpack.core.transform.TransformDeprecations; import org.elasticsearch.xpack.core.transform.TransformDeprecations;
@ -91,7 +91,7 @@ public class PivotConfig implements Writeable, ToXContentObject {
deprecationLogger.critical( deprecationLogger.critical(
DeprecationCategory.API, DeprecationCategory.API,
TransformField.MAX_PAGE_SEARCH_SIZE.getPreferredName(), TransformField.MAX_PAGE_SEARCH_SIZE.getPreferredName(),
"[max_page_search_size] is deprecated inside pivot please use settings instead" TransformDeprecations.ACTION_MAX_PAGE_SEARCH_SIZE_IS_DEPRECATED
); );
} }
} }
@ -187,7 +187,7 @@ public class PivotConfig implements Writeable, ToXContentObject {
Level.WARNING, Level.WARNING,
"Transform [" + id + "] uses deprecated max_page_search_size", "Transform [" + id + "] uses deprecated max_page_search_size",
TransformDeprecations.BREAKING_CHANGES_BASE_URL, TransformDeprecations.BREAKING_CHANGES_BASE_URL,
"[max_page_search_size] is deprecated inside pivot please use settings instead", TransformDeprecations.ACTION_MAX_PAGE_SEARCH_SIZE_IS_DEPRECATED,
false, false,
null null
) )

View file

@ -28,6 +28,7 @@ import org.elasticsearch.xpack.core.common.validation.SourceDestValidator.Source
import org.elasticsearch.xpack.core.deprecation.DeprecationIssue; import org.elasticsearch.xpack.core.deprecation.DeprecationIssue;
import org.elasticsearch.xpack.core.deprecation.DeprecationIssue.Level; import org.elasticsearch.xpack.core.deprecation.DeprecationIssue.Level;
import org.elasticsearch.xpack.core.transform.AbstractSerializingTransformTestCase; import org.elasticsearch.xpack.core.transform.AbstractSerializingTransformTestCase;
import org.elasticsearch.xpack.core.transform.TransformDeprecations;
import org.elasticsearch.xpack.core.transform.transforms.latest.LatestConfig; import org.elasticsearch.xpack.core.transform.transforms.latest.LatestConfig;
import org.elasticsearch.xpack.core.transform.transforms.latest.LatestConfigTests; import org.elasticsearch.xpack.core.transform.transforms.latest.LatestConfigTests;
import org.elasticsearch.xpack.core.transform.transforms.pivot.PivotConfig; import org.elasticsearch.xpack.core.transform.transforms.pivot.PivotConfig;
@ -510,7 +511,7 @@ public class TransformConfigTests extends AbstractSerializingTransformTestCase<T
assertTrue(transformConfigRewritten.getSettings().getDatesAsEpochMillis()); assertTrue(transformConfigRewritten.getSettings().getDatesAsEpochMillis());
assertFalse(transformConfigRewritten.getSettings().getAlignCheckpoints()); assertFalse(transformConfigRewritten.getSettings().getAlignCheckpoints());
assertWarnings("[max_page_search_size] is deprecated inside pivot please use settings instead"); assertWarnings(TransformDeprecations.ACTION_MAX_PAGE_SEARCH_SIZE_IS_DEPRECATED);
assertEquals(Version.CURRENT, transformConfigRewritten.getVersion()); assertEquals(Version.CURRENT, transformConfigRewritten.getVersion());
} }
@ -583,7 +584,7 @@ public class TransformConfigTests extends AbstractSerializingTransformTestCase<T
assertNotNull(transformConfigRewritten.getSettings().getMaxPageSearchSize()); assertNotNull(transformConfigRewritten.getSettings().getMaxPageSearchSize());
assertEquals(555L, transformConfigRewritten.getSettings().getMaxPageSearchSize().longValue()); assertEquals(555L, transformConfigRewritten.getSettings().getMaxPageSearchSize().longValue());
assertEquals(Version.CURRENT, transformConfigRewritten.getVersion()); assertEquals(Version.CURRENT, transformConfigRewritten.getVersion());
assertWarnings("[max_page_search_size] is deprecated inside pivot please use settings instead"); assertWarnings(TransformDeprecations.ACTION_MAX_PAGE_SEARCH_SIZE_IS_DEPRECATED);
} }
public void testRewriteForBWCOfDateNormalization() throws IOException { public void testRewriteForBWCOfDateNormalization() throws IOException {
@ -739,7 +740,7 @@ public class TransformConfigTests extends AbstractSerializingTransformTestCase<T
TransformConfig deprecatedConfig = randomTransformConfigWithDeprecatedFields(id, Version.CURRENT); TransformConfig deprecatedConfig = randomTransformConfigWithDeprecatedFields(id, Version.CURRENT);
// check _and_ clear warnings // check _and_ clear warnings
assertWarnings("[max_page_search_size] is deprecated inside pivot please use settings instead"); assertWarnings(TransformDeprecations.ACTION_MAX_PAGE_SEARCH_SIZE_IS_DEPRECATED);
// important: checkForDeprecations does _not_ create new deprecation warnings // important: checkForDeprecations does _not_ create new deprecation warnings
assertThat( assertThat(
@ -749,8 +750,8 @@ public class TransformConfigTests extends AbstractSerializingTransformTestCase<T
new DeprecationIssue( new DeprecationIssue(
Level.WARNING, Level.WARNING,
"Transform [" + id + "] uses deprecated max_page_search_size", "Transform [" + id + "] uses deprecated max_page_search_size",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-8.0.html", TransformDeprecations.BREAKING_CHANGES_BASE_URL,
"[max_page_search_size] is deprecated inside pivot please use settings instead", TransformDeprecations.ACTION_MAX_PAGE_SEARCH_SIZE_IS_DEPRECATED,
false, false,
null null
) )
@ -761,7 +762,7 @@ public class TransformConfigTests extends AbstractSerializingTransformTestCase<T
deprecatedConfig = randomTransformConfigWithDeprecatedFields(id, Version.V_7_10_0); deprecatedConfig = randomTransformConfigWithDeprecatedFields(id, Version.V_7_10_0);
// check _and_ clear warnings // check _and_ clear warnings
assertWarnings("[max_page_search_size] is deprecated inside pivot please use settings instead"); assertWarnings(TransformDeprecations.ACTION_MAX_PAGE_SEARCH_SIZE_IS_DEPRECATED);
// important: checkForDeprecations does _not_ create new deprecation warnings // important: checkForDeprecations does _not_ create new deprecation warnings
assertThat( assertThat(
@ -771,8 +772,8 @@ public class TransformConfigTests extends AbstractSerializingTransformTestCase<T
new DeprecationIssue( new DeprecationIssue(
Level.WARNING, Level.WARNING,
"Transform [" + id + "] uses deprecated max_page_search_size", "Transform [" + id + "] uses deprecated max_page_search_size",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-8.0.html", TransformDeprecations.BREAKING_CHANGES_BASE_URL,
"[max_page_search_size] is deprecated inside pivot please use settings instead", TransformDeprecations.ACTION_MAX_PAGE_SEARCH_SIZE_IS_DEPRECATED,
false, false,
null null
) )
@ -783,7 +784,7 @@ public class TransformConfigTests extends AbstractSerializingTransformTestCase<T
deprecatedConfig = randomTransformConfigWithDeprecatedFields(id, Version.V_7_4_0); deprecatedConfig = randomTransformConfigWithDeprecatedFields(id, Version.V_7_4_0);
// check _and_ clear warnings // check _and_ clear warnings
assertWarnings("[max_page_search_size] is deprecated inside pivot please use settings instead"); assertWarnings(TransformDeprecations.ACTION_MAX_PAGE_SEARCH_SIZE_IS_DEPRECATED);
// important: checkForDeprecations does _not_ create new deprecation warnings // important: checkForDeprecations does _not_ create new deprecation warnings
assertThat( assertThat(
@ -793,16 +794,16 @@ public class TransformConfigTests extends AbstractSerializingTransformTestCase<T
new DeprecationIssue( new DeprecationIssue(
Level.CRITICAL, Level.CRITICAL,
"Transform [" + id + "] is too old", "Transform [" + id + "] is too old",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-8.0.html", TransformDeprecations.UPGRADE_TRANSFORM_URL,
"The configuration uses an old format, you can use [_update] or [_upgrade] to update", TransformDeprecations.ACTION_UPGRADE_TRANSFORMS_API,
false, false,
null null
), ),
new DeprecationIssue( new DeprecationIssue(
Level.WARNING, Level.WARNING,
"Transform [" + id + "] uses deprecated max_page_search_size", "Transform [" + id + "] uses deprecated max_page_search_size",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-8.0.html", TransformDeprecations.BREAKING_CHANGES_BASE_URL,
"[max_page_search_size] is deprecated inside pivot please use settings instead", TransformDeprecations.ACTION_MAX_PAGE_SEARCH_SIZE_IS_DEPRECATED,
false, false,
null null
) )

View file

@ -15,6 +15,7 @@ import org.elasticsearch.xcontent.DeprecationHandler;
import org.elasticsearch.xcontent.XContentParser; import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xcontent.XContentType;
import org.elasticsearch.xpack.core.transform.AbstractSerializingTransformTestCase; import org.elasticsearch.xpack.core.transform.AbstractSerializingTransformTestCase;
import org.elasticsearch.xpack.core.transform.TransformDeprecations;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
@ -437,7 +438,7 @@ public class PivotConfigTests extends AbstractSerializingTransformTestCase<Pivot
public void testDeprecation() { public void testDeprecation() {
PivotConfig pivotConfig = randomPivotConfigWithDeprecatedFields(); PivotConfig pivotConfig = randomPivotConfigWithDeprecatedFields();
assertWarnings("[max_page_search_size] is deprecated inside pivot please use settings instead"); assertWarnings(TransformDeprecations.ACTION_MAX_PAGE_SEARCH_SIZE_IS_DEPRECATED);
} }
private static String dotJoin(String... fields) { private static String dotJoin(String... fields) {

View file

@ -41,6 +41,7 @@ import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.index.shard.ShardPath; import org.elasticsearch.index.shard.ShardPath;
import org.elasticsearch.index.store.StoreStats; import org.elasticsearch.index.store.StoreStats;
import org.elasticsearch.index.warmer.WarmerStats; import org.elasticsearch.index.warmer.WarmerStats;
import org.elasticsearch.indices.TestIndexNameExpressionResolver;
import org.elasticsearch.search.suggest.completion.CompletionStats; import org.elasticsearch.search.suggest.completion.CompletionStats;
import org.elasticsearch.test.client.NoOpClient; import org.elasticsearch.test.client.NoOpClient;
import org.elasticsearch.xpack.core.transform.transforms.TransformCheckpoint; import org.elasticsearch.xpack.core.transform.transforms.TransformCheckpoint;
@ -138,8 +139,13 @@ public class TransformCheckpointServiceNodeTests extends TransformSingleNodeTest
if (mockClientForCheckpointing == null) { if (mockClientForCheckpointing == null) {
mockClientForCheckpointing = new MockClientForCheckpointing("TransformCheckpointServiceNodeTests"); mockClientForCheckpointing = new MockClientForCheckpointing("TransformCheckpointServiceNodeTests");
} }
ClusterService clusterService = mock(ClusterService.class);
transformsConfigManager = new IndexBasedTransformConfigManager(client(), xContentRegistry()); transformsConfigManager = new IndexBasedTransformConfigManager(
clusterService,
TestIndexNameExpressionResolver.newInstance(),
client(),
xContentRegistry()
);
// use a mock for the checkpoint service // use a mock for the checkpoint service
TransformAuditor mockAuditor = mock(TransformAuditor.class); TransformAuditor mockAuditor = mock(TransformAuditor.class);

View file

@ -9,14 +9,30 @@ package org.elasticsearch.xpack.transform.persistence;
import org.elasticsearch.ResourceAlreadyExistsException; import org.elasticsearch.ResourceAlreadyExistsException;
import org.elasticsearch.ResourceNotFoundException; import org.elasticsearch.ResourceNotFoundException;
import org.elasticsearch.Version;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.Metadata;
import org.elasticsearch.cluster.routing.IndexRoutingTable;
import org.elasticsearch.cluster.routing.RoutingTable;
import org.elasticsearch.cluster.routing.ShardRoutingState;
import org.elasticsearch.cluster.routing.TestShardRouting;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.core.Tuple; import org.elasticsearch.core.Tuple;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.indices.TestIndexNameExpressionResolver;
import org.elasticsearch.xcontent.ToXContent; import org.elasticsearch.xcontent.ToXContent;
import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xcontent.XContentFactory; import org.elasticsearch.xcontent.XContentFactory;
@ -33,6 +49,7 @@ import org.elasticsearch.xpack.core.transform.transforms.persistence.TransformIn
import org.elasticsearch.xpack.transform.TransformSingleNodeTestCase; import org.elasticsearch.xpack.transform.TransformSingleNodeTestCase;
import org.junit.Before; import org.junit.Before;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@ -45,19 +62,29 @@ import java.util.stream.Collectors;
import static java.util.Collections.emptyMap; import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static org.elasticsearch.core.Tuple.tuple; import static org.elasticsearch.core.Tuple.tuple;
import static org.elasticsearch.index.mapper.MapperService.SINGLE_MAPPING_NAME;
import static org.elasticsearch.xpack.transform.persistence.TransformConfigManager.TO_XCONTENT_PARAMS; import static org.elasticsearch.xpack.transform.persistence.TransformConfigManager.TO_XCONTENT_PARAMS;
import static org.elasticsearch.xpack.transform.persistence.TransformInternalIndex.mappings; import static org.elasticsearch.xpack.transform.persistence.TransformInternalIndex.mappings;
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.instanceOf;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class TransformConfigManagerTests extends TransformSingleNodeTestCase { public class TransformConfigManagerTests extends TransformSingleNodeTestCase {
private IndexBasedTransformConfigManager transformConfigManager; private IndexBasedTransformConfigManager transformConfigManager;
private ClusterService clusterService;
@Before @Before
public void createComponents() { public void createComponents() {
transformConfigManager = new IndexBasedTransformConfigManager(client(), xContentRegistry()); clusterService = mock(ClusterService.class);
transformConfigManager = new IndexBasedTransformConfigManager(
clusterService,
TestIndexNameExpressionResolver.newInstance(),
client(),
xContentRegistry()
);
} }
public void testGetMissingTransform() throws InterruptedException { public void testGetMissingTransform() throws InterruptedException {
@ -706,6 +733,10 @@ public class TransformConfigManagerTests extends TransformSingleNodeTestCase {
assertAsync(listener -> transformConfigManager.getTransformConfiguration(transformId, listener), transformConfigNew, null, null); assertAsync(listener -> transformConfigManager.getTransformConfiguration(transformId, listener), transformConfigNew, null, null);
// delete old indices // delete old indices
when(clusterService.state()).thenReturn(
createClusterStateWithTransformIndex(oldIndex, TransformInternalIndexConstants.LATEST_INDEX_NAME)
);
assertAsync(listener -> transformConfigManager.deleteOldIndices(listener), true, null, null); assertAsync(listener -> transformConfigManager.deleteOldIndices(listener), true, null, null);
// the config should still be there // the config should still be there
@ -724,4 +755,32 @@ public class TransformConfigManagerTests extends TransformSingleNodeTestCase {
); );
} }
private static ClusterState createClusterStateWithTransformIndex(String... indexes) throws IOException {
ImmutableOpenMap.Builder<String, IndexMetadata> indexMapBuilder = ImmutableOpenMap.builder();
Metadata.Builder metaBuilder = Metadata.builder();
ClusterState.Builder csBuilder = ClusterState.builder(ClusterName.DEFAULT);
RoutingTable.Builder routingTableBuilder = RoutingTable.builder();
for (String index : indexes) {
IndexMetadata.Builder builder = new IndexMetadata.Builder(index).settings(
Settings.builder()
.put(TransformInternalIndex.settings())
.put(IndexMetadata.SETTING_INDEX_VERSION_CREATED.getKey(), Version.CURRENT)
.build()
).numberOfReplicas(0).numberOfShards(1).putMapping(SINGLE_MAPPING_NAME, Strings.toString(TransformInternalIndex.mappings()));
indexMapBuilder.put(index, builder.build());
routingTableBuilder.add(
IndexRoutingTable.builder(new Index(index, UUIDs.randomBase64UUID()))
.addShard(TestShardRouting.newShardRouting(index, 0, "node_a", null, true, ShardRoutingState.STARTED))
.build()
);
}
csBuilder.routingTable(routingTableBuilder.build());
metaBuilder.indices(indexMapBuilder.build());
csBuilder.metadata(metaBuilder.build());
return csBuilder.build();
}
} }

View file

@ -318,7 +318,12 @@ public class Transform extends Plugin implements SystemIndexPlugin, PersistentTa
return emptyList(); return emptyList();
} }
TransformConfigManager configManager = new IndexBasedTransformConfigManager(client, xContentRegistry); TransformConfigManager configManager = new IndexBasedTransformConfigManager(
clusterService,
expressionResolver,
client,
xContentRegistry
);
TransformAuditor auditor = new TransformAuditor(client, clusterService.getNodeName(), clusterService); TransformAuditor auditor = new TransformAuditor(client, clusterService.getNodeName(), clusterService);
TransformCheckpointService checkpointService = new TransformCheckpointService( TransformCheckpointService checkpointService = new TransformCheckpointService(
Clock.systemUTC(), Clock.systemUTC(),

View file

@ -28,9 +28,13 @@ import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.client.Client; import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
import org.elasticsearch.core.Tuple; import org.elasticsearch.core.Tuple;
import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.index.IndexNotFoundException;
@ -64,6 +68,7 @@ import org.elasticsearch.xpack.core.transform.transforms.persistence.TransformIn
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
@ -99,10 +104,19 @@ public class IndexBasedTransformConfigManager implements TransformConfigManager
private static final Logger logger = LogManager.getLogger(IndexBasedTransformConfigManager.class); private static final Logger logger = LogManager.getLogger(IndexBasedTransformConfigManager.class);
private static final int MAX_RESULTS_WINDOW = 10_000; private static final int MAX_RESULTS_WINDOW = 10_000;
private final ClusterService clusterService;
private final IndexNameExpressionResolver indexNameExpressionResolver;
private final Client client; private final Client client;
private final NamedXContentRegistry xContentRegistry; private final NamedXContentRegistry xContentRegistry;
public IndexBasedTransformConfigManager(Client client, NamedXContentRegistry xContentRegistry) { public IndexBasedTransformConfigManager(
ClusterService clusterService,
IndexNameExpressionResolver indexNameExpressionResolver,
Client client,
NamedXContentRegistry xContentRegistry
) {
this.clusterService = clusterService;
this.indexNameExpressionResolver = indexNameExpressionResolver;
this.client = client; this.client = client;
this.xContentRegistry = xContentRegistry; this.xContentRegistry = xContentRegistry;
} }
@ -255,11 +269,42 @@ public class IndexBasedTransformConfigManager implements TransformConfigManager
@Override @Override
public void deleteOldIndices(ActionListener<Boolean> listener) { public void deleteOldIndices(ActionListener<Boolean> listener) {
DeleteIndexRequest deleteRequest = new DeleteIndexRequest( ClusterState state = clusterService.state();
TransformInternalIndexConstants.INDEX_NAME_PATTERN, Set<String> indicesToDelete = new HashSet<>();
TransformInternalIndexConstants.INDEX_NAME_PATTERN_DEPRECATED,
"-" + TransformInternalIndexConstants.LATEST_INDEX_VERSIONED_NAME // use the transform context as we access system indexes
).indicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN); try (ThreadContext.StoredContext ctx = client.threadPool().getThreadContext().stashWithOrigin(TRANSFORM_ORIGIN)) {
indicesToDelete.addAll(
Arrays.asList(
indexNameExpressionResolver.concreteIndexNames(
state,
IndicesOptions.lenientExpandHidden(),
TransformInternalIndexConstants.INDEX_NAME_PATTERN
)
)
);
indicesToDelete.addAll(
Arrays.asList(
indexNameExpressionResolver.concreteIndexNames(
state,
IndicesOptions.lenientExpandHidden(),
TransformInternalIndexConstants.INDEX_NAME_PATTERN_DEPRECATED
)
)
);
indicesToDelete.remove(TransformInternalIndexConstants.LATEST_INDEX_VERSIONED_NAME);
}
if (indicesToDelete.isEmpty()) {
listener.onResponse(true);
return;
}
DeleteIndexRequest deleteRequest = new DeleteIndexRequest(indicesToDelete.toArray(new String[0])).indicesOptions(
IndicesOptions.LENIENT_EXPAND_OPEN
);
executeAsyncWithOrigin(client, TRANSFORM_ORIGIN, DeleteIndexAction.INSTANCE, deleteRequest, ActionListener.wrap(response -> { executeAsyncWithOrigin(client, TRANSFORM_ORIGIN, DeleteIndexAction.INSTANCE, deleteRequest, ActionListener.wrap(response -> {
if (response.isAcknowledged() == false) { if (response.isAcknowledged() == false) {

View file

@ -234,11 +234,20 @@ public class TransformPersistentTasksExecutorTests extends ESTestCase {
csBuilder.routingTable(routingTable.build()); csBuilder.routingTable(routingTable.build());
csBuilder.metadata(metadata); csBuilder.metadata(metadata);
ClusterSettings cSettings = new ClusterSettings(Settings.EMPTY, Collections.singleton(Transform.NUM_FAILURE_RETRIES_SETTING));
ClusterService clusterService = mock(ClusterService.class);
when(clusterService.getClusterSettings()).thenReturn(cSettings);
when(clusterService.state()).thenReturn(TransformInternalIndexTests.randomTransformClusterState());
ClusterState cs = csBuilder.build(); ClusterState cs = csBuilder.build();
Client client = mock(Client.class); Client client = mock(Client.class);
TransformAuditor mockAuditor = mock(TransformAuditor.class); TransformAuditor mockAuditor = mock(TransformAuditor.class);
IndexBasedTransformConfigManager transformsConfigManager = new IndexBasedTransformConfigManager(client, xContentRegistry()); IndexBasedTransformConfigManager transformsConfigManager = new IndexBasedTransformConfigManager(
clusterService,
TestIndexNameExpressionResolver.newInstance(),
client,
xContentRegistry()
);
TransformCheckpointService transformCheckpointService = new TransformCheckpointService( TransformCheckpointService transformCheckpointService = new TransformCheckpointService(
Clock.systemUTC(), Clock.systemUTC(),
Settings.EMPTY, Settings.EMPTY,
@ -253,10 +262,6 @@ public class TransformPersistentTasksExecutorTests extends ESTestCase {
mock(SchedulerEngine.class) mock(SchedulerEngine.class)
); );
ClusterSettings cSettings = new ClusterSettings(Settings.EMPTY, Collections.singleton(Transform.NUM_FAILURE_RETRIES_SETTING));
ClusterService clusterService = mock(ClusterService.class);
when(clusterService.getClusterSettings()).thenReturn(cSettings);
when(clusterService.state()).thenReturn(TransformInternalIndexTests.randomTransformClusterState());
TransformPersistentTasksExecutor executor = new TransformPersistentTasksExecutor( TransformPersistentTasksExecutor executor = new TransformPersistentTasksExecutor(
client, client,
transformServices, transformServices,
@ -514,9 +519,15 @@ public class TransformPersistentTasksExecutorTests extends ESTestCase {
} }
public TransformPersistentTasksExecutor buildTaskExecutor() { public TransformPersistentTasksExecutor buildTaskExecutor() {
ClusterService clusterService = mock(ClusterService.class);
Client client = mock(Client.class); Client client = mock(Client.class);
TransformAuditor mockAuditor = mock(TransformAuditor.class); TransformAuditor mockAuditor = mock(TransformAuditor.class);
IndexBasedTransformConfigManager transformsConfigManager = new IndexBasedTransformConfigManager(client, xContentRegistry()); IndexBasedTransformConfigManager transformsConfigManager = new IndexBasedTransformConfigManager(
clusterService,
TestIndexNameExpressionResolver.newInstance(),
client,
xContentRegistry()
);
TransformCheckpointService transformCheckpointService = new TransformCheckpointService( TransformCheckpointService transformCheckpointService = new TransformCheckpointService(
Clock.systemUTC(), Clock.systemUTC(),
Settings.EMPTY, Settings.EMPTY,
@ -532,7 +543,6 @@ public class TransformPersistentTasksExecutorTests extends ESTestCase {
); );
ClusterSettings cSettings = new ClusterSettings(Settings.EMPTY, Collections.singleton(Transform.NUM_FAILURE_RETRIES_SETTING)); ClusterSettings cSettings = new ClusterSettings(Settings.EMPTY, Collections.singleton(Transform.NUM_FAILURE_RETRIES_SETTING));
ClusterService clusterService = mock(ClusterService.class);
when(clusterService.getClusterSettings()).thenReturn(cSettings); when(clusterService.getClusterSettings()).thenReturn(cSettings);
when(clusterService.state()).thenReturn(TransformInternalIndexTests.randomTransformClusterState()); when(clusterService.state()).thenReturn(TransformInternalIndexTests.randomTransformClusterState());

View file

@ -20,11 +20,6 @@ import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.client.Client; import org.elasticsearch.client.Client;
import org.elasticsearch.common.ValidationException; import org.elasticsearch.common.ValidationException;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.xcontent.DeprecationHandler;
import org.elasticsearch.xcontent.NamedXContentRegistry;
import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.xcontent.XContentType;
import org.elasticsearch.xcontent.json.JsonXContent;
import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHit;
@ -32,6 +27,12 @@ import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.SearchModule; import org.elasticsearch.search.SearchModule;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.client.NoOpClient; import org.elasticsearch.test.client.NoOpClient;
import org.elasticsearch.xcontent.DeprecationHandler;
import org.elasticsearch.xcontent.NamedXContentRegistry;
import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.xcontent.XContentType;
import org.elasticsearch.xcontent.json.JsonXContent;
import org.elasticsearch.xpack.core.transform.TransformDeprecations;
import org.elasticsearch.xpack.core.transform.transforms.SettingsConfig; import org.elasticsearch.xpack.core.transform.transforms.SettingsConfig;
import org.elasticsearch.xpack.core.transform.transforms.SourceConfig; import org.elasticsearch.xpack.core.transform.transforms.SourceConfig;
import org.elasticsearch.xpack.core.transform.transforms.pivot.AggregationConfig; import org.elasticsearch.xpack.core.transform.transforms.pivot.AggregationConfig;
@ -136,7 +137,7 @@ public class PivotTests extends ESTestCase {
); );
assertThat(pivot.getInitialPageSize(), equalTo(Transform.DEFAULT_INITIAL_MAX_PAGE_SEARCH_SIZE)); assertThat(pivot.getInitialPageSize(), equalTo(Transform.DEFAULT_INITIAL_MAX_PAGE_SEARCH_SIZE));
assertWarnings("[max_page_search_size] is deprecated inside pivot please use settings instead"); assertWarnings(TransformDeprecations.ACTION_MAX_PAGE_SEARCH_SIZE_IS_DEPRECATED);
} }
public void testSearchFailure() throws Exception { public void testSearchFailure() throws Exception {