diff --git a/src/core/server/saved_objects/migrations/core/document_migrator.ts b/src/core/server/saved_objects/migrations/core/document_migrator.ts index cccd38bf5cc9e..51376bfbd8a0b 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.ts @@ -67,7 +67,7 @@ import { SavedObjectMigrationFn, SavedObjectMigrationMap } from '../types'; import { DEFAULT_NAMESPACE_STRING } from '../../service/lib/utils'; import { LegacyUrlAlias, LEGACY_URL_ALIAS_TYPE } from '../../object_types'; -const DEFAULT_MINIMUM_CONVERT_VERSION = '8.0.0'; +const DEFAULT_MINIMUM_CONVERT_VERSION = '7.13.0'; export type MigrateFn = (doc: SavedObjectUnsanitizedDoc) => SavedObjectUnsanitizedDoc; export type MigrateAndConvertFn = (doc: SavedObjectUnsanitizedDoc) => SavedObjectUnsanitizedDoc[]; @@ -850,7 +850,8 @@ function assertNoDowngrades( * that we can later regenerate any inbound object references to match. * * @note This is only intended to be used when single-namespace object types are converted into multi-namespace object types. + * @internal */ -function deterministicallyRegenerateObjectId(namespace: string, type: string, id: string) { +export function deterministicallyRegenerateObjectId(namespace: string, type: string, id: string) { return uuidv5(`${namespace}:${type}:${id}`, uuidv5.DNS); // the uuidv5 namespace constant (uuidv5.DNS) is arbitrary } diff --git a/src/core/server/saved_objects/migrationsv2/integration_tests/actions.test.ts b/src/core/server/saved_objects/migrationsv2/integration_tests/actions.test.ts index 0e1941f9070bd..b31f20950ae77 100644 --- a/src/core/server/saved_objects/migrationsv2/integration_tests/actions.test.ts +++ b/src/core/server/saved_objects/migrationsv2/integration_tests/actions.test.ts @@ -865,7 +865,7 @@ describe('migration actions', () => { await expect(docsResponse.right.outdatedDocuments.length).toBe(3); }); - it('excludes documents with types listed in unusedTypesToExclude', async () => { + it('it excludes documents not matching the provided "unusedTypesQuery"', async () => { const openPitTask = openPit(client, 'existing_index_with_docs'); const pitResponse = (await openPitTask()) as Either.Right; @@ -941,11 +941,11 @@ describe('migration actions', () => { { _id: 'foo:2', _source: { type: 'dashboard', value: 2 } }, ]; - const creteIndexTask = createIndex(client, index, { + const createIndexTask = createIndex(client, index, { dynamic: true, properties: {}, }); - await creteIndexTask(); + await createIndexTask(); async function tranformRawDocs(docs: SavedObjectsRawDoc[]): Promise { for (const doc of docs) { diff --git a/src/core/server/saved_objects/migrationsv2/integration_tests/rewriting_id.test.ts b/src/core/server/saved_objects/migrationsv2/integration_tests/rewriting_id.test.ts index a70e8ead7c61d..1b61394ba05a0 100644 --- a/src/core/server/saved_objects/migrationsv2/integration_tests/rewriting_id.test.ts +++ b/src/core/server/saved_objects/migrationsv2/integration_tests/rewriting_id.test.ts @@ -9,11 +9,11 @@ import Path from 'path'; import Fs from 'fs'; import Util from 'util'; -import uuidv5 from 'uuid/v5'; import { kibanaPackageJson as pkg } from '@kbn/utils'; import * as kbnTestServer from '../../../../test_helpers/kbn_server'; import type { ElasticsearchClient } from '../../../elasticsearch'; import { Root } from '../../../root'; +import { deterministicallyRegenerateObjectId } from '../../migrations/core/document_migrator'; const logFilePath = Path.join(__dirname, 'migration_test_kibana.log'); @@ -147,7 +147,7 @@ describe('migration v2', () => { hidden: false, mappings: { properties: { name: { type: 'text' } } }, namespaceType: 'multiple', - convertToMultiNamespaceTypeVersion: '8.0.0', + convertToMultiNamespaceTypeVersion: '7.13.0', }); coreSetup.savedObjects.registerType({ @@ -155,7 +155,7 @@ describe('migration v2', () => { hidden: false, mappings: { properties: { nomnom: { type: 'integer' } } }, namespaceType: 'multiple-isolated', - convertToMultiNamespaceTypeVersion: '8.0.0', + convertToMultiNamespaceTypeVersion: '7.13.0', }); const coreStart = await root.start(); @@ -165,8 +165,8 @@ describe('migration v2', () => { // each newly converted multi-namespace object in a non-default space has its ID deterministically regenerated, and a legacy-url-alias // object is created which links the old ID to the new ID - const newFooId = uuidv5('spacex:foo:1', uuidv5.DNS); - const newBarId = uuidv5('spacex:bar:1', uuidv5.DNS); + const newFooId = deterministicallyRegenerateObjectId('spacex', 'foo', '1'); + const newBarId = deterministicallyRegenerateObjectId('spacex', 'bar', '1'); expect(migratedDocs).toEqual( [ @@ -176,7 +176,7 @@ describe('migration v2', () => { foo: { name: 'Foo 1 default' }, references: [], namespaces: ['default'], - migrationVersion: { foo: '8.0.0' }, + migrationVersion: { foo: '7.13.0' }, coreMigrationVersion: pkg.version, }, { @@ -186,7 +186,7 @@ describe('migration v2', () => { references: [], namespaces: ['spacex'], originId: '1', - migrationVersion: { foo: '8.0.0' }, + migrationVersion: { foo: '7.13.0' }, coreMigrationVersion: pkg.version, }, { @@ -208,7 +208,7 @@ describe('migration v2', () => { bar: { nomnom: 1 }, references: [{ type: 'foo', id: '1', name: 'Foo 1 default' }], namespaces: ['default'], - migrationVersion: { bar: '8.0.0' }, + migrationVersion: { bar: '7.13.0' }, coreMigrationVersion: pkg.version, }, { @@ -218,7 +218,7 @@ describe('migration v2', () => { references: [{ type: 'foo', id: newFooId, name: 'Foo 1 spacex' }], namespaces: ['spacex'], originId: '1', - migrationVersion: { bar: '8.0.0' }, + migrationVersion: { bar: '7.13.0' }, coreMigrationVersion: pkg.version, }, { diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index 1e917b986f93f..2097b1de88aab 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -506,8 +506,9 @@ export const model = (currentState: State, resW: ResponseType): } else if (stateP.controlState === 'REINDEX_SOURCE_TO_TEMP_CLOSE_PIT') { const res = resW as ExcludeRetryableEsError>; if (Either.isRight(res)) { + const { sourceIndexPitId, ...state } = stateP; return { - ...stateP, + ...state, controlState: 'SET_TEMP_WRITE_BLOCK', sourceIndex: stateP.sourceIndex as Option.Some, };