diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.test.ts index ada352154a3c..cae79279a14a 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.test.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.test.ts @@ -176,8 +176,9 @@ describe('checkTargetTypesMappings', () => { const result = await task(); expect(result).toEqual( - Either.right({ - type: 'types_match' as const, + Either.left({ + type: 'types_added' as const, + newTypes: ['type3'], }) ); }); diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.ts index 0caee0882537..d3432d524071 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.ts @@ -11,7 +11,7 @@ import * as Either from 'fp-ts/lib/Either'; import * as TaskEither from 'fp-ts/lib/TaskEither'; import type { IndexMapping, VirtualVersionMap } from '@kbn/core-saved-objects-base-server-internal'; -import { getUpdatedTypes } from '../core/compare_mappings'; +import { getNewAndUpdatedTypes } from '../core/compare_mappings'; /** @internal */ export interface CheckTargetTypesMappingsParams { @@ -38,6 +38,12 @@ export interface TypesChanged { updatedTypes: string[]; } +/** @internal */ +export interface TypesAdded { + type: 'types_added'; + newTypes: string[]; +} + export const checkTargetTypesMappings = ({ indexTypes, @@ -46,7 +52,7 @@ export const checkTargetTypesMappings = latestMappingsVersions, hashToVersionMap = {}, }: CheckTargetTypesMappingsParams): TaskEither.TaskEither< - IndexMappingsIncomplete | TypesChanged, + IndexMappingsIncomplete | TypesChanged | TypesAdded, TypesMatch > => async () => { @@ -58,7 +64,7 @@ export const checkTargetTypesMappings = return Either.left({ type: 'index_mappings_incomplete' as const }); } - const updatedTypes = getUpdatedTypes({ + const { newTypes, updatedTypes } = getNewAndUpdatedTypes({ indexTypes, indexMeta: indexMappings?._meta, latestMappingsVersions, @@ -70,6 +76,11 @@ export const checkTargetTypesMappings = type: 'types_changed' as const, updatedTypes, }); + } else if (newTypes.length) { + return Either.left({ + type: 'types_added' as const, + newTypes, + }); } else { return Either.right({ type: 'types_match' as const }); } diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/index.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/index.ts index d489b6e51ae0..94727f88580a 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/index.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/index.ts @@ -112,7 +112,7 @@ import type { UnknownDocsFound } from './check_for_unknown_docs'; import type { IncompatibleClusterRoutingAllocation } from './check_cluster_routing_allocation'; import type { ClusterShardLimitExceeded } from './create_index'; import type { SynchronizationFailed } from './synchronize_migrators'; -import type { IndexMappingsIncomplete, TypesChanged } from './check_target_mappings'; +import type { IndexMappingsIncomplete, TypesAdded, TypesChanged } from './check_target_mappings'; export type { CheckForUnknownDocsParams, @@ -193,6 +193,7 @@ export interface ActionErrorTypeMap { synchronization_failed: SynchronizationFailed; index_mappings_incomplete: IndexMappingsIncomplete; types_changed: TypesChanged; + types_added: TypesAdded; operation_not_supported: OperationNotSupported; source_equals_target: SourceEqualsTarget; } diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/update_source_mappings_properties.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/update_source_mappings_properties.test.ts index d79b7f531167..80fad365f2c7 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/update_source_mappings_properties.test.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/update_source_mappings_properties.test.ts @@ -47,6 +47,7 @@ describe('updateSourceMappingsProperties', () => { appMappings: { properties: { a: { type: 'keyword' }, + b: { type: 'long' }, c: { type: 'long' }, ...getBaseMappings().properties, }, @@ -68,8 +69,10 @@ describe('updateSourceMappingsProperties', () => { it('should not update mappings when there are no changes', async () => { // we overwrite the app mappings to have the "unchanged" values with respect to the index mappings const sameMappingsParams = chain(params) + // let's not introduce 'c' for now + .set('indexTypes', ['a', 'b']) // even if the app versions are more recent, we emulate a scenario where mappings haven NOT changed - .set('latestMappingsVersions', { a: '10.1.0', b: '10.1.0', c: '10.1.0' }) + .set('latestMappingsVersions', { a: '10.1.0', b: '10.1.0' }) .value(); const result = await updateSourceMappingsProperties(sameMappingsParams)(); @@ -78,6 +81,28 @@ describe('updateSourceMappingsProperties', () => { expect(result).toHaveProperty('right', 'update_mappings_succeeded'); }); + it('should update mappings if there are new types', async () => { + // we overwrite the app mappings to have the "unchanged" values with respect to the index mappings + const sameMappingsParams = chain(params) + // even if the app versions are more recent, we emulate a scenario where mappings haven NOT changed + .set('latestMappingsVersions', { a: '10.1.0', b: '10.1.0', c: '10.1.0' }) + .value(); + const result = await updateSourceMappingsProperties(sameMappingsParams)(); + + expect(client.indices.putMapping).toHaveBeenCalledTimes(1); + expect(client.indices.putMapping).toHaveBeenCalledWith( + expect.objectContaining({ + properties: expect.objectContaining({ + a: { type: 'keyword' }, + b: { type: 'long' }, + c: { type: 'long' }, + }), + }) + ); + expect(Either.isRight(result)).toEqual(true); + expect(result).toHaveProperty('right', 'update_mappings_succeeded'); + }); + it('should return that mappings are updated when changes are compatible', async () => { const result = await updateSourceMappingsProperties(params)(); diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/compare_mappings.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/compare_mappings.test.ts index 4a155944c414..e756fb65ce71 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/compare_mappings.test.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/compare_mappings.test.ts @@ -9,17 +9,20 @@ import type { IndexMappingMeta } from '@kbn/core-saved-objects-base-server-internal'; import { getBaseMappings } from './build_active_mappings'; -import { getUpdatedTypes, getUpdatedRootFields } from './compare_mappings'; +import { getUpdatedRootFields, getNewAndUpdatedTypes } from './compare_mappings'; -describe('getUpdatedTypes', () => { +describe('getNewAndUpdatedTypes', () => { test('returns all types if _meta is missing in indexMappings', () => { const indexTypes = ['foo', 'bar']; const latestMappingsVersions = {}; - expect(getUpdatedTypes({ indexTypes, indexMeta: undefined, latestMappingsVersions })).toEqual([ - 'foo', - 'bar', - ]); + const { newTypes, updatedTypes } = getNewAndUpdatedTypes({ + indexTypes, + indexMeta: undefined, + latestMappingsVersions, + }); + expect(newTypes).toEqual([]); + expect(updatedTypes).toEqual(['foo', 'bar']); }); test('returns all types if migrationMappingPropertyHashes and mappingVersions are missing in indexMappings', () => { @@ -27,14 +30,17 @@ describe('getUpdatedTypes', () => { const indexMeta: IndexMappingMeta = {}; const latestMappingsVersions = {}; - expect(getUpdatedTypes({ indexTypes, indexMeta, latestMappingsVersions })).toEqual([ - 'foo', - 'bar', - ]); + const { newTypes, updatedTypes } = getNewAndUpdatedTypes({ + indexTypes, + indexMeta, + latestMappingsVersions, + }); + expect(newTypes).toEqual([]); + expect(updatedTypes).toEqual(['foo', 'bar']); }); describe('when ONLY migrationMappingPropertyHashes exists in indexMappings', () => { - test('uses the provided hashToVersionMap to compare changes and return only the types that have changed', async () => { + test('uses the provided hashToVersionMap to compare changes and return new types and types that have changed', async () => { const indexTypes = ['type1', 'type2', 'type4']; const indexMeta: IndexMappingMeta = { migrationMappingPropertyHashes: { @@ -56,14 +62,19 @@ describe('getUpdatedTypes', () => { type4: '10.5.0', // new type, no need to pick it up }; - expect( - getUpdatedTypes({ indexTypes, indexMeta, latestMappingsVersions, hashToVersionMap }) - ).toEqual(['type2']); + const { newTypes, updatedTypes } = getNewAndUpdatedTypes({ + indexTypes, + indexMeta, + latestMappingsVersions, + hashToVersionMap, + }); + expect(newTypes).toEqual(['type4']); + expect(updatedTypes).toEqual(['type2']); }); }); describe('when mappingVersions exist in indexMappings', () => { - test('compares the modelVersions and returns only the types that have changed', async () => { + test('compares the modelVersions and returns new types and types that have changed', async () => { const indexTypes = ['type1', 'type2', 'type4']; const indexMeta: IndexMappingMeta = { @@ -90,9 +101,14 @@ describe('getUpdatedTypes', () => { // empty on purpose, not used as mappingVersions is present in indexMappings }; - expect( - getUpdatedTypes({ indexTypes, indexMeta, latestMappingsVersions, hashToVersionMap }) - ).toEqual(['type2']); + const { newTypes, updatedTypes } = getNewAndUpdatedTypes({ + indexTypes, + indexMeta, + latestMappingsVersions, + hashToVersionMap, + }); + expect(newTypes).toEqual(['type4']); + expect(updatedTypes).toEqual(['type2']); }); }); }); diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/compare_mappings.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/compare_mappings.ts index b10311cb9f7e..0e2de5ee51ec 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/compare_mappings.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/compare_mappings.ts @@ -33,43 +33,56 @@ export const getUpdatedRootFields = (indexMappings: IndexMapping): string[] => { .map(([propertyName]) => propertyName); }; +interface GetUpdatedTypesParams { + indexMeta?: IndexMappingMeta; + indexTypes: string[]; + latestMappingsVersions: VirtualVersionMap; + hashToVersionMap?: Record; +} + /** * Compares the current vs stored mappings' hashes or modelVersions. - * Returns a list with all the types that have been updated. + * Returns 2 lists: one with all the new types and one with the types that have been updated. * @param indexMeta The meta information stored in the SO index * @param knownTypes The list of SO types that belong to the index and are enabled * @param latestMappingsVersions A map holding [type => version] with the latest versions where mappings have changed for each type * @param hashToVersionMap A map holding information about [md5 => modelVersion] equivalence - * @returns the list of types that have been updated (in terms of their mappings) + * @returns the lists of new types and updated types */ -export const getUpdatedTypes = ({ +export const getNewAndUpdatedTypes = ({ indexMeta, indexTypes, latestMappingsVersions, hashToVersionMap = {}, -}: { - indexMeta?: IndexMappingMeta; - indexTypes: string[]; - latestMappingsVersions: VirtualVersionMap; - hashToVersionMap?: Record; -}): string[] => { +}: GetUpdatedTypesParams) => { if (!indexMeta || (!indexMeta.mappingVersions && !indexMeta.migrationMappingPropertyHashes)) { // if we currently do NOT have meta information stored in the index // we consider that all types have been updated - return indexTypes; + return { newTypes: [], updatedTypes: indexTypes }; } // If something exists in stored, but is missing in current // we don't care, as it could be a disabled plugin, etc // and keeping stale stuff around is better than migrating unecessesarily. - return indexTypes.filter((type) => - isTypeUpdated({ + const newTypes: string[] = []; + const updatedTypes: string[] = []; + + indexTypes.forEach((type) => { + const status = checkTypeStatus({ type, mappingVersion: latestMappingsVersions[type], indexMeta, hashToVersionMap, - }) - ); + }); + + if (status === 'new') { + newTypes.push(type); + } else if (status === 'updated') { + updatedTypes.push(type); + } + }); + + return { newTypes, updatedTypes }; }; /** @@ -78,9 +91,9 @@ export const getUpdatedTypes = ({ * @param mappingVersion The most recent model version that includes mappings changes * @param indexMeta The meta information stored in the SO index * @param hashToVersionMap A map holding information about [md5 => modelVersion] equivalence - * @returns true if the mappings for the given type have changed since Kibana was last started + * @returns 'new' | 'updated' | 'unchanged' depending on whether the type has changed */ -function isTypeUpdated({ +function checkTypeStatus({ type, mappingVersion, indexMeta, @@ -90,7 +103,7 @@ function isTypeUpdated({ mappingVersion: string; indexMeta: IndexMappingMeta; hashToVersionMap: Record; -}): boolean { +}): 'new' | 'updated' | 'unchanged' { const latestMappingsVersion = Semver.parse(mappingVersion); if (!latestMappingsVersion) { throw new Error( @@ -104,26 +117,28 @@ function isTypeUpdated({ if (!indexVersion) { // either a new type, and thus there's not need to update + pickup any docs // or an old re-enabled type, which will be updated on OUTDATED_DOCUMENTS_TRANSFORM - return false; + return 'new'; } // if the last version where mappings have changed is more recent than the one stored in the index // it means that the type has been updated - return latestMappingsVersion.compare(indexVersion) === 1; + return latestMappingsVersion.compare(indexVersion) === 1 ? 'updated' : 'unchanged'; } else if (indexMeta.migrationMappingPropertyHashes) { const latestHash = indexMeta.migrationMappingPropertyHashes?.[type]; if (!latestHash) { // either a new type, and thus there's not need to update + pickup any docs // or an old re-enabled type, which will be updated on OUTDATED_DOCUMENTS_TRANSFORM - return false; + return 'new'; } const indexEquivalentVersion = hashToVersionMap[`${type}|${latestHash}`]; - return !indexEquivalentVersion || latestMappingsVersion.compare(indexEquivalentVersion) === 1; + return !indexEquivalentVersion || latestMappingsVersion.compare(indexEquivalentVersion) === 1 + ? 'updated' + : 'unchanged'; } // at this point, the mappings do not contain any meta informataion // we consider the type has been updated, out of caution - return true; + return 'updated'; } diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/diff_mappings.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/diff_mappings.test.ts index c9c4beabe2d7..5a34dfba6edd 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/diff_mappings.test.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/diff_mappings.test.ts @@ -9,12 +9,14 @@ import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; import { getBaseMappings } from './build_active_mappings'; -import { getUpdatedRootFields, getUpdatedTypes } from './compare_mappings'; +import { getUpdatedRootFields, getNewAndUpdatedTypes } from './compare_mappings'; import { diffMappings } from './diff_mappings'; jest.mock('./compare_mappings'); const getUpdatedRootFieldsMock = getUpdatedRootFields as jest.MockedFn; -const getUpdatedTypesMock = getUpdatedTypes as jest.MockedFn; +const getNewAndUpdatedTypesMock = getNewAndUpdatedTypes as jest.MockedFn< + typeof getNewAndUpdatedTypes +>; const dummyMappings: IndexMapping = { _meta: { @@ -56,7 +58,7 @@ const dummyHashToVersionMap = { describe('diffMappings', () => { beforeEach(() => { getUpdatedRootFieldsMock.mockReset(); - getUpdatedTypesMock.mockReset(); + getNewAndUpdatedTypesMock.mockReset(); }); test('is different if dynamic is different', () => { @@ -114,14 +116,17 @@ describe('diffMappings', () => { expect(getUpdatedRootFieldsMock).toHaveBeenCalledTimes(1); expect(getUpdatedRootFieldsMock).toHaveBeenCalledWith(initialMappings); - expect(getUpdatedTypesMock).not.toHaveBeenCalled(); + expect(getNewAndUpdatedTypesMock).not.toHaveBeenCalled(); }); }); - describe('if some types have changed', () => { + describe('if there are new or updated types', () => { test('returns a changed type', () => { getUpdatedRootFieldsMock.mockReturnValueOnce([]); - getUpdatedTypesMock.mockReturnValueOnce(['foo', 'bar']); + getNewAndUpdatedTypesMock.mockReturnValueOnce({ + newTypes: ['baz'], + updatedTypes: ['foo'], + }); expect( diffMappings({ @@ -137,8 +142,8 @@ describe('diffMappings', () => { expect(getUpdatedRootFieldsMock).toHaveBeenCalledTimes(1); expect(getUpdatedRootFieldsMock).toHaveBeenCalledWith(initialMappings); - expect(getUpdatedTypesMock).toHaveBeenCalledTimes(1); - expect(getUpdatedTypesMock).toHaveBeenCalledWith({ + expect(getNewAndUpdatedTypesMock).toHaveBeenCalledTimes(1); + expect(getNewAndUpdatedTypesMock).toHaveBeenCalledWith({ indexTypes: ['foo', 'bar', 'baz'], indexMeta: initialMappings._meta, latestMappingsVersions: { @@ -152,7 +157,10 @@ describe('diffMappings', () => { describe('if no root field or types have changed', () => { test('returns undefined', () => { getUpdatedRootFieldsMock.mockReturnValueOnce([]); - getUpdatedTypesMock.mockReturnValueOnce([]); + getNewAndUpdatedTypesMock.mockReturnValueOnce({ + newTypes: [], + updatedTypes: [], + }); expect( diffMappings({ diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/diff_mappings.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/diff_mappings.ts index 1f0184875450..7bc806e4277c 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/diff_mappings.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/diff_mappings.ts @@ -8,7 +8,7 @@ */ import type { IndexMapping, VirtualVersionMap } from '@kbn/core-saved-objects-base-server-internal'; -import { getUpdatedRootFields, getUpdatedTypes } from './compare_mappings'; +import { getNewAndUpdatedTypes, getUpdatedRootFields } from './compare_mappings'; /** * Diffs the stored vs app mappings. @@ -56,8 +56,9 @@ export function diffMappings({ } /** - * Finds a property that has changed its schema with respect to the mappings stored in the SO index - * It can either be a root field or a SO type + * Finds a property (either a root field or a SO type) that either: + * - is new (did not exist in the current mappings) + * - has changed its schema with respect to the mappings stored in the SO index * @returns the name of the property (if any) */ function findChangedProp({ @@ -76,7 +77,7 @@ function findChangedProp({ return updatedFields[0]; } - const updatedTypes = getUpdatedTypes({ + const { newTypes, updatedTypes } = getNewAndUpdatedTypes({ indexMeta: indexMappings._meta, indexTypes, latestMappingsVersions, @@ -84,6 +85,8 @@ function findChangedProp({ }); if (updatedTypes.length) { return updatedTypes[0]; + } else if (newTypes.length) { + return newTypes[0]; } return undefined; diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.test.ts index 23e5fba10fe3..54d8c9a6d0b7 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.test.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.test.ts @@ -2689,6 +2689,18 @@ describe('migrations v2 model', () => { }); }); + it('CHECK_TARGET_MAPPINGS -> UPDATE_TARGET_MAPPINGS_META if ONLY new SO types have been added', () => { + const res: ResponseType<'CHECK_TARGET_MAPPINGS'> = Either.left({ + type: 'types_added' as const, + updatedFields: [], + newTypes: ['newFeatureType'], + }); + const newState = model(checkTargetTypesMappingsState, res) as UpdateTargetMappingsMeta; + expect(newState.controlState).toEqual('UPDATE_TARGET_MAPPINGS_META'); + expect(newState.retryCount).toEqual(0); + expect(newState.retryDelay).toEqual(0); + }); + it('CHECK_TARGET_MAPPINGS -> CHECK_VERSION_INDEX_READY_ACTIONS if types match (there might be additions in core fields)', () => { const res: ResponseType<'CHECK_TARGET_MAPPINGS'> = Either.right({ type: 'types_match' as const, diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.ts index 14b171ac097d..f31f7c886af7 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.ts @@ -1522,6 +1522,12 @@ export const model = (currentState: State, resW: ResponseType): }, ], }; + } else if (isTypeof(left, 'types_added')) { + // compatible migration: ONLY new SO types have been introduced, skip directly to UPDATE_TARGET_MAPPINGS_META + return { + ...stateP, + controlState: 'UPDATE_TARGET_MAPPINGS_META', + }; } else { throwBadResponse(stateP, res as never); } diff --git a/src/core/server/integration_tests/saved_objects/migrations/group1/v2_migration.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group1/v2_migration.test.ts index 2236b6adcc62..06f7877874e8 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group1/v2_migration.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group1/v2_migration.test.ts @@ -67,34 +67,48 @@ describe('v2 migration', () => { migrationResults = await upToDateKit.runMigrations(); }); + it('updates the index mappings to account for new SO types', async () => { + const res = await upToDateKit.client.indices.getMapping({ index: defaultKibanaIndex }); + const mappings = res[`${defaultKibanaIndex}_${currentVersion}_001`].mappings; + + expect(mappings._meta?.indexTypesMap[defaultKibanaIndex]).toContain('recent'); + expect(mappings.properties?.recent).toEqual({ + properties: { + name: { + type: 'keyword', + }, + }, + }); + }); + it('skips UPDATE_TARGET_MAPPINGS_PROPERTIES if there are no changes in the mappings', async () => { const logs = await readLog(logFilePath); expect(logs).not.toMatch('CREATE_NEW_TARGET'); + + // defaultKibana index has a new SO type ('recent'), thus we must update the _meta properties expect(logs).toMatch( - `[${defaultKibanaIndex}] CHECK_TARGET_MAPPINGS -> CHECK_VERSION_INDEX_READY_ACTIONS` + `[${defaultKibanaIndex}] CHECK_TARGET_MAPPINGS -> UPDATE_TARGET_MAPPINGS_META.` ); expect(logs).toMatch( `[${defaultKibanaTaskIndex}] CHECK_TARGET_MAPPINGS -> CHECK_VERSION_INDEX_READY_ACTIONS` ); + + // no updated types, so no pickup expect(logs).not.toMatch('UPDATE_TARGET_MAPPINGS_PROPERTIES'); - expect(logs).not.toMatch('UPDATE_TARGET_MAPPINGS_PROPERTIES_WAIT_FOR_TASK'); - expect(logs).not.toMatch('UPDATE_TARGET_MAPPINGS_META'); }); it(`returns a 'patched' status for each SO index`, () => { // omit elapsedMs as it varies in each execution - expect(migrationResults.map((result) => omit(result, 'elapsedMs'))).toMatchInlineSnapshot(` - Array [ - Object { - "destIndex": ".kibana_migrator_${currentVersion}_001", - "status": "patched", - }, - Object { - "destIndex": ".kibana_migrator_tasks_${currentVersion}_001", - "status": "patched", - }, - ] - `); + expect(migrationResults.map((result) => omit(result, 'elapsedMs'))).toEqual([ + { + destIndex: `${defaultKibanaIndex}_${currentVersion}_001`, + status: 'patched', + }, + { + destIndex: `${defaultKibanaTaskIndex}_${currentVersion}_001`, + status: 'patched', + }, + ]); }); it('each migrator takes less than 10 seconds', () => { @@ -318,21 +332,18 @@ describe('v2 migration', () => { it('returns a migrated status for each SO index', () => { // omit elapsedMs as it varies in each execution - expect(migrationResults.map((result) => omit(result, 'elapsedMs'))) - .toMatchInlineSnapshot(` - Array [ - Object { - "destIndex": ".kibana_migrator_${nextMinor}_001", - "sourceIndex": ".kibana_migrator_${currentVersion}_001", - "status": "migrated", - }, - Object { - "destIndex": ".kibana_migrator_tasks_${currentVersion}_001", - "sourceIndex": ".kibana_migrator_tasks_${currentVersion}_001", - "status": "migrated", - }, - ] - `); + expect(migrationResults.map((result) => omit(result, 'elapsedMs'))).toEqual([ + { + destIndex: `${defaultKibanaIndex}_${nextMinor}_001`, + sourceIndex: `${defaultKibanaIndex}_${currentVersion}_001`, + status: 'migrated', + }, + { + destIndex: `${defaultKibanaTaskIndex}_${currentVersion}_001`, + sourceIndex: `${defaultKibanaTaskIndex}_${currentVersion}_001`, + status: 'migrated', + }, + ]); }); it('each migrator takes less than 60 seconds', () => { diff --git a/src/core/server/integration_tests/saved_objects/migrations/group2/multiple_kb_nodes.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group2/multiple_kb_nodes.test.ts index 19100fad017d..2f0e429cadb7 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group2/multiple_kb_nodes.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group2/multiple_kb_nodes.test.ts @@ -139,7 +139,7 @@ describe('multiple Kibana nodes performing a reindexing migration', () => { const typesMap = indicesInfo[`${defaultKibanaIndex}_${nextMinor}_001`].mappings?._meta?.indexTypesMap; - expect(typesMap[defaultKibanaIndex]).toEqual(['complex', 'server']); // 'deprecated' no longer present + expect(typesMap[defaultKibanaIndex]).toEqual(['complex', 'recent', 'server']); // 'deprecated' no longer present expect(typesMap[kibanaSplitIndex]).toEqual(['basic', 'task']); } @@ -239,11 +239,11 @@ describe('multiple Kibana nodes performing a reindexing migration', () => { ) ).toEqual([ { - destIndex: `.kibana_migrator_${nextMinor}_001`, + destIndex: `${defaultKibanaIndex}_${nextMinor}_001`, status: 'patched', }, { - destIndex: `.kibana_migrator_split_${nextMinor}_001`, + destIndex: `${kibanaSplitIndex}_${nextMinor}_001`, status: 'patched', }, ]); diff --git a/src/core/server/integration_tests/saved_objects/migrations/kibana_migrator_test_kit.fixtures.ts b/src/core/server/integration_tests/saved_objects/migrations/kibana_migrator_test_kit.fixtures.ts index 36887dd02a14..5b5e6db966ab 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/kibana_migrator_test_kit.fixtures.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/kibana_migrator_test_kit.fixtures.ts @@ -81,8 +81,14 @@ export const baselineTypes: Array> = [ }, ]; -export const getUpToDateBaselineTypes = (filterDeprecated: boolean) => - baselineTypes.filter((type) => !filterDeprecated || type.name !== 'deprecated'); +export const getUpToDateBaselineTypes = (filterDeprecated: boolean) => [ + ...baselineTypes.filter((type) => !filterDeprecated || type.name !== 'deprecated'), + // we add a new SO type + { + ...defaultType, + name: 'recent', + }, +]; export const getCompatibleBaselineTypes = (filterDeprecated: boolean) => getUpToDateBaselineTypes(filterDeprecated).map((type) => {