|
6 | 6 | package org.elasticsearch.xpack.ml.integration; |
7 | 7 |
|
8 | 8 | import org.elasticsearch.Version; |
| 9 | +import org.elasticsearch.action.DocWriteRequest; |
| 10 | +import org.elasticsearch.action.index.IndexRequestBuilder; |
9 | 11 | import org.elasticsearch.action.index.IndexResponse; |
10 | 12 | import org.elasticsearch.action.search.SearchResponse; |
| 13 | +import org.elasticsearch.action.support.WriteRequest; |
11 | 14 | import org.elasticsearch.cluster.ClusterName; |
12 | 15 | import org.elasticsearch.cluster.ClusterState; |
13 | 16 | import org.elasticsearch.cluster.ClusterStateUpdateTask; |
@@ -180,6 +183,59 @@ public void testMigrateConfigs() throws InterruptedException, IOException { |
180 | 183 | assertEquals("df-1", datafeedsHolder.get().get(0).getId()); |
181 | 184 | } |
182 | 185 |
|
| 186 | + public void testExistingSnapshotDoesNotBlockMigration() throws InterruptedException { |
| 187 | + // index a doc with the same Id as the config snapshot |
| 188 | + IndexRequestBuilder indexRequest = client().prepareIndex(AnomalyDetectorsIndex.jobStateIndexName(), |
| 189 | + ElasticsearchMappings.DOC_TYPE, "ml-config") |
| 190 | + .setSource(Collections.singletonMap("a_field", "a_value")) |
| 191 | + .setOpType(DocWriteRequest.OpType.CREATE) |
| 192 | + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE); |
| 193 | + |
| 194 | + indexRequest.execute().actionGet(); |
| 195 | + |
| 196 | + // define the configs |
| 197 | + MlMetadata.Builder mlMetadata = new MlMetadata.Builder(); |
| 198 | + mlMetadata.putJob(buildJobBuilder("job-foo").build(), false); |
| 199 | + |
| 200 | + MetaData.Builder metaData = MetaData.builder(); |
| 201 | + RoutingTable.Builder routingTable = RoutingTable.builder(); |
| 202 | + addMlConfigIndex(metaData, routingTable); |
| 203 | + ClusterState clusterState = ClusterState.builder(new ClusterName("_name")) |
| 204 | + .metaData(metaData.putCustom(MlMetadata.TYPE, mlMetadata.build())) |
| 205 | + .routingTable(routingTable.build()) |
| 206 | + .build(); |
| 207 | + |
| 208 | + doAnswer(invocation -> { |
| 209 | + ClusterStateUpdateTask listener = (ClusterStateUpdateTask) invocation.getArguments()[1]; |
| 210 | + listener.clusterStateProcessed("source", mock(ClusterState.class), mock(ClusterState.class)); |
| 211 | + return null; |
| 212 | + }).when(clusterService).submitStateUpdateTask(eq("remove-migrated-ml-configs"), any()); |
| 213 | + |
| 214 | + AtomicReference<Exception> exceptionHolder = new AtomicReference<>(); |
| 215 | + AtomicReference<Boolean> responseHolder = new AtomicReference<>(); |
| 216 | + |
| 217 | + // do the migration |
| 218 | + MlConfigMigrator mlConfigMigrator = new MlConfigMigrator(nodeSettings(), client(), clusterService); |
| 219 | + // writing the snapshot should fail because the doc already exists |
| 220 | + // in which case the migration should continue |
| 221 | + blockingCall(actionListener -> mlConfigMigrator.migrateConfigsWithoutTasks(clusterState, actionListener), |
| 222 | + responseHolder, exceptionHolder); |
| 223 | + |
| 224 | + assertNull(exceptionHolder.get()); |
| 225 | + assertTrue(responseHolder.get()); |
| 226 | + |
| 227 | + // check the jobs have been migrated |
| 228 | + AtomicReference<List<Job.Builder>> jobsHolder = new AtomicReference<>(); |
| 229 | + JobConfigProvider jobConfigProvider = new JobConfigProvider(client()); |
| 230 | + blockingCall(actionListener -> jobConfigProvider.expandJobs("*", true, true, actionListener), |
| 231 | + jobsHolder, exceptionHolder); |
| 232 | + |
| 233 | + assertNull(exceptionHolder.get()); |
| 234 | + assertThat(jobsHolder.get(), hasSize(1)); |
| 235 | + assertTrue(jobsHolder.get().get(0).build().getCustomSettings().containsKey(MlConfigMigrator.MIGRATED_FROM_VERSION)); |
| 236 | + assertEquals("job-foo", jobsHolder.get().get(0).build().getId()); |
| 237 | + } |
| 238 | + |
183 | 239 | public void testMigrateConfigs_GivenLargeNumberOfJobsAndDatafeeds() throws InterruptedException { |
184 | 240 | int jobCount = randomIntBetween(150, 201); |
185 | 241 | int datafeedCount = randomIntBetween(150, jobCount); |
|
0 commit comments