From db8feb81d03ad14709b926cb0897b4b2be5307cb Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Mon, 5 Apr 2021 17:02:11 -0700 Subject: [PATCH 01/27] Initial notes --- .../migrations/core/migrate_raw_docs.test.ts | 2 +- .../migrations/core/migrate_raw_docs.ts | 45 +++++++++++++++++- .../migrations/kibana/kibana_migrator.ts | 47 +++++++++++++++++-- .../saved_objects/migrationsv2/index.ts | 6 ++- .../migrations_state_action_machine.ts | 2 +- .../server/saved_objects/migrationsv2/next.ts | 22 +++++++-- .../saved_objects/migrationsv2/types.ts | 1 + 7 files changed, 114 insertions(+), 11 deletions(-) diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts index 66750a8abf1db..ce12bd22a0712 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts @@ -57,7 +57,7 @@ describe('migrateRawDocs', () => { expect(transform).toHaveBeenNthCalledWith(1, obj1); expect(transform).toHaveBeenNthCalledWith(2, obj2); }); - + // we don't want to throw test('throws when encountering a corrupt saved object document', async () => { const logger = createSavedObjectsMigrationLoggerMock(); const transform = jest.fn((doc: any) => [ diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts index e75f29e54c876..8c21149805283 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts @@ -34,7 +34,6 @@ export class CorruptSavedObjectError extends Error { Object.setPrototypeOf(this, CorruptSavedObjectError.prototype); } } - /** * Applies the specified migration function to every saved object document in the list * of raw docs. Any raw docs that are not valid saved objects will simply be passed through. @@ -70,7 +69,49 @@ export async function migrateRawDocs( } return processedDocs; } - +export interface MigrateRawDocsNonThrowing { + processedDocs: SavedObjectsRawDoc[]; + corruptSavedObjectErrors?: CorruptSavedObjectError[]; +} +/** approach options: + * 1. use a collection of processed docs and errors that we generate + * 2. log the errors -> we have the logger but aren't using it + * 3. return the transformed docs and throw away the corruptSavedObjectsErrors + */ +export async function migrateRawDocsNonThrowing( + serializer: SavedObjectsSerializer, + migrateDoc: MigrateAndConvertFn, + rawDocs: SavedObjectsRawDoc[], + log: SavedObjectsMigrationLogger +): Promise { + const migrateDocWithoutBlocking = transformNonBlocking(migrateDoc); + const processedDocs = []; + const corruptSavedObjectErrors = []; + for (const raw of rawDocs) { + const options = { namespaceTreatment: 'lax' as const }; + if (serializer.isRawSavedObject(raw, options)) { + const savedObject = serializer.rawToSavedObject(raw, options); + savedObject.migrationVersion = savedObject.migrationVersion || {}; + processedDocs.push( + ...(await migrateDocWithoutBlocking(savedObject)).map((attrs) => + serializer.savedObjectToRaw({ + references: [], + ...attrs, + }) + ) + ); + } else { + corruptSavedObjectErrors.push(new CorruptSavedObjectError(raw._id)); + } + } + if (corruptSavedObjectErrors.length > 0) { + corruptSavedObjectErrors.forEach((error) => { + log.error(error.message, error); + }); + } + // a promise only returns one thing. We want to return both things + return processedDocs; +} /** * Migration transform functions are potentially CPU heavy e.g. doing decryption/encryption * or (de)/serializing large JSON payloads. diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts index 29852f8ac6445..3a7cc836ed796 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts @@ -35,7 +35,7 @@ import { SavedObjectsMigrationConfigType } from '../../saved_objects_config'; import { ISavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { SavedObjectsType } from '../../types'; import { runResilientMigrator } from '../../migrationsv2'; -import { migrateRawDocs } from '../core/migrate_raw_docs'; +import { migrateRawDocsNonThrowing } from '../core/migrate_raw_docs'; import { MigrationLogger } from '../core/migration_logger'; export interface KibanaMigratorOptions { @@ -135,7 +135,7 @@ export class KibanaMigrator { if (!rerun) { this.status$.next({ status: 'running' }); } - + // TINA: this.runMigrationsInternal()'s return signature is going to change this.migrationResult = this.runMigrationsInternal().then((result) => { // Similar to above, don't publish status updates when rerunning in CI. if (!rerun) { @@ -178,6 +178,7 @@ export class KibanaMigrator { if (this.soMigrationsConfig.enableV2) { return { migrate: (): Promise => { + // TINA: adapt runResilientMigrator to handle the new return format for v2 version of migrateRawDocs => migrateRawDocsNonThrowing return runResilientMigrator({ client: this.client, kibanaVersion: this.kibanaVersion, @@ -185,15 +186,27 @@ export class KibanaMigrator { logger: this.log, preMigrationScript: indexMap[index].script, transformRawDocs: (rawDocs: SavedObjectsRawDoc[]) => - migrateRawDocs( + migrateRawDocsNonThrowing( this.serializer, this.documentMigrator.migrateAndConvert, rawDocs, new MigrationLogger(this.log) ), + // migrateRawDocs( + // this.serializer, + // this.documentMigrator.migrateAndConvert, + // rawDocs, + // new MigrationLogger(this.log) + // ), migrationVersionPerType: this.documentMigrator.migrationVersion, indexPrefix: index, migrationsConfig: this.soMigrationsConfig, + captureTransformRawDocsErrors: (collection: Error[], specificErrors: Error[]) => + logCorruptSavedObjectsErrors( + collection, + specificErrors, + new MigrationLogger(this.log) + ), }); }, }; @@ -255,3 +268,31 @@ export function mergeTypes(types: SavedObjectsType[]): SavedObjectsTypeMappingDe }; }, {}); } + +export interface LogCaptureTransformRawDocsErrors { + (existing: Error[], newCollection: Error[], log: MigrationLogger): string; + (arg0: Error[] | undefined, arg1: unknown): void; +} + +export type LogCorruptSavedObjectsErrors = ( + existing: Error[], + newCollection: Error[], + log: MigrationLogger +) => string; +// TINA there's a better way to handle this and I don't think we even need +// to but I'm trying to not have to throw in OUTDATED_DOCUMENTS_TRANSFORM +export function logCorruptSavedObjectsErrors( + existing: Error[], + newCollection: Error[], + logger: MigrationLogger +) { + if (newCollection && newCollection.length > 0) { + newCollection.map((entry) => { + existing.push(entry); + }); + } + if (existing && existing.length > 0) { + existing.forEach((accumulatedError) => logger.info(accumulatedError.message)); + } + return 'logging complete'; +} diff --git a/src/core/server/saved_objects/migrationsv2/index.ts b/src/core/server/saved_objects/migrationsv2/index.ts index 6e65a2e700fd3..7ef4eb486ba18 100644 --- a/src/core/server/saved_objects/migrationsv2/index.ts +++ b/src/core/server/saved_objects/migrationsv2/index.ts @@ -15,6 +15,7 @@ import { next, TransformRawDocs } from './next'; import { createInitialState, model } from './model'; import { migrationStateActionMachine } from './migrations_state_action_machine'; import { SavedObjectsMigrationConfigType } from '../saved_objects_config'; +import { LogCorruptSavedObjectsErrors } from '../migrations/kibana/kibana_migrator'; /** * Migrates the provided indexPrefix index using a resilient algorithm that is @@ -31,6 +32,7 @@ export async function runResilientMigrator({ migrationVersionPerType, indexPrefix, migrationsConfig, + captureTransformRawDocsErrors, }: { client: ElasticsearchClient; kibanaVersion: string; @@ -41,6 +43,8 @@ export async function runResilientMigrator({ migrationVersionPerType: SavedObjectsMigrationVersion; indexPrefix: string; migrationsConfig: SavedObjectsMigrationConfigType; + // TINA: added to log errors and not throw in OUTDATED_DOCUMENTS_TRANSFORM + captureTransformRawDocsErrors: LogCorruptSavedObjectsErrors; }): Promise { const initialState = createInitialState({ kibanaVersion, @@ -53,7 +57,7 @@ export async function runResilientMigrator({ return migrationStateActionMachine({ initialState, logger, - next: next(client, transformRawDocs), + next: next(client, transformRawDocs, captureTransformRawDocsErrors), model, }); } diff --git a/src/core/server/saved_objects/migrationsv2/migrations_state_action_machine.ts b/src/core/server/saved_objects/migrationsv2/migrations_state_action_machine.ts index e35e21421ac1f..fd2c240564476 100644 --- a/src/core/server/saved_objects/migrationsv2/migrations_state_action_machine.ts +++ b/src/core/server/saved_objects/migrationsv2/migrations_state_action_machine.ts @@ -53,7 +53,7 @@ const logActionResponse = ( ) => { logger.debug(logMessagePrefix + `${state.controlState} RESPONSE`, res as LogMeta); }; - +// naming here is misleading, dumpExecutionLog "dumps" the log messages, it doesn't delete them. const dumpExecutionLog = (logger: Logger, logMessagePrefix: string, executionLog: ExecutionLog) => { logger.error(logMessagePrefix + 'migration failed, dumping execution log:'); executionLog.forEach((log) => { diff --git a/src/core/server/saved_objects/migrationsv2/next.ts b/src/core/server/saved_objects/migrationsv2/next.ts index bb506cbca66fb..47053d6149c52 100644 --- a/src/core/server/saved_objects/migrationsv2/next.ts +++ b/src/core/server/saved_objects/migrationsv2/next.ts @@ -37,6 +37,11 @@ import type { import * as Actions from './actions'; import { ElasticsearchClient } from '../../elasticsearch'; import { SavedObjectsRawDoc } from '..'; +import { + LogCaptureTransformRawDocsErrors, + LogCorruptSavedObjectsErrors, +} from '../migrations/kibana/kibana_migrator'; +import { MigrationLogger } from '../migrations/core/migration_logger'; export type TransformRawDocs = (rawDocs: SavedObjectsRawDoc[]) => Promise; type ActionMap = ReturnType; @@ -51,7 +56,11 @@ export type ResponseType = UnwrapPromise< ReturnType> >; -export const nextActionMap = (client: ElasticsearchClient, transformRawDocs: TransformRawDocs) => { +export const nextActionMap = ( + client: ElasticsearchClient, + transformRawDocs: TransformRawDocs, + captureTransformRawDocsErrors: LogCaptureTransformRawDocsErrors +) => { return { INIT: (state: InitState) => Actions.fetchIndices(client, [state.currentAlias, state.versionAlias]), @@ -93,9 +102,12 @@ export const nextActionMap = (client: ElasticsearchClient, transformRawDocs: Tra TaskEither.tryCatch( () => transformRawDocs(state.outdatedDocuments), (e) => { + captureTransformRawDocsErrors(state.errors, e); + // TINA: we don't want to throw here, these errors are never caught throw e; } ), + // if we decide to return the CorruptSavedObjectsErrors, the return signature of `transformRawDocs` will change TaskEither.chain((docs) => Actions.bulkOverwriteTransformedDocuments(client, state.targetIndex, docs) ) @@ -124,8 +136,12 @@ export const nextActionMap = (client: ElasticsearchClient, transformRawDocs: Tra }; }; -export const next = (client: ElasticsearchClient, transformRawDocs: TransformRawDocs) => { - const map = nextActionMap(client, transformRawDocs); +export const next = ( + client: ElasticsearchClient, + transformRawDocs: TransformRawDocs, + captureTransformRawDocsErrors: LogCorruptSavedObjectsErrors +) => { + const map = nextActionMap(client, transformRawDocs, captureTransformRawDocsErrors); return (state: State) => { const delay = any>(fn: F): (() => ReturnType) => { return () => { diff --git a/src/core/server/saved_objects/migrationsv2/types.ts b/src/core/server/saved_objects/migrationsv2/types.ts index 5e84bc23b1d16..9db47da777188 100644 --- a/src/core/server/saved_objects/migrationsv2/types.ts +++ b/src/core/server/saved_objects/migrationsv2/types.ts @@ -210,6 +210,7 @@ export type OutdatedDocumentsTransform = PostInitState & { /** Transform a batch of outdated documents to their latest version and write them to the target index */ readonly controlState: 'OUTDATED_DOCUMENTS_TRANSFORM'; readonly outdatedDocuments: SavedObjectsRawDoc[]; + readonly errors?: Error[]; }; export type MarkVersionIndexReady = PostInitState & { From afd464953f9f1fc92d1f3a7f43611595aae3d14b Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Thu, 8 Apr 2021 17:10:10 -0700 Subject: [PATCH 02/27] Refactoring to add new state and state transforms --- .../migrations/core/migrate_raw_docs.ts | 78 +++++++++++-------- .../migrations/kibana/kibana_migrator.ts | 7 +- .../migrationsv2/actions/index.ts | 1 - .../saved_objects/migrationsv2/model.ts | 27 ++++++- .../server/saved_objects/migrationsv2/next.ts | 59 +++++++------- .../saved_objects/migrationsv2/types.ts | 10 ++- 6 files changed, 107 insertions(+), 75 deletions(-) diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts index 8c21149805283..65e291bb4567a 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts @@ -9,7 +9,7 @@ /* * This file provides logic for migrating raw documents. */ - +import { TaskEither } from 'fp-ts/lib/TaskEither'; import { SavedObjectsRawDoc, SavedObjectsSerializer, @@ -34,6 +34,7 @@ export class CorruptSavedObjectError extends Error { Object.setPrototypeOf(this, CorruptSavedObjectError.prototype); } } + /** * Applies the specified migration function to every saved object document in the list * of raw docs. Any raw docs that are not valid saved objects will simply be passed through. @@ -69,48 +70,59 @@ export async function migrateRawDocs( } return processedDocs; } -export interface MigrateRawDocsNonThrowing { + +/** TINA: approach options for https://github.com/elastic/kibana/issues/90279: + * don't log the errors + * return a list of processed docs and errors + * log those errors somewhere upstream in the next method that returns a complete list (using a new log message "corrupt-saved-object-${index-prefix}-${doc._id}" type) + */ +export interface DocumentsTransformFailed { + type: string; + corruptSavedObjectIds: string[]; +} +export interface DocumentsTransformSuccess { processedDocs: SavedObjectsRawDoc[]; - corruptSavedObjectErrors?: CorruptSavedObjectError[]; } -/** approach options: - * 1. use a collection of processed docs and errors that we generate - * 2. log the errors -> we have the logger but aren't using it - * 3. return the transformed docs and throw away the corruptSavedObjectsErrors - */ + export async function migrateRawDocsNonThrowing( serializer: SavedObjectsSerializer, migrateDoc: MigrateAndConvertFn, rawDocs: SavedObjectsRawDoc[], log: SavedObjectsMigrationLogger -): Promise { + // This method should never fail because we're returning an array of something, either transformed raw saved objects or an array of saved object ids. + // According to the docs we should be using a Task for process that will never fail +): TaskEither { const migrateDocWithoutBlocking = transformNonBlocking(migrateDoc); - const processedDocs = []; - const corruptSavedObjectErrors = []; - for (const raw of rawDocs) { - const options = { namespaceTreatment: 'lax' as const }; - if (serializer.isRawSavedObject(raw, options)) { - const savedObject = serializer.rawToSavedObject(raw, options); - savedObject.migrationVersion = savedObject.migrationVersion || {}; - processedDocs.push( - ...(await migrateDocWithoutBlocking(savedObject)).map((attrs) => - serializer.savedObjectToRaw({ - references: [], - ...attrs, - }) - ) - ); - } else { - corruptSavedObjectErrors.push(new CorruptSavedObjectError(raw._id)); + const processedDocs: SavedObjectsRawDoc[] = []; + const corruptSavedObjectIds: string[] = []; + try { + for (const raw of rawDocs) { + const options = { namespaceTreatment: 'lax' as const }; + if (serializer.isRawSavedObject(raw, options)) { + const savedObject = serializer.rawToSavedObject(raw, options); + savedObject.migrationVersion = savedObject.migrationVersion || {}; + processedDocs.push( + ...(await migrateDocWithoutBlocking(savedObject)).map((attrs) => + serializer.savedObjectToRaw({ + references: [], + ...attrs, + }) + ) + ); + } else { + // should we be pushing only the id onto this array or the whole doc? + corruptSavedObjectIds.push(raw._id); + } } + if (corruptSavedObjectIds.length > 0) { + // Do we need to return an error in order to transform the method into a TaskEither? i.e. should we return an error for a bulk failure. e.g. + // return Either.left({ type: 'document_transform_failed', new DocumentTransformFailuresError(corruptSavedObjectIds.toString())}) + return { type: 'document_transform_failed', corruptSavedObjectIds }; + } + return { processedDocs }; + } catch (e) { + throw e; } - if (corruptSavedObjectErrors.length > 0) { - corruptSavedObjectErrors.forEach((error) => { - log.error(error.message, error); - }); - } - // a promise only returns one thing. We want to return both things - return processedDocs; } /** * Migration transform functions are potentially CPU heavy e.g. doing decryption/encryption diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts index 3a7cc836ed796..73206035cdf4f 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts @@ -201,12 +201,6 @@ export class KibanaMigrator { migrationVersionPerType: this.documentMigrator.migrationVersion, indexPrefix: index, migrationsConfig: this.soMigrationsConfig, - captureTransformRawDocsErrors: (collection: Error[], specificErrors: Error[]) => - logCorruptSavedObjectsErrors( - collection, - specificErrors, - new MigrationLogger(this.log) - ), }); }, }; @@ -281,6 +275,7 @@ export type LogCorruptSavedObjectsErrors = ( ) => string; // TINA there's a better way to handle this and I don't think we even need // to but I'm trying to not have to throw in OUTDATED_DOCUMENTS_TRANSFORM +// don't need to do this, we just throw from next. These will be different errors though thrown from the transform raw docs function export function logCorruptSavedObjectsErrors( existing: Error[], newCollection: Error[], diff --git a/src/core/server/saved_objects/migrationsv2/actions/index.ts b/src/core/server/saved_objects/migrationsv2/actions/index.ts index 02d3f8e21a510..619a2501d486a 100644 --- a/src/core/server/saved_objects/migrationsv2/actions/index.ts +++ b/src/core/server/saved_objects/migrationsv2/actions/index.ts @@ -604,7 +604,6 @@ export const waitForPickupUpdatedMappingsTask = flow( } ) ); - export interface AliasNotFound { type: 'alias_not_found_exception'; } diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index acf0f620136a2..a0dcde3ab2e29 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -580,6 +580,7 @@ export const model = (currentState: State, resW: ResponseType): throwBadResponse(stateP, left); } } + // TINA } else if (stateP.controlState === 'OUTDATED_DOCUMENTS_SEARCH') { const res = resW as ExcludeRetryableEsError>; if (Either.isRight(res)) { @@ -602,14 +603,34 @@ export const model = (currentState: State, resW: ResponseType): throwBadResponse(stateP, res); } } else if (stateP.controlState === 'OUTDATED_DOCUMENTS_TRANSFORM') { - const res = resW as ExcludeRetryableEsError>; + // if any docs can't be migrated we don't try to index any ones that can and continue with the search to build up a complete list of all the error docs + // res should have processedDocs and the corruptSavedObjectIds (actual error with the doc Ids embedded in the error message string. + // there may be more than document Id in the error string and we'll need to split the string to do a count) + const res = resW as ExcludeRetryableEsError>; // we actually need both the success and failed results here. if (Either.isRight(res)) { + // if we don't have any corrupt documents on state then index the transformed docs + // state needs a new property for corruptSavedObjects + if (stateP.corruptSavedObjectIds.length === 0) { + return { + ...stateP, + controlState: 'TRANSFORMED_DOCUMENTS_BULK_INDEX', + }; + } else { + // we do have a collection of corruptSavedObjectDocs and need to reissue the OUTDATED_DOCUMENTS_SEARCH + // carry on searching through the rest of the batches + return { + ...stateP, + controlState: 'OUTDATED_DOCUMENTS_SEARCH', + }; + } + } else { + // handles the case when we return a Either.Left situation that is when the return from migrateRawDocsNonThrowing is an instance of Either.Left containing the function that returns the promise of corruptSavedObjects (they're errors right now but we might want to change that to a list of raw._id) return { ...stateP, controlState: 'OUTDATED_DOCUMENTS_SEARCH', + corruptSavedObjectIds: [...stateP.corruptSavedObjectIds, res.corruptSavedObjectIds], }; - } else { - throwBadResponse(stateP, res); + // throwBadResponse(stateP, res); } } else if (stateP.controlState === 'UPDATE_TARGET_MAPPINGS') { const res = resW as ExcludeRetryableEsError>; diff --git a/src/core/server/saved_objects/migrationsv2/next.ts b/src/core/server/saved_objects/migrationsv2/next.ts index 47053d6149c52..e92bae336086c 100644 --- a/src/core/server/saved_objects/migrationsv2/next.ts +++ b/src/core/server/saved_objects/migrationsv2/next.ts @@ -9,7 +9,6 @@ import * as TaskEither from 'fp-ts/lib/TaskEither'; import * as Option from 'fp-ts/lib/Option'; import { UnwrapPromise } from '@kbn/utility-types'; -import { pipe } from 'fp-ts/lib/pipeable'; import type { AllActionStates, ReindexSourceToTempState, @@ -36,14 +35,18 @@ import type { } from './types'; import * as Actions from './actions'; import { ElasticsearchClient } from '../../elasticsearch'; -import { SavedObjectsRawDoc } from '..'; +import { SavedObjectsRawDoc } from '../serialization'; import { - LogCaptureTransformRawDocsErrors, - LogCorruptSavedObjectsErrors, -} from '../migrations/kibana/kibana_migrator'; -import { MigrationLogger } from '../migrations/core/migration_logger'; + DocumentsTransformFailed, + DocumentsTransformSuccess, +} from '../migrations/core/migrate_raw_docs'; + +// How do i handle this type now that transformRawDocs is actually running migrateRawDocsNonThrowing +// migrateRawDocsNonThrowing returns an Either.left with failed docs or an Either.right with successfylly processed/transformed docs +export type TransformRawDocs = ( + processedDocs: SavedObjectsRawDoc[] | { corruptSavedObjectIds: string[]; type: string } +) => Promise; -export type TransformRawDocs = (rawDocs: SavedObjectsRawDoc[]) => Promise; type ActionMap = ReturnType; /** @@ -56,11 +59,7 @@ export type ResponseType = UnwrapPromise< ReturnType> >; -export const nextActionMap = ( - client: ElasticsearchClient, - transformRawDocs: TransformRawDocs, - captureTransformRawDocsErrors: LogCaptureTransformRawDocsErrors -) => { +export const nextActionMap = (client: ElasticsearchClient, transformRawDocs: TransformRawDocs) => { return { INIT: (state: InitState) => Actions.fetchIndices(client, [state.currentAlias, state.versionAlias]), @@ -98,20 +97,22 @@ export const nextActionMap = ( outdatedDocumentsQuery: state.outdatedDocumentsQuery, }), OUTDATED_DOCUMENTS_TRANSFORM: (state: OutdatedDocumentsTransform) => - pipe( - TaskEither.tryCatch( - () => transformRawDocs(state.outdatedDocuments), - (e) => { - captureTransformRawDocsErrors(state.errors, e); - // TINA: we don't want to throw here, these errors are never caught - throw e; - } - ), - // if we decide to return the CorruptSavedObjectsErrors, the return signature of `transformRawDocs` will change - TaskEither.chain((docs) => - Actions.bulkOverwriteTransformedDocuments(client, state.targetIndex, docs) - ) + // this needs to change because we're no longer throwing anything from the transformRawDocs method + TaskEither.tryCatch( + () => transformRawDocs(state.outdatedDocuments), // one of { processedDocs } or { type: 'document_transform_failed', corruptSavedObjectIds } + (e) => { + // TINA: we throw for realy bad errors + throw e; + } ), + TRANSFORMED_DOCUMENTS_BULK_INDEX: (state: any) => + // The call to this action was being handled in OUTDATES_DOCUMENTS_TRANSFORM: + // TaskEither.chain((docs) => + // Actions.bulkOverwriteTransformedDocuments(client, state.targetIndex, docs) + // ) + // ), + // How to I get access to the processedDocs now? + Actions.bulkOverwriteTransformedDocuments(client, state.targetIndex, docs.processedDocs), MARK_VERSION_INDEX_READY: (state: MarkVersionIndexReady) => Actions.updateAliases(client, state.versionIndexReadyActions.value), MARK_VERSION_INDEX_READY_CONFLICT: (state: MarkVersionIndexReadyConflict) => @@ -136,12 +137,8 @@ export const nextActionMap = ( }; }; -export const next = ( - client: ElasticsearchClient, - transformRawDocs: TransformRawDocs, - captureTransformRawDocsErrors: LogCorruptSavedObjectsErrors -) => { - const map = nextActionMap(client, transformRawDocs, captureTransformRawDocsErrors); +export const next = (client: ElasticsearchClient, transformRawDocs: TransformRawDocs) => { + const map = nextActionMap(client, transformRawDocs); return (state: State) => { const delay = any>(fn: F): (() => ReturnType) => { return () => { diff --git a/src/core/server/saved_objects/migrationsv2/types.ts b/src/core/server/saved_objects/migrationsv2/types.ts index 9db47da777188..10de0e5d0d491 100644 --- a/src/core/server/saved_objects/migrationsv2/types.ts +++ b/src/core/server/saved_objects/migrationsv2/types.ts @@ -205,7 +205,7 @@ export type OutdatedDocumentsSearch = PostInitState & { /** Search for outdated documents in the target index */ readonly controlState: 'OUTDATED_DOCUMENTS_SEARCH'; }; - +// this has changed because we're no longer writing the latest version of the documents to the target index. export type OutdatedDocumentsTransform = PostInitState & { /** Transform a batch of outdated documents to their latest version and write them to the target index */ readonly controlState: 'OUTDATED_DOCUMENTS_TRANSFORM'; @@ -295,6 +295,14 @@ export type LegacyDeleteState = LegacyBaseState & { readonly controlState: 'LEGACY_DELETE'; }; +export type TransformedDocumentsBulkIndex = LegacyBaseState & { + /** + * Write the up-to-date transformed documents to the index, overwriting any + * documents that are still on their outdated version. + */ + readonly controlState: 'TRANSFORMED_DOCUMENTS_BULK_INDEX'; +}; + export type State = | FatalState | InitState From 96c2901fcefee2edaab703cb06ebeacf0cff4dad Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Mon, 12 Apr 2021 16:36:34 -0700 Subject: [PATCH 03/27] Converts migrateRawDocsNonThrowing into a TaskEither implementation --- .../migrations/core/migrate_raw_docs.ts | 33 ++++----- .../migrations/kibana/kibana_migrator.ts | 36 ---------- .../migrationsv2/actions/index.ts | 2 + .../saved_objects/migrationsv2/index.ts | 6 +- .../migrations_state_action_machine.ts | 6 -- .../saved_objects/migrationsv2/model.ts | 70 +++++++++++++------ .../server/saved_objects/migrationsv2/next.ts | 23 ++---- .../saved_objects/migrationsv2/types.ts | 20 +++--- 8 files changed, 80 insertions(+), 116 deletions(-) diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts index 65e291bb4567a..e3fe5b27efbf1 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts @@ -9,7 +9,8 @@ /* * This file provides logic for migrating raw documents. */ -import { TaskEither } from 'fp-ts/lib/TaskEither'; +import * as TaskEither from 'fp-ts/lib/TaskEither'; +import * as Either from 'fp-ts/lib/Either'; import { SavedObjectsRawDoc, SavedObjectsSerializer, @@ -78,24 +79,22 @@ export async function migrateRawDocs( */ export interface DocumentsTransformFailed { type: string; - corruptSavedObjectIds: string[]; + failedDocumentIds: string[]; } export interface DocumentsTransformSuccess { processedDocs: SavedObjectsRawDoc[]; } -export async function migrateRawDocsNonThrowing( +export function migrateRawDocsNonThrowing( serializer: SavedObjectsSerializer, migrateDoc: MigrateAndConvertFn, rawDocs: SavedObjectsRawDoc[], log: SavedObjectsMigrationLogger - // This method should never fail because we're returning an array of something, either transformed raw saved objects or an array of saved object ids. - // According to the docs we should be using a Task for process that will never fail -): TaskEither { - const migrateDocWithoutBlocking = transformNonBlocking(migrateDoc); - const processedDocs: SavedObjectsRawDoc[] = []; - const corruptSavedObjectIds: string[] = []; - try { +): TaskEither.TaskEither { + return async () => { + const migrateDocWithoutBlocking = transformNonBlocking(migrateDoc); + const processedDocs: SavedObjectsRawDoc[] = []; + const corruptSavedObjectIds: string[] = []; for (const raw of rawDocs) { const options = { namespaceTreatment: 'lax' as const }; if (serializer.isRawSavedObject(raw, options)) { @@ -110,19 +109,17 @@ export async function migrateRawDocsNonThrowing( ) ); } else { - // should we be pushing only the id onto this array or the whole doc? corruptSavedObjectIds.push(raw._id); } } if (corruptSavedObjectIds.length > 0) { - // Do we need to return an error in order to transform the method into a TaskEither? i.e. should we return an error for a bulk failure. e.g. - // return Either.left({ type: 'document_transform_failed', new DocumentTransformFailuresError(corruptSavedObjectIds.toString())}) - return { type: 'document_transform_failed', corruptSavedObjectIds }; + return Either.left({ + type: 'documents_transform_failed', + failedDocumentIds: [...corruptSavedObjectIds], + }); } - return { processedDocs }; - } catch (e) { - throw e; - } + return Either.right({ processedDocs }); + }; } /** * Migration transform functions are potentially CPU heavy e.g. doing decryption/encryption diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts index 73206035cdf4f..d27311280ff89 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts @@ -178,7 +178,6 @@ export class KibanaMigrator { if (this.soMigrationsConfig.enableV2) { return { migrate: (): Promise => { - // TINA: adapt runResilientMigrator to handle the new return format for v2 version of migrateRawDocs => migrateRawDocsNonThrowing return runResilientMigrator({ client: this.client, kibanaVersion: this.kibanaVersion, @@ -192,12 +191,6 @@ export class KibanaMigrator { rawDocs, new MigrationLogger(this.log) ), - // migrateRawDocs( - // this.serializer, - // this.documentMigrator.migrateAndConvert, - // rawDocs, - // new MigrationLogger(this.log) - // ), migrationVersionPerType: this.documentMigrator.migrationVersion, indexPrefix: index, migrationsConfig: this.soMigrationsConfig, @@ -262,32 +255,3 @@ export function mergeTypes(types: SavedObjectsType[]): SavedObjectsTypeMappingDe }; }, {}); } - -export interface LogCaptureTransformRawDocsErrors { - (existing: Error[], newCollection: Error[], log: MigrationLogger): string; - (arg0: Error[] | undefined, arg1: unknown): void; -} - -export type LogCorruptSavedObjectsErrors = ( - existing: Error[], - newCollection: Error[], - log: MigrationLogger -) => string; -// TINA there's a better way to handle this and I don't think we even need -// to but I'm trying to not have to throw in OUTDATED_DOCUMENTS_TRANSFORM -// don't need to do this, we just throw from next. These will be different errors though thrown from the transform raw docs function -export function logCorruptSavedObjectsErrors( - existing: Error[], - newCollection: Error[], - logger: MigrationLogger -) { - if (newCollection && newCollection.length > 0) { - newCollection.map((entry) => { - existing.push(entry); - }); - } - if (existing && existing.length > 0) { - existing.forEach((accumulatedError) => logger.info(accumulatedError.message)); - } - return 'logging complete'; -} diff --git a/src/core/server/saved_objects/migrationsv2/actions/index.ts b/src/core/server/saved_objects/migrationsv2/actions/index.ts index 619a2501d486a..b25c39b3964ba 100644 --- a/src/core/server/saved_objects/migrationsv2/actions/index.ts +++ b/src/core/server/saved_objects/migrationsv2/actions/index.ts @@ -21,6 +21,7 @@ import { catchRetryableEsClientErrors, RetryableEsClientError, } from './catch_retryable_es_client_errors'; +import { DocumentsTransformFailed } from '../../migrations/core/migrate_raw_docs'; export type { RetryableEsClientError }; /** @@ -45,6 +46,7 @@ export interface ActionErrorTypeMap { incompatible_mapping_exception: IncompatibleMappingException; alias_not_found_exception: AliasNotFound; remove_index_not_a_concrete_index: RemoveIndexNotAConcreteIndex; + documents_transform_failed: DocumentsTransformFailed; } /** diff --git a/src/core/server/saved_objects/migrationsv2/index.ts b/src/core/server/saved_objects/migrationsv2/index.ts index 7ef4eb486ba18..6e65a2e700fd3 100644 --- a/src/core/server/saved_objects/migrationsv2/index.ts +++ b/src/core/server/saved_objects/migrationsv2/index.ts @@ -15,7 +15,6 @@ import { next, TransformRawDocs } from './next'; import { createInitialState, model } from './model'; import { migrationStateActionMachine } from './migrations_state_action_machine'; import { SavedObjectsMigrationConfigType } from '../saved_objects_config'; -import { LogCorruptSavedObjectsErrors } from '../migrations/kibana/kibana_migrator'; /** * Migrates the provided indexPrefix index using a resilient algorithm that is @@ -32,7 +31,6 @@ export async function runResilientMigrator({ migrationVersionPerType, indexPrefix, migrationsConfig, - captureTransformRawDocsErrors, }: { client: ElasticsearchClient; kibanaVersion: string; @@ -43,8 +41,6 @@ export async function runResilientMigrator({ migrationVersionPerType: SavedObjectsMigrationVersion; indexPrefix: string; migrationsConfig: SavedObjectsMigrationConfigType; - // TINA: added to log errors and not throw in OUTDATED_DOCUMENTS_TRANSFORM - captureTransformRawDocsErrors: LogCorruptSavedObjectsErrors; }): Promise { const initialState = createInitialState({ kibanaVersion, @@ -57,7 +53,7 @@ export async function runResilientMigrator({ return migrationStateActionMachine({ initialState, logger, - next: next(client, transformRawDocs, captureTransformRawDocsErrors), + next: next(client, transformRawDocs), model, }); } diff --git a/src/core/server/saved_objects/migrationsv2/migrations_state_action_machine.ts b/src/core/server/saved_objects/migrationsv2/migrations_state_action_machine.ts index fd2c240564476..86bf145956549 100644 --- a/src/core/server/saved_objects/migrationsv2/migrations_state_action_machine.ts +++ b/src/core/server/saved_objects/migrationsv2/migrations_state_action_machine.ts @@ -53,7 +53,6 @@ const logActionResponse = ( ) => { logger.debug(logMessagePrefix + `${state.controlState} RESPONSE`, res as LogMeta); }; -// naming here is misleading, dumpExecutionLog "dumps" the log messages, it doesn't delete them. const dumpExecutionLog = (logger: Logger, logMessagePrefix: string, executionLog: ExecutionLog) => { logger.error(logMessagePrefix + 'migration failed, dumping execution log:'); executionLog.forEach((log) => { @@ -177,11 +176,6 @@ export async function migrationStateActionMachine({ logger.error(e); dumpExecutionLog(logger, logMessagePrefix, executionLog); - if (e instanceof CorruptSavedObjectError) { - throw new Error( - `${e.message} To allow migrations to proceed, please delete this document from the [${initialState.indexPrefix}_${initialState.kibanaVersion}_001] index.` - ); - } throw new Error( `Unable to complete saved object migrations for the [${initialState.indexPrefix}] index. ${e}` diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index a0dcde3ab2e29..8b50cca5a4f23 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -202,6 +202,7 @@ export const model = (currentState: State, resW: ResponseType): indices[aliases[stateP.currentAlias]].mappings ), versionIndexReadyActions: Option.none, + failedDocumentIds: [], }; } else if ( // `.kibana` is pointing to an index that belongs to a later @@ -563,6 +564,7 @@ export const model = (currentState: State, resW: ResponseType): return { ...stateP, controlState: 'OUTDATED_DOCUMENTS_SEARCH', + failedDocumentIds: [], }; } else { const left = res.left; @@ -575,6 +577,7 @@ export const model = (currentState: State, resW: ResponseType): return { ...stateP, controlState: 'OUTDATED_DOCUMENTS_SEARCH', + failedDocumentIds: [], }; } else { throwBadResponse(stateP, left); @@ -592,45 +595,55 @@ export const model = (currentState: State, resW: ResponseType): outdatedDocuments: res.right.outdatedDocuments, }; } else { - // If there are no more results we have transformed all outdated - // documents and can proceed to the next step - return { - ...stateP, - controlState: 'UPDATE_TARGET_MAPPINGS', - }; + if (stateP.failedDocumentIds.length > 0) { + // We have documents that couldn't be transformed and exit out of the migration + return { + ...stateP, + controlState: 'FATAL', + reason: `Migrations failed because of the following corrupt saved object documents: ${JSON.stringify( + stateP.failedDocumentIds + )}. To allow migrations to proceed, please delete thse documents.`, + }; + } else { + // If there are no more results we have transformed all outdated + // documents and can proceed to the next step + return { + ...stateP, + controlState: 'UPDATE_TARGET_MAPPINGS', + }; + } } } else { throwBadResponse(stateP, res); } } else if (stateP.controlState === 'OUTDATED_DOCUMENTS_TRANSFORM') { - // if any docs can't be migrated we don't try to index any ones that can and continue with the search to build up a complete list of all the error docs - // res should have processedDocs and the corruptSavedObjectIds (actual error with the doc Ids embedded in the error message string. - // there may be more than document Id in the error string and we'll need to split the string to do a count) - const res = resW as ExcludeRetryableEsError>; // we actually need both the success and failed results here. + const res = resW as ExcludeRetryableEsError>; if (Either.isRight(res)) { - // if we don't have any corrupt documents on state then index the transformed docs - // state needs a new property for corruptSavedObjects - if (stateP.corruptSavedObjectIds.length === 0) { + if (res.right.processedDocs.length > 0) { + if (stateP.failedDocumentIds.length === 0) { + return { ...stateP, controlState: 'TRANSFORMED_DOCUMENTS_BULK_INDEX' }; + } else { + return { ...stateP, controlState: 'OUTDATED_DOCUMENTS_SEARCH' }; + } + } else { + return { ...stateP, controlState: 'OUTDATED_DOCUMENTS_SEARCH' }; + } + } else if (Either.isLeft(res) && isLeftTypeof(res.left, 'documents_transform_failed')) { + if (stateP.failedDocumentIds.length === 0) { return { ...stateP, - controlState: 'TRANSFORMED_DOCUMENTS_BULK_INDEX', + controlState: 'OUTDATED_DOCUMENTS_SEARCH', + failedDocumentIds: [...res.left.failedDocumentIds], }; } else { - // we do have a collection of corruptSavedObjectDocs and need to reissue the OUTDATED_DOCUMENTS_SEARCH - // carry on searching through the rest of the batches return { ...stateP, controlState: 'OUTDATED_DOCUMENTS_SEARCH', + failedDocumentIds: [...stateP.failedDocumentIds, ...res.left.failedDocumentIds], }; } } else { - // handles the case when we return a Either.Left situation that is when the return from migrateRawDocsNonThrowing is an instance of Either.Left containing the function that returns the promise of corruptSavedObjects (they're errors right now but we might want to change that to a list of raw._id) - return { - ...stateP, - controlState: 'OUTDATED_DOCUMENTS_SEARCH', - corruptSavedObjectIds: [...stateP.corruptSavedObjectIds, res.corruptSavedObjectIds], - }; - // throwBadResponse(stateP, res); + throwBadResponse(stateP, res as never); } } else if (stateP.controlState === 'UPDATE_TARGET_MAPPINGS') { const res = resW as ExcludeRetryableEsError>; @@ -643,6 +656,17 @@ export const model = (currentState: State, resW: ResponseType): } else { throwBadResponse(stateP, res); } + } else if (stateP.controlState === 'TRANSFORMED_DOCUMENTS_BULK_INDEX') { + const res = resW as ExcludeRetryableEsError>; + if (Either.isRight(res)) { + return { + ...stateP, + controlState: 'OUTDATED_DOCUMENTS_SEARCH', + failedDocumentIds: [], + }; + } else { + throwBadResponse(stateP, res); + } } else if (stateP.controlState === 'UPDATE_TARGET_MAPPINGS_WAIT_FOR_TASK') { const res = resW as ExcludeRetryableEsError>; if (Either.isRight(res)) { diff --git a/src/core/server/saved_objects/migrationsv2/next.ts b/src/core/server/saved_objects/migrationsv2/next.ts index e92bae336086c..0888ba8b4e522 100644 --- a/src/core/server/saved_objects/migrationsv2/next.ts +++ b/src/core/server/saved_objects/migrationsv2/next.ts @@ -41,11 +41,9 @@ import { DocumentsTransformSuccess, } from '../migrations/core/migrate_raw_docs'; -// How do i handle this type now that transformRawDocs is actually running migrateRawDocsNonThrowing -// migrateRawDocsNonThrowing returns an Either.left with failed docs or an Either.right with successfylly processed/transformed docs export type TransformRawDocs = ( - processedDocs: SavedObjectsRawDoc[] | { corruptSavedObjectIds: string[]; type: string } -) => Promise; + processedDocs: SavedObjectsRawDoc[] +) => TaskEither.TaskEither; type ActionMap = ReturnType; @@ -97,22 +95,9 @@ export const nextActionMap = (client: ElasticsearchClient, transformRawDocs: Tra outdatedDocumentsQuery: state.outdatedDocumentsQuery, }), OUTDATED_DOCUMENTS_TRANSFORM: (state: OutdatedDocumentsTransform) => - // this needs to change because we're no longer throwing anything from the transformRawDocs method - TaskEither.tryCatch( - () => transformRawDocs(state.outdatedDocuments), // one of { processedDocs } or { type: 'document_transform_failed', corruptSavedObjectIds } - (e) => { - // TINA: we throw for realy bad errors - throw e; - } - ), + transformRawDocs(state.outdatedDocuments), TRANSFORMED_DOCUMENTS_BULK_INDEX: (state: any) => - // The call to this action was being handled in OUTDATES_DOCUMENTS_TRANSFORM: - // TaskEither.chain((docs) => - // Actions.bulkOverwriteTransformedDocuments(client, state.targetIndex, docs) - // ) - // ), - // How to I get access to the processedDocs now? - Actions.bulkOverwriteTransformedDocuments(client, state.targetIndex, docs.processedDocs), + Actions.bulkOverwriteTransformedDocuments(client, state.targetIndex, state.processedDocs), MARK_VERSION_INDEX_READY: (state: MarkVersionIndexReady) => Actions.updateAliases(client, state.versionIndexReadyActions.value), MARK_VERSION_INDEX_READY_CONFLICT: (state: MarkVersionIndexReadyConflict) => diff --git a/src/core/server/saved_objects/migrationsv2/types.ts b/src/core/server/saved_objects/migrationsv2/types.ts index 10de0e5d0d491..b55003f12ac37 100644 --- a/src/core/server/saved_objects/migrationsv2/types.ts +++ b/src/core/server/saved_objects/migrationsv2/types.ts @@ -204,13 +204,22 @@ export type UpdateTargetMappingsWaitForTaskState = PostInitState & { export type OutdatedDocumentsSearch = PostInitState & { /** Search for outdated documents in the target index */ readonly controlState: 'OUTDATED_DOCUMENTS_SEARCH'; + readonly failedDocumentIds: string[]; }; -// this has changed because we're no longer writing the latest version of the documents to the target index. + export type OutdatedDocumentsTransform = PostInitState & { /** Transform a batch of outdated documents to their latest version and write them to the target index */ readonly controlState: 'OUTDATED_DOCUMENTS_TRANSFORM'; readonly outdatedDocuments: SavedObjectsRawDoc[]; readonly errors?: Error[]; + readonly failedDocumentIds: string[]; +}; +export type TransformedDocumentsBulkIndex = PostInitState & { + /** + * Write the up-to-date transformed documents to the index, overwriting any + * documents that are still on their outdated version. + */ + readonly controlState: 'TRANSFORMED_DOCUMENTS_BULK_INDEX'; }; export type MarkVersionIndexReady = PostInitState & { @@ -295,14 +304,6 @@ export type LegacyDeleteState = LegacyBaseState & { readonly controlState: 'LEGACY_DELETE'; }; -export type TransformedDocumentsBulkIndex = LegacyBaseState & { - /** - * Write the up-to-date transformed documents to the index, overwriting any - * documents that are still on their outdated version. - */ - readonly controlState: 'TRANSFORMED_DOCUMENTS_BULK_INDEX'; -}; - export type State = | FatalState | InitState @@ -321,6 +322,7 @@ export type State = | OutdatedDocumentsTransform | MarkVersionIndexReady | MarkVersionIndexReadyConflict + | TransformedDocumentsBulkIndex | LegacyCreateReindexTargetState | LegacySetWriteBlockState | LegacyReindexState From b0eb13f86386d1522eec65d290e81a2fa75ed091 Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Tue, 13 Apr 2021 16:35:42 -0700 Subject: [PATCH 04/27] Adds unit tests for model -> OUTDATED_DOCUMENTS_TRANSFORM and TRANSFORMED_DOCUMENTS_BULK_INDEX --- .../migrations_state_action_machine.ts | 1 - .../saved_objects/migrationsv2/model.test.ts | 113 ++++++++++++++++-- .../saved_objects/migrationsv2/model.ts | 17 ++- .../saved_objects/migrationsv2/types.ts | 1 + 4 files changed, 121 insertions(+), 11 deletions(-) diff --git a/src/core/server/saved_objects/migrationsv2/migrations_state_action_machine.ts b/src/core/server/saved_objects/migrationsv2/migrations_state_action_machine.ts index 86bf145956549..1b3bb022d6e40 100644 --- a/src/core/server/saved_objects/migrationsv2/migrations_state_action_machine.ts +++ b/src/core/server/saved_objects/migrationsv2/migrations_state_action_machine.ts @@ -9,7 +9,6 @@ import { errors as EsErrors } from '@elastic/elasticsearch'; import * as Option from 'fp-ts/lib/Option'; import { Logger, LogMeta } from '../../logging'; -import { CorruptSavedObjectError } from '../migrations/core/migrate_raw_docs'; import { Model, Next, stateActionMachine } from './state_action_machine'; import { State } from './types'; diff --git a/src/core/server/saved_objects/migrationsv2/model.test.ts b/src/core/server/saved_objects/migrationsv2/model.test.ts index 0267ae33dd157..86006df851a9b 100644 --- a/src/core/server/saved_objects/migrationsv2/model.test.ts +++ b/src/core/server/saved_objects/migrationsv2/model.test.ts @@ -31,6 +31,7 @@ import type { CloneTempToSource, SetTempWriteBlock, WaitForYellowSourceState, + TransformedDocumentsBulkIndex, } from './types'; import { SavedObjectsRawDoc } from '..'; import { AliasAction, RetryableEsClientError } from './actions'; @@ -868,6 +869,7 @@ describe('migrations v2 model', () => { versionIndexReadyActions: Option.none, sourceIndex: Option.some('.kibana') as Option.Some, targetIndex: '.kibana_7.11.0_001', + failedDocumentIds: [], }; test('OUTDATED_DOCUMENTS_SEARCH -> OUTDATED_DOCUMENTS_TRANSFORM if some outdated documents were found', () => { const outdatedDocuments = ([ @@ -923,15 +925,110 @@ describe('migrations v2 model', () => { sourceIndex: Option.some('.kibana') as Option.Some, targetIndex: '.kibana_7.11.0_001', outdatedDocuments, + failedDocumentIds: [], }; - test('OUTDATED_DOCUMENTS_TRANSFORM -> OUTDATED_DOCUMENTS_SEARCH if action succeeds', () => { - const res: ResponseType<'OUTDATED_DOCUMENTS_TRANSFORM'> = Either.right( - 'bulk_index_succeeded' - ); - const newState = model(outdatedDocumentsTransformState, res); - expect(newState.controlState).toEqual('OUTDATED_DOCUMENTS_SEARCH'); - expect(newState.retryCount).toEqual(0); - expect(newState.retryDelay).toEqual(0); + describe('OUTDATED_DOCUMENTS_TRANSFORM if action succeeds', () => { + const processedDocs = ([Symbol('raw saved object doc')] as unknown) as SavedObjectsRawDoc[]; + const failedTransformDocumentIds = ([ + Symbol('raw saved object doc ID'), + ] as unknown) as string[]; + test('OUTDATED_DOCUMENTS_TRANSFORM -> TRANSFORMED_DOCUMENTS_BULK_INDEX if action succeeds', () => { + const res: ResponseType<'OUTDATED_DOCUMENTS_TRANSFORM'> = Either.right({ processedDocs }); + const newState = model( + outdatedDocumentsTransformState, + res + ) as TransformedDocumentsBulkIndex; + expect(newState.controlState).toEqual('TRANSFORMED_DOCUMENTS_BULK_INDEX'); + expect(newState.transformedDocs).toEqual(processedDocs); + expect(newState.retryCount).toEqual(0); + expect(newState.retryDelay).toEqual(0); + }); + test('OUTDATED_DOCUMENTS_TRANSFORM -> OUTDATED_DOCUMENTS_SEARCH if there are are existing documents that failed transformation', () => { + const outdatedDocumentsTransformStateWithFailedDocuments: OutdatedDocumentsTransform = { + ...outdatedDocumentsTransformState, + failedDocumentIds: [...failedTransformDocumentIds], + }; + const res: ResponseType<'OUTDATED_DOCUMENTS_TRANSFORM'> = Either.right({ processedDocs }); + const newState = model( + outdatedDocumentsTransformStateWithFailedDocuments, + res + ) as OutdatedDocumentsSearch; + expect(newState.controlState).toEqual('OUTDATED_DOCUMENTS_SEARCH'); + expect(newState.failedDocumentIds).toEqual(failedTransformDocumentIds); + expect(newState.retryCount).toEqual(0); + expect(newState.retryDelay).toEqual(0); + }); + test("OUTDATED_DOCUMENTS_TRANSFORM -> OUTDATED_DOCUMENTS_SEARCH if we don't have any processed docs returned", () => { + const res: ResponseType<'OUTDATED_DOCUMENTS_TRANSFORM'> = Either.right({ + processedDocs: [], + }); + const newState = model(outdatedDocumentsTransformState, res) as OutdatedDocumentsSearch; + expect(newState.controlState).toEqual('OUTDATED_DOCUMENTS_SEARCH'); + expect(newState.failedDocumentIds).toEqual([]); + }); + }); + describe('OUTDATED_DOCUMENTS_TRANSFORM if action fails', () => { + test('OUTDATED_DOCUMENTS_TRANSFORM -> OUTDATED_DOCUMENTS_SEARCH adding newly failed documents to state if documents failed the transform', () => { + const failedTransformDocumentIds = ([ + Symbol('raw saved object doc ID'), + ] as unknown) as string[]; + const res: ResponseType<'OUTDATED_DOCUMENTS_TRANSFORM'> = Either.left({ + type: 'documents_transform_failed', + failedDocumentIds: failedTransformDocumentIds, + }); + const newState = model(outdatedDocumentsTransformState, res) as OutdatedDocumentsSearch; + expect(newState.controlState).toEqual('OUTDATED_DOCUMENTS_SEARCH'); + expect(newState.failedDocumentIds).toEqual(failedTransformDocumentIds); + }); + test('OUTDATED_DOCUMENTS_TRANSFORM -> OUTDATED_DOCUMENTS_SEARCH combines newly failed documents with those already on state if documents failed the transform', () => { + const failedTransformDocumentIds = ([ + Symbol('raw saved object doc ID'), + ] as unknown) as string[]; + const newFailedTransformDocumentIds = ([ + Symbol('raw saved object doc ID 2'), + ] as unknown) as string[]; + const outdatedDocumentsTransformStateWithFailedDocuments: OutdatedDocumentsTransform = { + ...outdatedDocumentsTransformState, + failedDocumentIds: [...failedTransformDocumentIds], + }; + const res: ResponseType<'OUTDATED_DOCUMENTS_TRANSFORM'> = Either.left({ + type: 'documents_transform_failed', + failedDocumentIds: newFailedTransformDocumentIds, + }); + const newState = model( + outdatedDocumentsTransformStateWithFailedDocuments, + res + ) as OutdatedDocumentsSearch; + expect(newState.controlState).toEqual('OUTDATED_DOCUMENTS_SEARCH'); + expect(newState.failedDocumentIds).toEqual([ + ...failedTransformDocumentIds, + ...newFailedTransformDocumentIds, + ]); + }); + }); + }); + describe('TRANSFORMED_DOCUMENTS_BULK_INDEX', () => { + const transformedDocs = ([Symbol('raw saved object doc')] as unknown) as SavedObjectsRawDoc[]; + const transformedDocumentsBulkIndexState: TransformedDocumentsBulkIndex = { + ...baseState, + controlState: 'TRANSFORMED_DOCUMENTS_BULK_INDEX', + transformedDocs, + versionIndexReadyActions: Option.none, + sourceIndex: Option.some('.kibana') as Option.Some, + targetIndex: '.kibana_7.11.0_001', + }; + test('TRANSFORMED_DOCUMENTS_BULK_INDEX should throw a throwBadResponse error if action failed', () => { + const res: ResponseType<'TRANSFORMED_DOCUMENTS_BULK_INDEX'> = Either.left({ + type: 'retryable_es_client_error', + message: 'random transform documents bulk error', + }); + const newState = model( + transformedDocumentsBulkIndexState, + res + ) as TransformedDocumentsBulkIndex; + expect(newState.controlState).toEqual('TRANSFORMED_DOCUMENTS_BULK_INDEX'); + expect(newState.retryCount).toEqual(1); + expect(newState.retryDelay).toEqual(2000); }); }); describe('UPDATE_TARGET_MAPPINGS', () => { diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index 8b50cca5a4f23..ad8ef40db81e8 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -621,11 +621,24 @@ export const model = (currentState: State, resW: ResponseType): if (Either.isRight(res)) { if (res.right.processedDocs.length > 0) { if (stateP.failedDocumentIds.length === 0) { - return { ...stateP, controlState: 'TRANSFORMED_DOCUMENTS_BULK_INDEX' }; + return { + ...stateP, + controlState: 'TRANSFORMED_DOCUMENTS_BULK_INDEX', + transformedDocs: [...res.right.processedDocs], + }; } else { - return { ...stateP, controlState: 'OUTDATED_DOCUMENTS_SEARCH' }; + return { + ...stateP, + controlState: 'OUTDATED_DOCUMENTS_SEARCH', + failedDocumentIds: [...stateP.failedDocumentIds], // not strictly nescessary but being explicit for readability + }; } } else { + // we shouldn't get to this condition because migrateRawDocsNonThrowing that means: + // we've received outdated documents from OUTDATED_DOCUMENTS_SEARCH + // none of thos outdated documents were successfully transformed (processedDocs is empty) + // we're in the success case + // Question: Should be not be throwing a Bad Response? return { ...stateP, controlState: 'OUTDATED_DOCUMENTS_SEARCH' }; } } else if (Either.isLeft(res) && isLeftTypeof(res.left, 'documents_transform_failed')) { diff --git a/src/core/server/saved_objects/migrationsv2/types.ts b/src/core/server/saved_objects/migrationsv2/types.ts index b55003f12ac37..9a263fd472e25 100644 --- a/src/core/server/saved_objects/migrationsv2/types.ts +++ b/src/core/server/saved_objects/migrationsv2/types.ts @@ -220,6 +220,7 @@ export type TransformedDocumentsBulkIndex = PostInitState & { * documents that are still on their outdated version. */ readonly controlState: 'TRANSFORMED_DOCUMENTS_BULK_INDEX'; + readonly transformedDocs: SavedObjectsRawDoc[]; }; export type MarkVersionIndexReady = PostInitState & { From 0b14388f4eb67bef9125094c93eb0fc67195354e Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Mon, 19 Apr 2021 11:48:36 -0700 Subject: [PATCH 05/27] Keeps track of transform scripts failing during migrations --- .../migrations/core/document_migrator.test.ts | 14 +- .../migrations/core/document_migrator.ts | 30 +++- .../saved_objects/migrations/core/index.ts | 6 + .../migrations/core/migrate_raw_docs.test.ts | 161 +++++++++++++++++- .../migrations/core/migrate_raw_docs.ts | 42 ++++- ...nsform_saved_object_document_error.test.ts | 45 +++++ .../transform_saved_object_document_error.ts | 49 ++++++ .../migrations/kibana/kibana_migrator.ts | 2 +- .../saved_objects/migrationsv2/model.test.ts | 72 +++++--- .../saved_objects/migrationsv2/model.ts | 80 ++++----- .../server/saved_objects/migrationsv2/next.ts | 2 +- .../saved_objects/migrationsv2/types.ts | 7 +- 12 files changed, 426 insertions(+), 84 deletions(-) create mode 100644 src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.test.ts create mode 100644 src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts diff --git a/src/core/server/saved_objects/migrations/core/document_migrator.test.ts b/src/core/server/saved_objects/migrations/core/document_migrator.test.ts index 1cf408ea96a56..45286f158edb1 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.test.ts @@ -11,6 +11,7 @@ import { set } from '@elastic/safer-lodash-set'; import _ from 'lodash'; import { SavedObjectUnsanitizedDoc } from '../../serialization'; import { DocumentMigrator } from './document_migrator'; +import { TransformSavedObjectDocumentError } from './transform_saved_object_document_error'; import { loggingSystemMock } from '../../../logging/logging_system.mock'; import { SavedObjectsType } from '../../types'; import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; @@ -724,6 +725,12 @@ describe('DocumentMigrator', () => { it('logs the original error and throws a transform error if a document transform fails', () => { const log = mockLogger; + const failedDoc = { + id: 'smelly', + type: 'dog', + attributes: {}, + migrationVersion: {}, + }; const migrator = new DocumentMigrator({ ...testOpts(), typeRegistry: createRegistry({ @@ -737,12 +744,6 @@ describe('DocumentMigrator', () => { log, }); migrator.prepareMigrations(); - const failedDoc = { - id: 'smelly', - type: 'dog', - attributes: {}, - migrationVersion: {}, - }; try { migrator.migrate(_.cloneDeep(failedDoc)); expect('Did not throw').toEqual('But it should have!'); @@ -751,6 +752,7 @@ describe('DocumentMigrator', () => { "Failed to transform document smelly. Transform: dog:1.2.3 Doc: {\\"id\\":\\"smelly\\",\\"type\\":\\"dog\\",\\"attributes\\":{},\\"migrationVersion\\":{}}" `); + expect(error).toBeInstanceOf(TransformSavedObjectDocumentError); expect(loggingSystemMock.collect(mockLoggerFactory).error[0][0]).toMatchInlineSnapshot( `[Error: Dang diggity!]` ); 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..c96fa199d4b49 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.ts @@ -62,6 +62,7 @@ import { SavedObjectsType, } from '../../types'; import { MigrationLogger } from './migration_logger'; +import { TransformSavedObjectDocumentError } from '.'; import { ISavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { SavedObjectMigrationFn, SavedObjectMigrationMap } from '../types'; import { DEFAULT_NAMESPACE_STRING } from '../../service/lib/utils'; @@ -652,6 +653,24 @@ function transformComparator(a: Transform, b: Transform) { /** * If a specific transform function fails, this tacks on a bit of information * about the document and transform that caused the failure. + * + * TINA: + * @remarks + * ideally (to make debugging failed migrations easier), we want to return an Either.left type with: + * the actual error and + * the failedTransform + * the rawDoc Id (not the id on the unsanitizedDoc that we have here), + * the serializer has a `generateRawId` method to do that but it's using other stuff from within the Serializer class + * we can either pass the serializer.generateRawId down into here somehow or + * send the stuff the method needs back up and generate the ids from within migrateRawDocsNonThrowing + * FYI: rawDocumentId: generateRawId(doc.namespace, doc.type, doc.id), // (doc.id) just the uuid part, so doesn't tell users what the full elasticsearch id is + * return { + * failedTransform, + * error, + * namespace: doc.namespace, + * type: doc.type, + * id: doc.id, + * }; */ function wrapWithTry( version: string, @@ -680,8 +699,15 @@ function wrapWithTry( const failedDoc = JSON.stringify(doc); log.error(error); - throw new Error( - `Failed to transform document ${doc?.id}. Transform: ${failedTransform}\nDoc: ${failedDoc}` + // changing the error being thrown to an object or an instance of Either.left requires refactoring a lot of try/catch implementations further upstream within v2 migrations. + // as an initial improvement, we're adding more information to the error that's thrown (full error itself). + throw new TransformSavedObjectDocumentError( + doc.id, + doc.type, + doc.namespace ?? 'N/A', + failedTransform, + failedDoc, + error ); } }; diff --git a/src/core/server/saved_objects/migrations/core/index.ts b/src/core/server/saved_objects/migrations/core/index.ts index 1e51983a0ffbd..ca54d6876ad75 100644 --- a/src/core/server/saved_objects/migrations/core/index.ts +++ b/src/core/server/saved_objects/migrations/core/index.ts @@ -15,3 +15,9 @@ export type { MigrationResult, MigrationStatus } from './migration_coordinator'; export { createMigrationEsClient } from './migration_es_client'; export type { MigrationEsClient } from './migration_es_client'; export { excludeUnusedTypesQuery } from './elastic_index'; +export { TransformSavedObjectDocumentError } from './transform_saved_object_document_error'; +export type { + DocumentsTransformFailed, + DocumentsTransformSuccess, + TransformErrorObjects, +} from './migrate_raw_docs'; diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts index ce12bd22a0712..2e01b51249f44 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts @@ -10,8 +10,9 @@ import { set } from '@elastic/safer-lodash-set'; import _ from 'lodash'; import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { SavedObjectsSerializer } from '../../serialization'; -import { migrateRawDocs } from './migrate_raw_docs'; +import { migrateRawDocs, migrateRawDocsNonThrowing } from './migrate_raw_docs'; import { createSavedObjectsMigrationLoggerMock } from '../../migrations/mocks'; +import { TransformSavedObjectDocumentError } from './transform_saved_object_document_error'; describe('migrateRawDocs', () => { test('converts raw docs to saved objects', async () => { @@ -128,3 +129,161 @@ describe('migrateRawDocs', () => { ).rejects.toThrowErrorMatchingInlineSnapshot(`"error during transform"`); }); }); + +describe('migrateRawDocsNonThrowing', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + // create an instance of a TransformSavedObjectDocumentError; + + test('converts raw docs to saved objects', async () => { + let result: any; + const transform = jest.fn((doc: any) => [ + set(_.cloneDeep(doc), 'attributes.name', 'HOI!'), + ]); + const task = migrateRawDocsNonThrowing( + new SavedObjectsSerializer(new SavedObjectTypeRegistry()), + transform, + [ + { _id: 'a:b', _source: { type: 'a', a: { name: 'AAA' } } }, + { _id: 'c:d', _source: { type: 'c', c: { name: 'DDD' } } }, + ], + createSavedObjectsMigrationLoggerMock() + ); + try { + result = await task(); + } catch (e) { + /** ignore */ + } + expect(result._tag).toEqual('Right'); + expect(result.right.processedDocs).toEqual([ + { + _id: 'a:b', + _source: { type: 'a', a: { name: 'HOI!' }, migrationVersion: {}, references: [] }, + }, + { + _id: 'c:d', + _source: { type: 'c', c: { name: 'HOI!' }, migrationVersion: {}, references: [] }, + }, + ]); + + const obj1 = { + id: 'b', + type: 'a', + attributes: { name: 'AAA' }, + migrationVersion: {}, + references: [], + }; + const obj2 = { + id: 'd', + type: 'c', + attributes: { name: 'DDD' }, + migrationVersion: {}, + references: [], + }; + expect(transform).toHaveBeenCalledTimes(2); + expect(transform).toHaveBeenNthCalledWith(1, obj1); + expect(transform).toHaveBeenNthCalledWith(2, obj2); + }); + test('returns a `left` tag when encountering a corrupt saved object document', async () => { + let result: any; + const logger = createSavedObjectsMigrationLoggerMock(); + const transform = jest.fn((doc: any) => [ + set(_.cloneDeep(doc), 'attributes.name', 'TADA'), + ]); + const task = migrateRawDocsNonThrowing( + new SavedObjectsSerializer(new SavedObjectTypeRegistry()), + transform, + [ + { _id: 'foo:b', _source: { type: 'a', a: { name: 'AAA' } } }, + { _id: 'c:d', _source: { type: 'c', c: { name: 'DDD' } } }, + ], + logger + ); + try { + result = await task(); + } catch (e) { + result = e; + } + expect(transform).toHaveBeenCalledTimes(1); + expect(result._tag).toEqual('Left'); + expect(Object.keys(result.left)).toEqual(['type', 'corruptDocumentIds', 'transformErrors']); + expect(result.left.corruptDocumentIds.length).toEqual(1); + expect(result.left.transformErrors.length).toEqual(0); + }); + + test('handles when one document is transformed into multiple documents', async () => { + let result: any; + const transform = jest.fn((doc: any) => [ + set(_.cloneDeep(doc), 'attributes.name', 'HOI!'), + { id: 'bar', type: 'foo', attributes: { name: 'baz' } }, + ]); + const task = migrateRawDocsNonThrowing( + new SavedObjectsSerializer(new SavedObjectTypeRegistry()), + transform, + [{ _id: 'a:b', _source: { type: 'a', a: { name: 'AAA' } } }], + createSavedObjectsMigrationLoggerMock() + ); + try { + result = await task(); + } catch (err) { + /** ignore */ + } + expect(result._tag).toEqual('Right'); + expect(result.right.processedDocs).toEqual([ + { + _id: 'a:b', + _source: { type: 'a', a: { name: 'HOI!' }, migrationVersion: {}, references: [] }, + }, + { + _id: 'foo:bar', + _source: { type: 'foo', foo: { name: 'baz' }, references: [] }, + }, + ]); + + const obj = { + id: 'b', + type: 'a', + attributes: { name: 'AAA' }, + migrationVersion: {}, + references: [], + }; + expect(transform).toHaveBeenCalledTimes(1); + expect(transform).toHaveBeenCalledWith(obj); + }); + + test('rejects when the transform function throws an error', async () => { + let result: any; + const transform = jest.fn((doc: any) => { + throw new TransformSavedObjectDocumentError( + `${doc.id}`, + `${doc.type}`, + `${doc.namespace}`, + `${doc.type}1.2.3`, + JSON.stringify(doc), + new Error('error during transform') + ); + }); + const task = migrateRawDocsNonThrowing( + new SavedObjectsSerializer(new SavedObjectTypeRegistry()), + transform, + [{ _id: 'a:b', _source: { type: 'a', a: { name: 'AAA' } } }], // this is the raw doc + createSavedObjectsMigrationLoggerMock() + ); + try { + result = await task(); + } catch (err) { + /* ignore */ + } + expect(transform).toHaveBeenCalledTimes(1); + expect(result._tag).toEqual('Left'); + expect(result.left.corruptDocumentIds.length).toEqual(0); + expect(result.left.transformErrors.length).toEqual(1); + expect(result.left.transformErrors[0].err.message).toMatchInlineSnapshot( + ` + "Failed to transform document b. Transform: a1.2.3 + Doc: {\\"type\\":\\"a\\",\\"id\\":\\"b\\",\\"attributes\\":{\\"name\\":\\"AAA\\"},\\"references\\":[],\\"migrationVersion\\":{}}" + ` + ); + }); +}); diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts index e3fe5b27efbf1..d82989ebf389f 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts @@ -17,7 +17,7 @@ import { SavedObjectUnsanitizedDoc, } from '../../serialization'; import { MigrateAndConvertFn } from './document_migrator'; -import { SavedObjectsMigrationLogger } from '.'; +import { SavedObjectsMigrationLogger, TransformSavedObjectDocumentError } from '.'; /** * Error thrown when saved object migrations encounter a corrupt saved object. @@ -79,11 +79,16 @@ export async function migrateRawDocs( */ export interface DocumentsTransformFailed { type: string; - failedDocumentIds: string[]; + corruptDocumentIds: string[]; + transformErrors: TransformErrorObjects[]; } export interface DocumentsTransformSuccess { processedDocs: SavedObjectsRawDoc[]; } +export interface TransformErrorObjects { + rawId: string; + err: TransformSavedObjectDocumentError | Error; // do we want the full error here or just the stack trace? +} export function migrateRawDocsNonThrowing( serializer: SavedObjectsSerializer, @@ -94,28 +99,47 @@ export function migrateRawDocsNonThrowing( return async () => { const migrateDocWithoutBlocking = transformNonBlocking(migrateDoc); const processedDocs: SavedObjectsRawDoc[] = []; + const transformErrors: TransformErrorObjects[] = []; // this isn't going to be an instance of an Error anymore since we're going to return an object const corruptSavedObjectIds: string[] = []; for (const raw of rawDocs) { const options = { namespaceTreatment: 'lax' as const }; if (serializer.isRawSavedObject(raw, options)) { const savedObject = serializer.rawToSavedObject(raw, options); savedObject.migrationVersion = savedObject.migrationVersion || {}; - processedDocs.push( - ...(await migrateDocWithoutBlocking(savedObject)).map((attrs) => + try { + const migratedDocs = [...(await migrateDocWithoutBlocking(savedObject))].map((attrs) => serializer.savedObjectToRaw({ references: [], ...attrs, }) - ) - ); + ); + processedDocs.push(...migratedDocs); + } catch (err) { + // if there is an error, we want to intercept it and convert the id (that is only the uuid part) to the raw document id so that users can actually act on the document where the transform script failed. + // We're passing the stack trace back up to allow easier debugging. + if (err instanceof TransformSavedObjectDocumentError) { + // the error message contains a Doc:... item that's a stringified version of the doc itself. + // the doc id we get from the error isn't a raw saved object id. The transform method throws an error from a document where the _id is only the uuid part + // transform the id in the error message to a raw saved object id. + const serializedId = serializer.generateRawId( + err.getNamespace(), + err.getType(), + err.getId() + ); + transformErrors.push({ rawId: serializedId, err }); + } else { + transformErrors.push({ rawId: 'unknown', err }); // cases we haven't accounted for yet + } + } } else { corruptSavedObjectIds.push(raw._id); } } - if (corruptSavedObjectIds.length > 0) { + if (corruptSavedObjectIds.length > 0 || transformErrors.length > 0) { return Either.left({ type: 'documents_transform_failed', - failedDocumentIds: [...corruptSavedObjectIds], + corruptDocumentIds: [...corruptSavedObjectIds], + transformErrors, }); } return Either.right({ processedDocs }); @@ -137,8 +161,10 @@ function transformNonBlocking( // set immediate is though setImmediate(() => { try { + // TINA: If we changed document_migrator `wrapWithTry` to always resolve something and return with an Either.left for a fialed case, v1 migrations would need refactoring too: v1 migrations expect an error when the document migrator runs the transform resolve(transform(doc)); } catch (e) { + // TINA: We need to continue to throw from within the transform for v1 migrations to carry on working. This can be changed when we remove v1 migrations reject(e); } }); diff --git a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.test.ts b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.test.ts new file mode 100644 index 0000000000000..57ba389268538 --- /dev/null +++ b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.test.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import { TransformSavedObjectDocumentError } from './transform_saved_object_document_error'; +// TINA TODO: +// Clean up the test input +// Add more test cases +describe('TransformSavedObjectDocumentError', () => { + it('is a special error', () => { + const originalError = new Error('Dang diggity!'); + const err = new TransformSavedObjectDocumentError( + 'id', + 'type', + 'namespace', + 'failedTransform', + 'failedDoc', + originalError + ); + expect(err).toBeInstanceOf(TransformSavedObjectDocumentError); + expect(err.id).toEqual('id'); + expect(err.namespace).toEqual('namespace'); + expect(err.stack).not.toBeNull(); + }); + it('is constructs an special error message', () => { + const originalError = new Error('Dang diggity!'); + const err = new TransformSavedObjectDocumentError( + 'id', + 'type', + 'namespace', + 'failedTransform', + 'failedDoc', + originalError + ); + expect(err.message).toMatchInlineSnapshot( + ` + "Failed to transform document id. Transform: failedTransform + Doc: failedDoc" + ` + ); + }); +}); diff --git a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts new file mode 100644 index 0000000000000..3ff1abde1f2c3 --- /dev/null +++ b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/** + * Error thrown when saved object migrations encounter a transformation error. + * Transformation errors happen when a transform function throws an error for an unsanitized saved object + * The id (doc.id) reported in this error class is just the uuid part and doesn't tell users what the full elasticsearch id is. + * in order to convert the id to the serialized version further upstream using serializer.generateRawId, we need to provide the following items: + * - namespace: doc.namespace, + * - type: doc.type, + * - id: doc.id, + * The new error class helps with v2 migrations. + * For backward compatibility with v1 migrations, the error message is the same as what was previouslt thrown as a plain error + */ + +// TINA TODO: create getters for retrieving the id, type and namespace to use in migrate_raw_doc for generating the serialized SO id +export class TransformSavedObjectDocumentError extends Error { + constructor( + public readonly id: string, + public readonly type: string, + public readonly namespace: string, + public readonly failedTransform: string, // created by document_migrator wrapWithTry as `${type.name}:${version}`; + public readonly failedDoc: string, + public readonly originalError: Error // public readonly namespace?: string--> part of the stringified failedDoc + ) { + super(`Failed to transform document ${id}. Transform: ${failedTransform}\nDoc: ${failedDoc}`); + this.id = id; + this.namespace = namespace; + this.type = type; + // Removed because not including still seems to work, it may have been an old Typescript 2.1 issue: + // Set the prototype explicitly, see: + // https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work + // Object.setPrototypeOf(this, TransformSavedObjectDocumentError.prototype); + } + public getId() { + return this.id; + } + public getNamespace() { + return this.namespace; + } + public getType() { + return this.type; + } +} diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts index d27311280ff89..d86e7082770e4 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts @@ -187,7 +187,7 @@ export class KibanaMigrator { transformRawDocs: (rawDocs: SavedObjectsRawDoc[]) => migrateRawDocsNonThrowing( this.serializer, - this.documentMigrator.migrateAndConvert, + this.documentMigrator.migrateAndConvert, // TINA: used in both v1 and v2 migrations, limiting how much we can refactor this method rawDocs, new MigrationLogger(this.log) ), diff --git a/src/core/server/saved_objects/migrationsv2/model.test.ts b/src/core/server/saved_objects/migrationsv2/model.test.ts index 86006df851a9b..bcfab86d08455 100644 --- a/src/core/server/saved_objects/migrationsv2/model.test.ts +++ b/src/core/server/saved_objects/migrationsv2/model.test.ts @@ -38,6 +38,7 @@ import { AliasAction, RetryableEsClientError } from './actions'; import { createInitialState, model } from './model'; import { ResponseType } from './next'; import { SavedObjectsMigrationConfigType } from '../saved_objects_config'; +import { TransformErrorObjects } from '../migrations/core'; describe('migrations v2 model', () => { const baseState: BaseState = { @@ -869,7 +870,8 @@ describe('migrations v2 model', () => { versionIndexReadyActions: Option.none, sourceIndex: Option.some('.kibana') as Option.Some, targetIndex: '.kibana_7.11.0_001', - failedDocumentIds: [], + corruptDocumentIds: [], + transformErrors: [], }; test('OUTDATED_DOCUMENTS_SEARCH -> OUTDATED_DOCUMENTS_TRANSFORM if some outdated documents were found', () => { const outdatedDocuments = ([ @@ -925,13 +927,18 @@ describe('migrations v2 model', () => { sourceIndex: Option.some('.kibana') as Option.Some, targetIndex: '.kibana_7.11.0_001', outdatedDocuments, - failedDocumentIds: [], + corruptDocumentIds: [], + transformErrors: [], }; describe('OUTDATED_DOCUMENTS_TRANSFORM if action succeeds', () => { const processedDocs = ([Symbol('raw saved object doc')] as unknown) as SavedObjectsRawDoc[]; - const failedTransformDocumentIds = ([ - Symbol('raw saved object doc ID'), - ] as unknown) as string[]; + const corruptDocumentIds = ([Symbol('raw saved object doc ID')] as unknown) as string[]; + const transformationErrors = ([ + { + rawId: Symbol('transform error object') as unknown, + err: Symbol('transform error itself') as unknown, + }, + ] as unknown) as TransformErrorObjects[]; test('OUTDATED_DOCUMENTS_TRANSFORM -> TRANSFORMED_DOCUMENTS_BULK_INDEX if action succeeds', () => { const res: ResponseType<'OUTDATED_DOCUMENTS_TRANSFORM'> = Either.right({ processedDocs }); const newState = model( @@ -946,7 +953,8 @@ describe('migrations v2 model', () => { test('OUTDATED_DOCUMENTS_TRANSFORM -> OUTDATED_DOCUMENTS_SEARCH if there are are existing documents that failed transformation', () => { const outdatedDocumentsTransformStateWithFailedDocuments: OutdatedDocumentsTransform = { ...outdatedDocumentsTransformState, - failedDocumentIds: [...failedTransformDocumentIds], + corruptDocumentIds: [...corruptDocumentIds], + transformErrors: [], }; const res: ResponseType<'OUTDATED_DOCUMENTS_TRANSFORM'> = Either.right({ processedDocs }); const newState = model( @@ -954,54 +962,68 @@ describe('migrations v2 model', () => { res ) as OutdatedDocumentsSearch; expect(newState.controlState).toEqual('OUTDATED_DOCUMENTS_SEARCH'); - expect(newState.failedDocumentIds).toEqual(failedTransformDocumentIds); + expect(newState.corruptDocumentIds).toEqual(corruptDocumentIds); expect(newState.retryCount).toEqual(0); expect(newState.retryDelay).toEqual(0); }); - test("OUTDATED_DOCUMENTS_TRANSFORM -> OUTDATED_DOCUMENTS_SEARCH if we don't have any processed docs returned", () => { - const res: ResponseType<'OUTDATED_DOCUMENTS_TRANSFORM'> = Either.right({ - processedDocs: [], - }); - const newState = model(outdatedDocumentsTransformState, res) as OutdatedDocumentsSearch; + test('OUTDATED_DOCUMENTS_TRANSFORM -> OUTDATED_DOCUMENTS_SEARCH if there are are existing documents that failed transformation because of transform errors', () => { + const outdatedDocumentsTransformStateWithFailedDocuments: OutdatedDocumentsTransform = { + ...outdatedDocumentsTransformState, + corruptDocumentIds: [], + transformErrors: [...transformationErrors], + }; + const res: ResponseType<'OUTDATED_DOCUMENTS_TRANSFORM'> = Either.right({ processedDocs }); + const newState = model( + outdatedDocumentsTransformStateWithFailedDocuments, + res + ) as OutdatedDocumentsSearch; expect(newState.controlState).toEqual('OUTDATED_DOCUMENTS_SEARCH'); - expect(newState.failedDocumentIds).toEqual([]); + expect(newState.corruptDocumentIds.length).toEqual(0); + expect(newState.transformErrors.length).toEqual(1); + expect(newState.retryCount).toEqual(0); + expect(newState.retryDelay).toEqual(0); }); }); describe('OUTDATED_DOCUMENTS_TRANSFORM if action fails', () => { test('OUTDATED_DOCUMENTS_TRANSFORM -> OUTDATED_DOCUMENTS_SEARCH adding newly failed documents to state if documents failed the transform', () => { - const failedTransformDocumentIds = ([ - Symbol('raw saved object doc ID'), - ] as unknown) as string[]; + const corruptDocumentIds = ([Symbol('raw saved object doc ID')] as unknown) as string[]; const res: ResponseType<'OUTDATED_DOCUMENTS_TRANSFORM'> = Either.left({ type: 'documents_transform_failed', - failedDocumentIds: failedTransformDocumentIds, + corruptDocumentIds, + transformErrors: [], }); const newState = model(outdatedDocumentsTransformState, res) as OutdatedDocumentsSearch; expect(newState.controlState).toEqual('OUTDATED_DOCUMENTS_SEARCH'); - expect(newState.failedDocumentIds).toEqual(failedTransformDocumentIds); + expect(newState.corruptDocumentIds).toEqual(corruptDocumentIds); }); test('OUTDATED_DOCUMENTS_TRANSFORM -> OUTDATED_DOCUMENTS_SEARCH combines newly failed documents with those already on state if documents failed the transform', () => { - const failedTransformDocumentIds = ([ - Symbol('raw saved object doc ID'), - ] as unknown) as string[]; + const corruptDocumentIds = ([Symbol('raw saved object doc ID')] as unknown) as string[]; + const transformationErrors = ([ + { + rawId: Symbol('transform error object') as unknown, + err: Symbol('transform error itself') as unknown, + }, + ] as unknown) as TransformErrorObjects[]; const newFailedTransformDocumentIds = ([ Symbol('raw saved object doc ID 2'), ] as unknown) as string[]; const outdatedDocumentsTransformStateWithFailedDocuments: OutdatedDocumentsTransform = { ...outdatedDocumentsTransformState, - failedDocumentIds: [...failedTransformDocumentIds], + corruptDocumentIds: [...corruptDocumentIds], + transformErrors: [...transformationErrors], }; const res: ResponseType<'OUTDATED_DOCUMENTS_TRANSFORM'> = Either.left({ type: 'documents_transform_failed', - failedDocumentIds: newFailedTransformDocumentIds, + corruptDocumentIds: newFailedTransformDocumentIds, + transformErrors: transformationErrors, }); const newState = model( outdatedDocumentsTransformStateWithFailedDocuments, res ) as OutdatedDocumentsSearch; expect(newState.controlState).toEqual('OUTDATED_DOCUMENTS_SEARCH'); - expect(newState.failedDocumentIds).toEqual([ - ...failedTransformDocumentIds, + expect(newState.corruptDocumentIds).toEqual([ + ...corruptDocumentIds, ...newFailedTransformDocumentIds, ]); }); diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index ad8ef40db81e8..a20b37a7564e1 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -202,7 +202,8 @@ export const model = (currentState: State, resW: ResponseType): indices[aliases[stateP.currentAlias]].mappings ), versionIndexReadyActions: Option.none, - failedDocumentIds: [], + corruptDocumentIds: [], + transformErrors: [], }; } else if ( // `.kibana` is pointing to an index that belongs to a later @@ -564,7 +565,8 @@ export const model = (currentState: State, resW: ResponseType): return { ...stateP, controlState: 'OUTDATED_DOCUMENTS_SEARCH', - failedDocumentIds: [], + corruptDocumentIds: [], + transformErrors: [], }; } else { const left = res.left; @@ -577,7 +579,8 @@ export const model = (currentState: State, resW: ResponseType): return { ...stateP, controlState: 'OUTDATED_DOCUMENTS_SEARCH', - failedDocumentIds: [], + corruptDocumentIds: [], + transformErrors: [], }; } else { throwBadResponse(stateP, left); @@ -595,18 +598,31 @@ export const model = (currentState: State, resW: ResponseType): outdatedDocuments: res.right.outdatedDocuments, }; } else { - if (stateP.failedDocumentIds.length > 0) { - // We have documents that couldn't be transformed and exit out of the migration + // we don't have any more outdated documents and need to either fail or move on to updating the target mappins. + if (stateP.corruptDocumentIds.length > 0 || stateP.transformErrors.length > 0) { + // If documents couldn't be transformed or there were transformation errors we fail the migration + const corruptDocumentIdReason = + stateP.corruptDocumentIds.length > 0 + ? `The following corrupt saved object documents: ${JSON.stringify( + stateP.corruptDocumentIds + )}` + : ''; + // we have both the saved object Id and the stack trace in each `transformErrors` item. + const transformErrorsReason = + stateP.transformErrors.length > 0 + ? `the following saved object documents could not be transformed: ${JSON.stringify( + stateP.transformErrors + )}` + : ''; return { ...stateP, controlState: 'FATAL', - reason: `Migrations failed because of the following corrupt saved object documents: ${JSON.stringify( - stateP.failedDocumentIds - )}. To allow migrations to proceed, please delete thse documents.`, + reason: `Migrations failed. Reason: ${corruptDocumentIdReason} ${transformErrorsReason}. To allow migrations to proceed, please delete these documents.`, }; } else { // If there are no more results we have transformed all outdated - // documents and can proceed to the next step + // documents and we didn't encounter any corrupt documents or transformation errors + // and can proceed to the next step return { ...stateP, controlState: 'UPDATE_TARGET_MAPPINGS', @@ -619,44 +635,31 @@ export const model = (currentState: State, resW: ResponseType): } else if (stateP.controlState === 'OUTDATED_DOCUMENTS_TRANSFORM') { const res = resW as ExcludeRetryableEsError>; if (Either.isRight(res)) { - if (res.right.processedDocs.length > 0) { - if (stateP.failedDocumentIds.length === 0) { - return { - ...stateP, - controlState: 'TRANSFORMED_DOCUMENTS_BULK_INDEX', - transformedDocs: [...res.right.processedDocs], - }; - } else { - return { - ...stateP, - controlState: 'OUTDATED_DOCUMENTS_SEARCH', - failedDocumentIds: [...stateP.failedDocumentIds], // not strictly nescessary but being explicit for readability - }; - } - } else { - // we shouldn't get to this condition because migrateRawDocsNonThrowing that means: - // we've received outdated documents from OUTDATED_DOCUMENTS_SEARCH - // none of thos outdated documents were successfully transformed (processedDocs is empty) - // we're in the success case - // Question: Should be not be throwing a Bad Response? - return { ...stateP, controlState: 'OUTDATED_DOCUMENTS_SEARCH' }; - } - } else if (Either.isLeft(res) && isLeftTypeof(res.left, 'documents_transform_failed')) { - if (stateP.failedDocumentIds.length === 0) { + // we haven't seen corrupt documents or any transformation errors thus far in the migration + if (stateP.corruptDocumentIds.length === 0 && stateP.transformErrors.length === 0) { return { ...stateP, - controlState: 'OUTDATED_DOCUMENTS_SEARCH', - failedDocumentIds: [...res.left.failedDocumentIds], + controlState: 'TRANSFORMED_DOCUMENTS_BULK_INDEX', + transformedDocs: [...res.right.processedDocs], }; } else { + // We have seen corrupt documents or any transformation errors and continue searching for more, state already has these on it return { ...stateP, controlState: 'OUTDATED_DOCUMENTS_SEARCH', - failedDocumentIds: [...stateP.failedDocumentIds, ...res.left.failedDocumentIds], }; } } else { - throwBadResponse(stateP, res as never); + if (isLeftTypeof(res.left, 'documents_transform_failed')) { + return { + ...stateP, + controlState: 'OUTDATED_DOCUMENTS_SEARCH', + corruptDocumentIds: [...stateP.corruptDocumentIds, ...res.left.corruptDocumentIds], + transformErrors: [...stateP.transformErrors, ...res.left.transformErrors], + }; + } else { + throwBadResponse(stateP, res as never); + } } } else if (stateP.controlState === 'UPDATE_TARGET_MAPPINGS') { const res = resW as ExcludeRetryableEsError>; @@ -675,7 +678,8 @@ export const model = (currentState: State, resW: ResponseType): return { ...stateP, controlState: 'OUTDATED_DOCUMENTS_SEARCH', - failedDocumentIds: [], + corruptDocumentIds: [], + transformErrors: [], }; } else { throwBadResponse(stateP, res); diff --git a/src/core/server/saved_objects/migrationsv2/next.ts b/src/core/server/saved_objects/migrationsv2/next.ts index 0888ba8b4e522..8c64a70faab93 100644 --- a/src/core/server/saved_objects/migrationsv2/next.ts +++ b/src/core/server/saved_objects/migrationsv2/next.ts @@ -97,7 +97,7 @@ export const nextActionMap = (client: ElasticsearchClient, transformRawDocs: Tra OUTDATED_DOCUMENTS_TRANSFORM: (state: OutdatedDocumentsTransform) => transformRawDocs(state.outdatedDocuments), TRANSFORMED_DOCUMENTS_BULK_INDEX: (state: any) => - Actions.bulkOverwriteTransformedDocuments(client, state.targetIndex, state.processedDocs), + Actions.bulkOverwriteTransformedDocuments(client, state.targetIndex, state.transformedDocs), MARK_VERSION_INDEX_READY: (state: MarkVersionIndexReady) => Actions.updateAliases(client, state.versionIndexReadyActions.value), MARK_VERSION_INDEX_READY_CONFLICT: (state: MarkVersionIndexReadyConflict) => diff --git a/src/core/server/saved_objects/migrationsv2/types.ts b/src/core/server/saved_objects/migrationsv2/types.ts index 9a263fd472e25..d84e372eeea05 100644 --- a/src/core/server/saved_objects/migrationsv2/types.ts +++ b/src/core/server/saved_objects/migrationsv2/types.ts @@ -12,6 +12,7 @@ import { ControlState } from './state_action_machine'; import { AliasAction } from './actions'; import { IndexMapping } from '../mappings'; import { SavedObjectsRawDoc } from '..'; +import { TransformErrorObjects } from '../migrations/core'; export interface BaseState extends ControlState { /** The first part of the index name such as `.kibana` or `.kibana_task_manager` */ @@ -204,7 +205,8 @@ export type UpdateTargetMappingsWaitForTaskState = PostInitState & { export type OutdatedDocumentsSearch = PostInitState & { /** Search for outdated documents in the target index */ readonly controlState: 'OUTDATED_DOCUMENTS_SEARCH'; - readonly failedDocumentIds: string[]; + readonly corruptDocumentIds: string[]; + readonly transformErrors: TransformErrorObjects[]; }; export type OutdatedDocumentsTransform = PostInitState & { @@ -212,7 +214,8 @@ export type OutdatedDocumentsTransform = PostInitState & { readonly controlState: 'OUTDATED_DOCUMENTS_TRANSFORM'; readonly outdatedDocuments: SavedObjectsRawDoc[]; readonly errors?: Error[]; - readonly failedDocumentIds: string[]; + readonly corruptDocumentIds: string[]; + readonly transformErrors: TransformErrorObjects[]; }; export type TransformedDocumentsBulkIndex = PostInitState & { /** From 1f7a3895f7720bf82bc7f59b0629c458944b61fe Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Wed, 21 Apr 2021 16:49:02 -0700 Subject: [PATCH 06/27] Factors out common functionality in migrate_raw_docs, adds state type, cleans up comments --- .../migrations/core/migrate_raw_docs.test.ts | 17 +-- .../migrations/core/migrate_raw_docs.ts | 128 +++++++++++------- .../transform_saved_object_document_error.ts | 11 +- .../migrations/kibana/kibana_migrator.ts | 6 +- .../saved_objects/migrationsv2/model.ts | 4 +- .../server/saved_objects/migrationsv2/next.ts | 3 +- .../saved_objects/migrationsv2/types.ts | 1 - 7 files changed, 91 insertions(+), 79 deletions(-) diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts index 2e01b51249f44..eeee90f8d479b 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts @@ -58,7 +58,7 @@ describe('migrateRawDocs', () => { expect(transform).toHaveBeenNthCalledWith(1, obj1); expect(transform).toHaveBeenNthCalledWith(2, obj2); }); - // we don't want to throw + test('throws when encountering a corrupt saved object document', async () => { const logger = createSavedObjectsMigrationLoggerMock(); const transform = jest.fn((doc: any) => [ @@ -134,7 +134,6 @@ describe('migrateRawDocsNonThrowing', () => { beforeEach(() => { jest.clearAllMocks(); }); - // create an instance of a TransformSavedObjectDocumentError; test('converts raw docs to saved objects', async () => { let result: any; @@ -147,8 +146,7 @@ describe('migrateRawDocsNonThrowing', () => { [ { _id: 'a:b', _source: { type: 'a', a: { name: 'AAA' } } }, { _id: 'c:d', _source: { type: 'c', c: { name: 'DDD' } } }, - ], - createSavedObjectsMigrationLoggerMock() + ] ); try { result = await task(); @@ -185,9 +183,9 @@ describe('migrateRawDocsNonThrowing', () => { expect(transform).toHaveBeenNthCalledWith(1, obj1); expect(transform).toHaveBeenNthCalledWith(2, obj2); }); + test('returns a `left` tag when encountering a corrupt saved object document', async () => { let result: any; - const logger = createSavedObjectsMigrationLoggerMock(); const transform = jest.fn((doc: any) => [ set(_.cloneDeep(doc), 'attributes.name', 'TADA'), ]); @@ -197,8 +195,7 @@ describe('migrateRawDocsNonThrowing', () => { [ { _id: 'foo:b', _source: { type: 'a', a: { name: 'AAA' } } }, { _id: 'c:d', _source: { type: 'c', c: { name: 'DDD' } } }, - ], - logger + ] ); try { result = await task(); @@ -221,8 +218,7 @@ describe('migrateRawDocsNonThrowing', () => { const task = migrateRawDocsNonThrowing( new SavedObjectsSerializer(new SavedObjectTypeRegistry()), transform, - [{ _id: 'a:b', _source: { type: 'a', a: { name: 'AAA' } } }], - createSavedObjectsMigrationLoggerMock() + [{ _id: 'a:b', _source: { type: 'a', a: { name: 'AAA' } } }] ); try { result = await task(); @@ -267,8 +263,7 @@ describe('migrateRawDocsNonThrowing', () => { const task = migrateRawDocsNonThrowing( new SavedObjectsSerializer(new SavedObjectTypeRegistry()), transform, - [{ _id: 'a:b', _source: { type: 'a', a: { name: 'AAA' } } }], // this is the raw doc - createSavedObjectsMigrationLoggerMock() + [{ _id: 'a:b', _source: { type: 'a', a: { name: 'AAA' } } }] // this is the raw doc ); try { result = await task(); diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts index d82989ebf389f..2695df6781df1 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts @@ -12,6 +12,7 @@ import * as TaskEither from 'fp-ts/lib/TaskEither'; import * as Either from 'fp-ts/lib/Either'; import { + SavedObjectSanitizedDoc, SavedObjectsRawDoc, SavedObjectsSerializer, SavedObjectUnsanitizedDoc, @@ -19,6 +20,22 @@ import { import { MigrateAndConvertFn } from './document_migrator'; import { SavedObjectsMigrationLogger, TransformSavedObjectDocumentError } from '.'; +export interface DocumentsTransformFailed { + type: string; + corruptDocumentIds: string[]; + transformErrors: TransformErrorObjects[]; +} +export interface DocumentsTransformSuccess { + processedDocs: SavedObjectsRawDoc[]; +} +export interface TransformErrorObjects { + rawId: string; + err: TransformSavedObjectDocumentError | Error; // do we want the full error here or just the stack trace? +} +type MigrateMethod = ( + doc: SavedObjectUnsanitizedDoc +) => Promise>>; + /** * Error thrown when saved object migrations encounter a corrupt saved object. * Corrupt saved objects cannot be serialized because: @@ -39,7 +56,6 @@ export class CorruptSavedObjectError extends Error { /** * Applies the specified migration function to every saved object document in the list * of raw docs. Any raw docs that are not valid saved objects will simply be passed through. - * * @param {TransformFn} migrateDoc * @param {SavedObjectsRawDoc[]} rawDocs * @returns {SavedObjectsRawDoc[]} @@ -55,15 +71,9 @@ export async function migrateRawDocs( for (const raw of rawDocs) { const options = { namespaceTreatment: 'lax' as const }; if (serializer.isRawSavedObject(raw, options)) { - const savedObject = serializer.rawToSavedObject(raw, options); - savedObject.migrationVersion = savedObject.migrationVersion || {}; + const savedObject = convertToRawAddMigrationVersion(raw, options, serializer); processedDocs.push( - ...(await migrateDocWithoutBlocking(savedObject)).map((attrs) => - serializer.savedObjectToRaw({ - references: [], - ...attrs, - }) - ) + ...(await migrateMapToRawDoc(migrateDocWithoutBlocking, savedObject, serializer)) ); } else { throw new CorruptSavedObjectError(raw._id); @@ -72,61 +82,43 @@ export async function migrateRawDocs( return processedDocs; } -/** TINA: approach options for https://github.com/elastic/kibana/issues/90279: - * don't log the errors - * return a list of processed docs and errors - * log those errors somewhere upstream in the next method that returns a complete list (using a new log message "corrupt-saved-object-${index-prefix}-${doc._id}" type) +/** + * Applies the specified migration function to every saved object document provided + * and converts the saved object to a raw document. + * Captures the ids and errors from any documents that are not valid saved objects or + * for which the transformation function failed. + * @param {SavedObjectsSerializer} serializer + * @param {TransformFn} migrateDoc + * @param {SavedObjectsRawDoc[]} rawDocs + * @param {SavedObjectsMigrationLogger} log + * @returns {TaskEither.TaskEither} */ -export interface DocumentsTransformFailed { - type: string; - corruptDocumentIds: string[]; - transformErrors: TransformErrorObjects[]; -} -export interface DocumentsTransformSuccess { - processedDocs: SavedObjectsRawDoc[]; -} -export interface TransformErrorObjects { - rawId: string; - err: TransformSavedObjectDocumentError | Error; // do we want the full error here or just the stack trace? -} - export function migrateRawDocsNonThrowing( serializer: SavedObjectsSerializer, migrateDoc: MigrateAndConvertFn, - rawDocs: SavedObjectsRawDoc[], - log: SavedObjectsMigrationLogger + rawDocs: SavedObjectsRawDoc[] ): TaskEither.TaskEither { return async () => { const migrateDocWithoutBlocking = transformNonBlocking(migrateDoc); const processedDocs: SavedObjectsRawDoc[] = []; - const transformErrors: TransformErrorObjects[] = []; // this isn't going to be an instance of an Error anymore since we're going to return an object + const transformErrors: TransformErrorObjects[] = []; const corruptSavedObjectIds: string[] = []; for (const raw of rawDocs) { const options = { namespaceTreatment: 'lax' as const }; if (serializer.isRawSavedObject(raw, options)) { - const savedObject = serializer.rawToSavedObject(raw, options); - savedObject.migrationVersion = savedObject.migrationVersion || {}; + const savedObject = convertToRawAddMigrationVersion(raw, options, serializer); try { - const migratedDocs = [...(await migrateDocWithoutBlocking(savedObject))].map((attrs) => - serializer.savedObjectToRaw({ - references: [], - ...attrs, - }) + processedDocs.push( + ...(await migrateMapToRawDoc(migrateDocWithoutBlocking, savedObject, serializer)) ); - processedDocs.push(...migratedDocs); } catch (err) { - // if there is an error, we want to intercept it and convert the id (that is only the uuid part) to the raw document id so that users can actually act on the document where the transform script failed. - // We're passing the stack trace back up to allow easier debugging. if (err instanceof TransformSavedObjectDocumentError) { - // the error message contains a Doc:... item that's a stringified version of the doc itself. - // the doc id we get from the error isn't a raw saved object id. The transform method throws an error from a document where the _id is only the uuid part - // transform the id in the error message to a raw saved object id. - const serializedId = serializer.generateRawId( - err.getNamespace(), - err.getType(), - err.getId() - ); - transformErrors.push({ rawId: serializedId, err }); + // the doc id we get from the error is only the uuid part of the saved object + // we want to transform the id to a raw saved object id. + transformErrors.push({ + rawId: serializer.generateRawId(err.namespace, err.type, err.id), + err, + }); } else { transformErrors.push({ rawId: 'unknown', err }); // cases we haven't accounted for yet } @@ -145,6 +137,7 @@ export function migrateRawDocsNonThrowing( return Either.right({ processedDocs }); }; } + /** * Migration transform functions are potentially CPU heavy e.g. doing decryption/encryption * or (de)/serializing large JSON payloads. @@ -161,12 +154,47 @@ function transformNonBlocking( // set immediate is though setImmediate(() => { try { - // TINA: If we changed document_migrator `wrapWithTry` to always resolve something and return with an Either.left for a fialed case, v1 migrations would need refactoring too: v1 migrations expect an error when the document migrator runs the transform resolve(transform(doc)); } catch (e) { - // TINA: We need to continue to throw from within the transform for v1 migrations to carry on working. This can be changed when we remove v1 migrations reject(e); } }); }); } + +/** + * Applies the specified migration function to every saved object document provided + * and converts the saved object to a raw document + * @param {MigrateMethod} transformNonBlocking + * @param {SavedObjectsRawDoc[]} rawDoc + * @returns {Promise} + */ +async function migrateMapToRawDoc( + migrateMethod: MigrateMethod, + savedObject: SavedObjectSanitizedDoc, + serializer: SavedObjectsSerializer +): Promise { + return [...(await migrateMethod(savedObject))].map((attrs) => + serializer.savedObjectToRaw({ + references: [], + ...attrs, + }) + ); +} + +/** + * Sanitizes the raw saved object document and sets the migration version + * @param {SavedObjectRawDoc} rawDoc + * @param options + * @param {SavedObjectsSerializer} serializer + * @returns {SavedObjectSanitizedDoc} + */ +function convertToRawAddMigrationVersion( + rawDoc: SavedObjectsRawDoc, + options: { namespaceTreatment: 'lax' }, + serializer: SavedObjectsSerializer +): SavedObjectSanitizedDoc { + const savedObject = serializer.rawToSavedObject(rawDoc, options); + savedObject.migrationVersion = savedObject.migrationVersion || {}; + return savedObject; +} diff --git a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts index 3ff1abde1f2c3..a6fc1bccc5750 100644 --- a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts +++ b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts @@ -15,7 +15,7 @@ * - type: doc.type, * - id: doc.id, * The new error class helps with v2 migrations. - * For backward compatibility with v1 migrations, the error message is the same as what was previouslt thrown as a plain error + * For backward compatibility with v1 migrations, the error message is the same as what was previously thrown as a plain error */ // TINA TODO: create getters for retrieving the id, type and namespace to use in migrate_raw_doc for generating the serialized SO id @@ -37,13 +37,4 @@ export class TransformSavedObjectDocumentError extends Error { // https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work // Object.setPrototypeOf(this, TransformSavedObjectDocumentError.prototype); } - public getId() { - return this.id; - } - public getNamespace() { - return this.namespace; - } - public getType() { - return this.type; - } } diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts index d86e7082770e4..70275213a5063 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts @@ -135,7 +135,6 @@ export class KibanaMigrator { if (!rerun) { this.status$.next({ status: 'running' }); } - // TINA: this.runMigrationsInternal()'s return signature is going to change this.migrationResult = this.runMigrationsInternal().then((result) => { // Similar to above, don't publish status updates when rerunning in CI. if (!rerun) { @@ -187,9 +186,8 @@ export class KibanaMigrator { transformRawDocs: (rawDocs: SavedObjectsRawDoc[]) => migrateRawDocsNonThrowing( this.serializer, - this.documentMigrator.migrateAndConvert, // TINA: used in both v1 and v2 migrations, limiting how much we can refactor this method - rawDocs, - new MigrationLogger(this.log) + this.documentMigrator.migrateAndConvert, + rawDocs ), migrationVersionPerType: this.documentMigrator.migrationVersion, indexPrefix: index, diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index a20b37a7564e1..a66c47581939c 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -603,8 +603,8 @@ export const model = (currentState: State, resW: ResponseType): // If documents couldn't be transformed or there were transformation errors we fail the migration const corruptDocumentIdReason = stateP.corruptDocumentIds.length > 0 - ? `The following corrupt saved object documents: ${JSON.stringify( - stateP.corruptDocumentIds + ? `The following corrupt saved object documents: ${stateP.corruptDocumentIds.join( + ',' )}` : ''; // we have both the saved object Id and the stack trace in each `transformErrors` item. diff --git a/src/core/server/saved_objects/migrationsv2/next.ts b/src/core/server/saved_objects/migrationsv2/next.ts index 8c64a70faab93..3ca70673cb279 100644 --- a/src/core/server/saved_objects/migrationsv2/next.ts +++ b/src/core/server/saved_objects/migrationsv2/next.ts @@ -32,6 +32,7 @@ import type { CloneTempToSource, SetTempWriteBlock, WaitForYellowSourceState, + TransformedDocumentsBulkIndex, } from './types'; import * as Actions from './actions'; import { ElasticsearchClient } from '../../elasticsearch'; @@ -96,7 +97,7 @@ export const nextActionMap = (client: ElasticsearchClient, transformRawDocs: Tra }), OUTDATED_DOCUMENTS_TRANSFORM: (state: OutdatedDocumentsTransform) => transformRawDocs(state.outdatedDocuments), - TRANSFORMED_DOCUMENTS_BULK_INDEX: (state: any) => + TRANSFORMED_DOCUMENTS_BULK_INDEX: (state: TransformedDocumentsBulkIndex) => Actions.bulkOverwriteTransformedDocuments(client, state.targetIndex, state.transformedDocs), MARK_VERSION_INDEX_READY: (state: MarkVersionIndexReady) => Actions.updateAliases(client, state.versionIndexReadyActions.value), diff --git a/src/core/server/saved_objects/migrationsv2/types.ts b/src/core/server/saved_objects/migrationsv2/types.ts index d84e372eeea05..156a5803c0b0a 100644 --- a/src/core/server/saved_objects/migrationsv2/types.ts +++ b/src/core/server/saved_objects/migrationsv2/types.ts @@ -213,7 +213,6 @@ export type OutdatedDocumentsTransform = PostInitState & { /** Transform a batch of outdated documents to their latest version and write them to the target index */ readonly controlState: 'OUTDATED_DOCUMENTS_TRANSFORM'; readonly outdatedDocuments: SavedObjectsRawDoc[]; - readonly errors?: Error[]; readonly corruptDocumentIds: string[]; readonly transformErrors: TransformErrorObjects[]; }; From d7ba06cb0ec2c278050bc3d37110d0d07f93d81d Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Wed, 21 Apr 2021 17:05:44 -0700 Subject: [PATCH 07/27] Cleans up more code comments --- .../migrations/core/document_migrator.ts | 23 ++----------------- ...nsform_saved_object_document_error.test.ts | 4 +--- .../transform_saved_object_document_error.ts | 1 - 3 files changed, 3 insertions(+), 25 deletions(-) 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 c96fa199d4b49..51fc9e2ad5dec 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.ts @@ -653,24 +653,6 @@ function transformComparator(a: Transform, b: Transform) { /** * If a specific transform function fails, this tacks on a bit of information * about the document and transform that caused the failure. - * - * TINA: - * @remarks - * ideally (to make debugging failed migrations easier), we want to return an Either.left type with: - * the actual error and - * the failedTransform - * the rawDoc Id (not the id on the unsanitizedDoc that we have here), - * the serializer has a `generateRawId` method to do that but it's using other stuff from within the Serializer class - * we can either pass the serializer.generateRawId down into here somehow or - * send the stuff the method needs back up and generate the ids from within migrateRawDocsNonThrowing - * FYI: rawDocumentId: generateRawId(doc.namespace, doc.type, doc.id), // (doc.id) just the uuid part, so doesn't tell users what the full elasticsearch id is - * return { - * failedTransform, - * error, - * namespace: doc.namespace, - * type: doc.type, - * id: doc.id, - * }; */ function wrapWithTry( version: string, @@ -698,9 +680,8 @@ function wrapWithTry( const failedTransform = `${type.name}:${version}`; const failedDoc = JSON.stringify(doc); log.error(error); - - // changing the error being thrown to an object or an instance of Either.left requires refactoring a lot of try/catch implementations further upstream within v2 migrations. - // as an initial improvement, we're adding more information to the error that's thrown (full error itself). + // To make debugging failed migrations easier, we add items needed to convert the + // saved object id to the full raw id (the id only contains the uuid part) and the full error itself throw new TransformSavedObjectDocumentError( doc.id, doc.type, diff --git a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.test.ts b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.test.ts index 57ba389268538..cc50967708094 100644 --- a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.test.ts +++ b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.test.ts @@ -6,9 +6,7 @@ * Side Public License, v 1. */ import { TransformSavedObjectDocumentError } from './transform_saved_object_document_error'; -// TINA TODO: -// Clean up the test input -// Add more test cases + describe('TransformSavedObjectDocumentError', () => { it('is a special error', () => { const originalError = new Error('Dang diggity!'); diff --git a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts index a6fc1bccc5750..31cdd8c152969 100644 --- a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts +++ b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts @@ -18,7 +18,6 @@ * For backward compatibility with v1 migrations, the error message is the same as what was previously thrown as a plain error */ -// TINA TODO: create getters for retrieving the id, type and namespace to use in migrate_raw_doc for generating the serialized SO id export class TransformSavedObjectDocumentError extends Error { constructor( public readonly id: string, From 6dd4d8999fa44e4bc629cdcbdd3efcdd59c6127b Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Thu, 22 Apr 2021 11:34:03 -0700 Subject: [PATCH 08/27] Formats transformation errors reason for migration failing better, specifies namespace as undefined for multi-namespace saved objects --- .../migrations/core/document_migrator.ts | 2 +- ...ransform_saved_object_document_error.test.ts | 17 +++++++++++++++++ .../transform_saved_object_document_error.ts | 2 +- .../server/saved_objects/migrationsv2/model.ts | 7 ++++--- 4 files changed, 23 insertions(+), 5 deletions(-) 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 51fc9e2ad5dec..3ce1c19d38c91 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.ts @@ -685,7 +685,7 @@ function wrapWithTry( throw new TransformSavedObjectDocumentError( doc.id, doc.type, - doc.namespace ?? 'N/A', + doc.namespace ?? undefined, failedTransform, failedDoc, error diff --git a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.test.ts b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.test.ts index cc50967708094..f80b4aaddcdb9 100644 --- a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.test.ts +++ b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.test.ts @@ -40,4 +40,21 @@ describe('TransformSavedObjectDocumentError', () => { ` ); }); + it('handles undefined namespace', () => { + const originalError = new Error('Dang diggity!'); + const err = new TransformSavedObjectDocumentError( + 'id', + 'type', + undefined, + 'failedTransform', + 'failedDoc', + originalError + ); + expect(err.message).toMatchInlineSnapshot( + ` + "Failed to transform document id. Transform: failedTransform + Doc: failedDoc" + ` + ); + }); }); diff --git a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts index 31cdd8c152969..4831f14889833 100644 --- a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts +++ b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts @@ -22,7 +22,7 @@ export class TransformSavedObjectDocumentError extends Error { constructor( public readonly id: string, public readonly type: string, - public readonly namespace: string, + public readonly namespace: string | undefined, public readonly failedTransform: string, // created by document_migrator wrapWithTry as `${type.name}:${version}`; public readonly failedDoc: string, public readonly originalError: Error // public readonly namespace?: string--> part of the stringified failedDoc diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index a66c47581939c..bbe261d8d75bd 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -610,9 +610,10 @@ export const model = (currentState: State, resW: ResponseType): // we have both the saved object Id and the stack trace in each `transformErrors` item. const transformErrorsReason = stateP.transformErrors.length > 0 - ? `the following saved object documents could not be transformed: ${JSON.stringify( - stateP.transformErrors - )}` + ? 'the following saved object documents could not be transformed:/n' + + stateP.transformErrors + .map((errObj) => `${errObj.rawId}: ${errObj.err.message}`) + .join('/n') : ''; return { ...stateP, From e804e74f4e374be3db66336fee664b36b582c47f Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Mon, 26 Apr 2021 11:04:05 -0700 Subject: [PATCH 09/27] Works collecting document transform failures and issues into current workflow --- .../migrationsv2/actions/index.ts | 38 +++--- .../saved_objects/migrationsv2/model.ts | 117 ++++++++++++++---- .../server/saved_objects/migrationsv2/next.ts | 32 ++++- .../saved_objects/migrationsv2/types.ts | 21 +++- 4 files changed, 162 insertions(+), 46 deletions(-) diff --git a/src/core/server/saved_objects/migrationsv2/actions/index.ts b/src/core/server/saved_objects/migrationsv2/actions/index.ts index 10018f44a7ec2..e7ebfc16f43a8 100644 --- a/src/core/server/saved_objects/migrationsv2/actions/index.ts +++ b/src/core/server/saved_objects/migrationsv2/actions/index.ts @@ -22,7 +22,10 @@ import { catchRetryableEsClientErrors, RetryableEsClientError, } from './catch_retryable_es_client_errors'; -import { DocumentsTransformFailed } from '../../migrations/core/migrate_raw_docs'; +import { + DocumentsTransformFailed, + DocumentsTransformSuccess, +} from '../../migrations/core/migrate_raw_docs'; export type { RetryableEsClientError }; /** @@ -529,24 +532,23 @@ export const closePit = ( * Transform outdated docs and write them to the index. * */ export const transformDocs = ( - client: ElasticsearchClient, + // move the commented out params to bulkOverwriteTransformedDocuments + // client: ElasticsearchClient, transformRawDocs: TransformRawDocs, - outdatedDocuments: SavedObjectsRawDoc[], - index: string, - refresh: estypes.Refresh -): TaskEither.TaskEither< - RetryableEsClientError | IndexNotFound | TargetIndexHadWriteBlock, - 'bulk_index_succeeded' -> => - pipe( - TaskEither.tryCatch( - () => transformRawDocs(outdatedDocuments), - (e) => { - throw e; - } - ), - TaskEither.chain((docs) => bulkOverwriteTransformedDocuments(client, index, docs, refresh)) - ); + outdatedDocuments: SavedObjectsRawDoc[] + // index: string, + // refresh: estypes.Refresh +): TaskEither.TaskEither => + transformRawDocs(outdatedDocuments); +// pipe( +// TaskEither.tryCatch( +// () => transformRawDocs(outdatedDocuments), +// (e) => { +// throw e; +// } +// ), +// TaskEither.chain((docs) => bulkOverwriteTransformedDocuments(client, index, docs, refresh)) +// ); /** @internal */ export interface ReindexResponse { diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index 33a997548ca6c..343db757a80bc 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -483,11 +483,15 @@ export const model = (currentState: State, resW: ResponseType): controlState: 'REINDEX_SOURCE_TO_TEMP_READ', sourceIndexPitId: res.right.pitId, lastHitSortValue: undefined, + // placeholders to collect document transform problems + corruptDocumentIds: [], + transformErrors: [], }; } else { throwBadResponse(stateP, res); } } else if (stateP.controlState === 'REINDEX_SOURCE_TO_TEMP_READ') { + // we carry through any failures we've seen with transforming documents on state const res = resW as ExcludeRetryableEsError>; if (Either.isRight(res)) { if (res.right.outdatedDocuments.length > 0) { @@ -497,11 +501,37 @@ export const model = (currentState: State, resW: ResponseType): outdatedDocuments: res.right.outdatedDocuments, lastHitSortValue: res.right.lastHitSortValue, }; + } else { + // we don't have any more outdated documents but had issues with transforming docs, we fail the migration + if (stateP.corruptDocumentIds.length > 0 || stateP.transformErrors.length > 0) { + // if documents couldn't be transformed or there were transformation errors we fail the migration + const corruptDocumentIdReason = + stateP.corruptDocumentIds.length > 0 + ? `The following corrupt saved object documents: ${stateP.corruptDocumentIds.join( + ',' + )}` + : ''; + const transformErrorsReason = + stateP.transformErrors.length > 0 + ? 'The following saved object documents could not be transformed:/n' + + stateP.transformErrors + .map((errObj) => `${errObj.rawId}: ${errObj.err.message}`) + .join('/n') + : ''; + return { + ...stateP, + controlState: 'FATAL', + reason: `Migrations failed. Reason: ${corruptDocumentIdReason} ${transformErrorsReason}. TO allow migrations to proceed, please delete these documents.`, + }; + } else { + // we don't have any more outdated documents and we haven't encountered any document transformation issues. + // Close the PIT search and carry on with the happy path. + return { + ...stateP, + controlState: 'REINDEX_SOURCE_TO_TEMP_CLOSE_PIT', + }; + } } - return { - ...stateP, - controlState: 'REINDEX_SOURCE_TO_TEMP_CLOSE_PIT', - }; } else { throwBadResponse(stateP, res); } @@ -518,34 +548,75 @@ export const model = (currentState: State, resW: ResponseType): throwBadResponse(stateP, res); } } else if (stateP.controlState === 'REINDEX_SOURCE_TO_TEMP_INDEX') { + // TINA We used to transform and index documents in one action. + // This is not split into two steps: One for transforms, the next for the bulk index + // We follow a similar control flow as for + // outdated document search -> outdated document transform -> transform documents bulk index + // collecting issues along the way rather than failing + // REINDEX_SOURCE_TO_TEMP_INDEX handles the document transforms const res = resW as ExcludeRetryableEsError>; if (Either.isRight(res)) { - return { - ...stateP, - controlState: 'REINDEX_SOURCE_TO_TEMP_READ', - }; + if (stateP.corruptDocumentIds.length === 0 && stateP.transformErrors.length === 0) { + return { + ...stateP, + controlState: 'REINDEX_SOURCE_TO_TEMP_INDEX_BULK', // handles the actual bulk indexing into temp index + transformedDocs: [...res.right.processedDocs], + }; + } else { + // we don't have any transform issues with the current batch of outdated docs BUT + // we have carried through previous transformation issues. + // The migration will ultimately fail BUT + // search throught remaining docs for more issues and pass the previous failures along on state + return { + ...stateP, + controlState: 'REINDEX_SOURCE_TO_TEMP_READ', + }; + } } else { + // we have failures from the current batch of documents and add them to the lists const left = res.left; - if ( - isLeftTypeof(left, 'target_index_had_write_block') || - (isLeftTypeof(left, 'index_not_found_exception') && left.index === stateP.tempIndex) - ) { - // index_not_found_exception: - // another instance completed the MARK_VERSION_INDEX_READY and - // removed the temp index. - // target_index_had_write_block - // another instance completed the SET_TEMP_WRITE_BLOCK step adding a - // write block to the temp index. - // - // For simplicity we continue linearly through the next steps even if - // we know another instance already completed these. + if (isLeftTypeof(left, 'documents_transform_failed')) { return { ...stateP, controlState: 'REINDEX_SOURCE_TO_TEMP_READ', + corruptDocumentIds: [...stateP.corruptDocumentIds, ...left.corruptDocumentIds], + transformErrors: [...stateP.transformErrors, ...left.transformErrors], }; + } else { + // should never happen + throwBadResponse(stateP, res as never); } - // should never happen - throwBadResponse(stateP, res as never); + // if ( + // isLeftTypeof(left, 'target_index_had_write_block') || + // (isLeftTypeof(left, 'index_not_found_exception') && left.index === stateP.tempIndex) + // ) { + // index_not_found_exception: + // another instance completed the MARK_VERSION_INDEX_READY and + // removed the temp index. + // target_index_had_write_block + // another instance completed the SET_TEMP_WRITE_BLOCK step adding a + // write block to the temp index. + // + // For simplicity we continue linearly through the next steps even if + // we know another instance already completed these. + // return { + // ...stateP, + // controlState: 'REINDEX_SOURCE_TO_TEMP_READ', + // }; + // } + } + } else if (stateP.controlState === 'REINDEX_SOURCE_TO_TEMP_INDEX_BULK') { + const res = resW as ExcludeRetryableEsError>; + if (Either.isRight(res)) { + return { + ...stateP, + controlState: 'REINDEX_SOURCE_TO_TEMP_READ', + // we're still on the happy path with no transformation failures seen. + corruptDocumentIds: [], + transformErrors: [], + }; + } else { + throwBadResponse(stateP, res); } } else if (stateP.controlState === 'SET_TEMP_WRITE_BLOCK') { const res = resW as ExcludeRetryableEsError>; diff --git a/src/core/server/saved_objects/migrationsv2/next.ts b/src/core/server/saved_objects/migrationsv2/next.ts index 6d61634a6948e..b6e3f5bab4691 100644 --- a/src/core/server/saved_objects/migrationsv2/next.ts +++ b/src/core/server/saved_objects/migrationsv2/next.ts @@ -33,6 +33,8 @@ import type { SetTempWriteBlock, WaitForYellowSourceState, TransformRawDocs, + TransformedDocumentsBulkIndex, + ReindexSourceToTempIndexBulk, } from './types'; import * as Actions from './actions'; import { ElasticsearchClient } from '../../elasticsearch'; @@ -75,10 +77,17 @@ export const nextActionMap = (client: ElasticsearchClient, transformRawDocs: Tra Actions.closePit(client, state.sourceIndexPitId), REINDEX_SOURCE_TO_TEMP_INDEX: (state: ReindexSourceToTempIndex) => Actions.transformDocs( - client, + // client, transformRawDocs, - state.outdatedDocuments, + state.outdatedDocuments + // state.tempIndex, + // false + ), + REINDEX_SOURCE_TO_TEMP_INDEX_BULK: (state: ReindexSourceToTempIndexBulk) => + Actions.bulkOverwriteTransformedDocuments( + client, state.tempIndex, + state.transformedDocs, /** * Since we don't run a search against the target index, we disable "refresh" to speed up * the migration process. @@ -113,10 +122,25 @@ export const nextActionMap = (client: ElasticsearchClient, transformRawDocs: Tra // The alternative is to use a search_after with either a tie_breaker // field or using a Point In Time as a cursor to go through all documents. Actions.transformDocs( - client, + // client, transformRawDocs, - state.outdatedDocuments, + state.outdatedDocuments + // state.targetIndex, + // 'wait_for' + ), + TRANSFORMED_DOCUMENTS_BULK_INDEX: (state: TransformedDocumentsBulkIndex) => + // Wait for a refresh to happen before returning. This ensures that when + // this Kibana instance searches for outdated documents, it won't find + // documents that were already transformed by itself or another Kibana + // instance. However, this causes each OUTDATED_DOCUMENTS_SEARCH -> + // OUTDATED_DOCUMENTS_TRANSFORM cycle to take 1s so when batches are + // small performance will become a lot worse. + // The alternative is to use a search_after with either a tie_breaker + // field or using a Point In Time as a cursor to go through all documents. + Actions.bulkOverwriteTransformedDocuments( + client, state.targetIndex, + state.transformedDocs, 'wait_for' ), MARK_VERSION_INDEX_READY: (state: MarkVersionIndexReady) => diff --git a/src/core/server/saved_objects/migrationsv2/types.ts b/src/core/server/saved_objects/migrationsv2/types.ts index 5efee300f9036..6217bf8f52b99 100644 --- a/src/core/server/saved_objects/migrationsv2/types.ts +++ b/src/core/server/saved_objects/migrationsv2/types.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import * as TaskEither from 'fp-ts/lib/TaskEither'; import * as Option from 'fp-ts/lib/Option'; import { estypes } from '@elastic/elasticsearch'; import { ControlState } from './state_action_machine'; @@ -13,6 +14,10 @@ import { AliasAction } from './actions'; import { IndexMapping } from '../mappings'; import { SavedObjectsRawDoc } from '..'; import { TransformErrorObjects } from '../migrations/core'; +import { + DocumentsTransformFailed, + DocumentsTransformSuccess, +} from '../migrations/core/migrate_raw_docs'; export interface BaseState extends ControlState { /** The first part of the index name such as `.kibana` or `.kibana_task_manager` */ @@ -169,6 +174,8 @@ export interface ReindexSourceToTempRead extends PostInitState { readonly controlState: 'REINDEX_SOURCE_TO_TEMP_READ'; readonly sourceIndexPitId: string; readonly lastHitSortValue: number[] | undefined; + readonly corruptDocumentIds: string[]; + readonly transformErrors: TransformErrorObjects[]; } export interface ReindexSourceToTempClosePit extends PostInitState { @@ -181,6 +188,15 @@ export interface ReindexSourceToTempIndex extends PostInitState { readonly outdatedDocuments: SavedObjectsRawDoc[]; readonly sourceIndexPitId: string; readonly lastHitSortValue: number[] | undefined; + readonly corruptDocumentIds: string[]; + readonly transformErrors: TransformErrorObjects[]; +} + +export interface ReindexSourceToTempIndexBulk extends PostInitState { + readonly controlState: 'REINDEX_SOURCE_TO_TEMP_INDEX_BULK'; + readonly transformedDocs: SavedObjectsRawDoc[]; + readonly sourceIndexPitId: string; + readonly lastHitSortValue: number[] | undefined; } export type SetTempWriteBlock = PostInitState & { @@ -327,6 +343,7 @@ export type State = | ReindexSourceToTempRead | ReindexSourceToTempClosePit | ReindexSourceToTempIndex + | ReindexSourceToTempIndexBulk | SetTempWriteBlock | CloneTempToSource | UpdateTargetMappingsState @@ -349,4 +366,6 @@ export type AllControlStates = State['controlState']; */ export type AllActionStates = Exclude; -export type TransformRawDocs = (rawDocs: SavedObjectsRawDoc[]) => Promise; +export type TransformRawDocs = ( + rawDocs: SavedObjectsRawDoc[] +) => TaskEither.TaskEither; From beee25e015fc8cc5718606fd44bf2a700589870a Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Mon, 26 Apr 2021 12:35:16 -0700 Subject: [PATCH 10/27] Refactors model.test.ts --- ...nsform_saved_object_document_error.test.ts | 2 +- .../migrationsv2/actions/index.test.ts | 12 ----- .../saved_objects/migrationsv2/model.test.ts | 48 ++++++++++++------- 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.test.ts b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.test.ts index f80b4aaddcdb9..80c670edd39ba 100644 --- a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.test.ts +++ b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.test.ts @@ -23,7 +23,7 @@ describe('TransformSavedObjectDocumentError', () => { expect(err.namespace).toEqual('namespace'); expect(err.stack).not.toBeNull(); }); - it('is constructs an special error message', () => { + it('constructs an special error message', () => { const originalError = new Error('Dang diggity!'); const err = new TransformSavedObjectDocumentError( 'id', diff --git a/src/core/server/saved_objects/migrationsv2/actions/index.test.ts b/src/core/server/saved_objects/migrationsv2/actions/index.test.ts index b144905cf01ad..10a8848fe85db 100644 --- a/src/core/server/saved_objects/migrationsv2/actions/index.test.ts +++ b/src/core/server/saved_objects/migrationsv2/actions/index.test.ts @@ -114,18 +114,6 @@ describe('actions', () => { }); }); - describe('transformDocs', () => { - it('calls catchRetryableEsClientErrors when the promise rejects', async () => { - const task = Actions.transformDocs(client, () => Promise.resolve([]), [], 'my_index', false); - try { - await task(); - } catch (e) { - /** ignore */ - } - expect(catchRetryableEsClientErrors).toHaveBeenCalledWith(retryableError); - }); - }); - describe('reindex', () => { it('calls catchRetryableEsClientErrors when the promise rejects', async () => { const task = Actions.reindex( diff --git a/src/core/server/saved_objects/migrationsv2/model.test.ts b/src/core/server/saved_objects/migrationsv2/model.test.ts index 033c1cac098a0..33af9c1dbe307 100644 --- a/src/core/server/saved_objects/migrationsv2/model.test.ts +++ b/src/core/server/saved_objects/migrationsv2/model.test.ts @@ -777,6 +777,8 @@ describe('migrations v2 model', () => { targetIndex: '.kibana_7.11.0_001', tempIndexMappings: { properties: {} }, lastHitSortValue: undefined, + corruptDocumentIds: [], + transformErrors: [], }; it('REINDEX_SOURCE_TO_TEMP_READ -> REINDEX_SOURCE_TO_TEMP_INDEX if the index has outdated documents to reindex', () => { @@ -832,35 +834,49 @@ describe('migrations v2 model', () => { sourceIndexPitId: 'pit_id', targetIndex: '.kibana_7.11.0_001', lastHitSortValue: undefined, + corruptDocumentIds: [], + transformErrors: [], }; + const processedDocs = ([ + { + _id: 'a:b', + _source: { type: 'a', a: { name: 'HOI!' }, migrationVersion: {}, references: [] }, + }, + ] as unknown[]) as SavedObjectsRawDoc[]; - it('REINDEX_SOURCE_TO_TEMP_INDEX -> REINDEX_SOURCE_TO_TEMP_READ if action succeeded', () => { - const res: ResponseType<'REINDEX_SOURCE_TO_TEMP_INDEX'> = Either.right( - 'bulk_index_succeeded' - ); + it('REINDEX_SOURCE_TO_TEMP_INDEX -> REINDEX_SOURCE_TO_TEMP_INDEX_BULK if action succeeded', () => { + const res: ResponseType<'REINDEX_SOURCE_TO_TEMP_INDEX'> = Either.right({ + processedDocs, + }); const newState = model(state, res); - expect(newState.controlState).toEqual('REINDEX_SOURCE_TO_TEMP_READ'); - expect(newState.retryCount).toEqual(0); - expect(newState.retryDelay).toEqual(0); + expect(newState.controlState).toEqual('REINDEX_SOURCE_TO_TEMP_INDEX_BULK'); }); - it('REINDEX_SOURCE_TO_TEMP_INDEX -> REINDEX_SOURCE_TO_TEMP_READ when response is left target_index_had_write_block', () => { - const res: ResponseType<'REINDEX_SOURCE_TO_TEMP_INDEX'> = Either.left({ - type: 'target_index_had_write_block', + it('REINDEX_SOURCE_TO_TEMP_INDEX -> REINDEX_SOURCE_TO_TEMP_READ if action succeeded but we have carried through previous failures', () => { + const res: ResponseType<'REINDEX_SOURCE_TO_TEMP_INDEX'> = Either.right({ + processedDocs, }); - const newState = model(state, res) as ReindexSourceToTempRead; + const testState = { + ...state, + corruptDocumentIds: ['a:b'], + transformErrors: [], + }; + const newState = model(testState, res); expect(newState.controlState).toEqual('REINDEX_SOURCE_TO_TEMP_READ'); - expect(newState.retryCount).toEqual(0); - expect(newState.retryDelay).toEqual(0); + expect(newState.corruptDocumentIds.length).toEqual(1); + expect(newState.transformErrors.length).toEqual(0); }); - it('REINDEX_SOURCE_TO_TEMP_INDEX -> REINDEX_SOURCE_TO_TEMP_READ when response is left index_not_found_exception for temp index', () => { + it('REINDEX_SOURCE_TO_TEMP_INDEX -> REINDEX_SOURCE_TO_TEMP_READ when response is left documents_transform_failed', () => { const res: ResponseType<'REINDEX_SOURCE_TO_TEMP_INDEX'> = Either.left({ - type: 'index_not_found_exception', - index: state.tempIndex, + type: 'documents_transform_failed', + corruptDocumentIds: ['a:b'], + transformErrors: [], }); const newState = model(state, res) as ReindexSourceToTempRead; expect(newState.controlState).toEqual('REINDEX_SOURCE_TO_TEMP_READ'); + expect(newState.corruptDocumentIds.length).toEqual(1); + expect(newState.transformErrors.length).toEqual(0); expect(newState.retryCount).toEqual(0); expect(newState.retryDelay).toEqual(0); }); From 9d7f824c612a1686f43f6a13e5abf164666a058d Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Mon, 26 Apr 2021 17:05:11 -0700 Subject: [PATCH 11/27] Refactors unit and some integration tests with new control flow --- .../integration_tests/actions.test.ts | 46 +++++++--------- .../integration_tests/cleanup.test.ts | 2 +- .../saved_objects/migrationsv2/model.test.ts | 52 ++++++++++++++++++- .../saved_objects/migrationsv2/model.ts | 4 +- 4 files changed, 72 insertions(+), 32 deletions(-) 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 b31f20950ae77..9aefe800a77a2 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 @@ -41,6 +41,8 @@ import { import * as Either from 'fp-ts/lib/Either'; import * as Option from 'fp-ts/lib/Option'; import { ResponseError } from '@elastic/elasticsearch/lib/errors'; +import { DocumentsTransformFailed, DocumentsTransformSuccess } from '../../migrations/core'; +import { TaskEither } from 'fp-ts/lib/TaskEither'; const { startES } = kbnTestServer.createTestServers({ adjustTimeout: (t: number) => jest.setTimeout(t), @@ -934,42 +936,30 @@ describe('migration actions', () => { }); describe('transformDocs', () => { - it('applies "transformRawDocs" and writes result into an index', async () => { - const index = 'transform_docs_index'; + it('applies "transformRawDocs" and returns the transformed documents', async () => { const originalDocs = [ { _id: 'foo:1', _source: { type: 'dashboard', value: 1 } }, { _id: 'foo:2', _source: { type: 'dashboard', value: 2 } }, ]; - const createIndexTask = createIndex(client, index, { - dynamic: true, - properties: {}, - }); - await createIndexTask(); - - async function tranformRawDocs(docs: SavedObjectsRawDoc[]): Promise { - for (const doc of docs) { - doc._source.value += 1; - } - return docs; + function innerTransformRawDocs( + docs: SavedObjectsRawDoc[] + ): TaskEither { + return async () => { + const processedDocs: SavedObjectsRawDoc[] = []; + for (const doc of docs) { + doc._source.value += 1; + processedDocs.push(doc); + } + return Either.right({ processedDocs }); + }; } + const transformTask = transformDocs(innerTransformRawDocs, originalDocs); - const transformTask = transformDocs(client, tranformRawDocs, originalDocs, index, 'wait_for'); - - const result = (await transformTask()) as Either.Right<'bulk_index_succeeded'>; - - expect(result.right).toBe('bulk_index_succeeded'); - - const { body } = await client.search<{ value: number }>({ - index, - }); - const hits = body.hits.hits; - - const foo1 = hits.find((h) => h._id === 'foo:1'); - expect(foo1?._source?.value).toBe(2); + const resultsWithProcessDocs = ((await transformTask()) as Either.Right) + .right.processedDocs; - const foo2 = hits.find((h) => h._id === 'foo:2'); - expect(foo2?._source?.value).toBe(3); + expect(resultsWithProcessDocs.length).toEqual(2); }); }); diff --git a/src/core/server/saved_objects/migrationsv2/integration_tests/cleanup.test.ts b/src/core/server/saved_objects/migrationsv2/integration_tests/cleanup.test.ts index 48bb282da18f6..aa2f5cb330d97 100644 --- a/src/core/server/saved_objects/migrationsv2/integration_tests/cleanup.test.ts +++ b/src/core/server/saved_objects/migrationsv2/integration_tests/cleanup.test.ts @@ -100,7 +100,7 @@ describe('migration v2', () => { await root.setup(); await expect(root.start()).rejects.toThrow( - /Unable to migrate the corrupt saved object document with _id: 'index-pattern:test_index\*'/ + 'Unable to complete saved object migrations for the [.kibana] index: Migrations failed. Reason: The following corrupt saved object documents: index-pattern:test_index* . To allow migrations to proceed, please delete these documents.' ); const logFileContent = await asyncReadFile(logFilePath, 'utf-8'); diff --git a/src/core/server/saved_objects/migrationsv2/model.test.ts b/src/core/server/saved_objects/migrationsv2/model.test.ts index 33af9c1dbe307..0c01f6cbaf437 100644 --- a/src/core/server/saved_objects/migrationsv2/model.test.ts +++ b/src/core/server/saved_objects/migrationsv2/model.test.ts @@ -34,6 +34,7 @@ import type { SetTempWriteBlock, WaitForYellowSourceState, TransformedDocumentsBulkIndex, + ReindexSourceToTempIndexBulk, } from './types'; import { SavedObjectsRawDoc } from '..'; import { AliasAction, RetryableEsClientError } from './actions'; @@ -803,6 +804,23 @@ describe('migrations v2 model', () => { expect(newState.controlState).toBe('REINDEX_SOURCE_TO_TEMP_CLOSE_PIT'); expect(newState.sourceIndexPitId).toBe('pit_id'); }); + + it('REINDEX_SOURCE_TO_TEMP_READ -> FATAL if no outdated documents to reindex and transform failures seen with previous outdated documents', () => { + const testState: ReindexSourceToTempRead = { + ...state, + corruptDocumentIds: ['a:b'], + transformErrors: [], + }; + const res: ResponseType<'REINDEX_SOURCE_TO_TEMP_READ'> = Either.right({ + outdatedDocuments: [], + lastHitSortValue: undefined, + }); + const newState = model(testState, res) as FatalState; + expect(newState.controlState).toBe('FATAL'); + expect(newState.reason).toMatchInlineSnapshot( + `"Migrations failed. Reason: The following saved object documents are corrupt: a:b . To allow migrations to proceed, please delete these documents."` + ); + }); }); describe('REINDEX_SOURCE_TO_TEMP_CLOSE_PIT', () => { @@ -861,7 +879,7 @@ describe('migrations v2 model', () => { corruptDocumentIds: ['a:b'], transformErrors: [], }; - const newState = model(testState, res); + const newState = model(testState, res) as ReindexSourceToTempIndex; expect(newState.controlState).toEqual('REINDEX_SOURCE_TO_TEMP_READ'); expect(newState.corruptDocumentIds.length).toEqual(1); expect(newState.transformErrors.length).toEqual(0); @@ -881,6 +899,38 @@ describe('migrations v2 model', () => { expect(newState.retryDelay).toEqual(0); }); }); + describe('REINDEX_SOURCE_TO_TEMP_INDEX_BULK', () => { + const transformedDocs = ([Symbol('raw saved object doc')] as unknown) as SavedObjectsRawDoc[]; + const reindexSourceToTempIndexBulkState: ReindexSourceToTempIndexBulk = { + ...baseState, + controlState: 'REINDEX_SOURCE_TO_TEMP_INDEX_BULK', + transformedDocs, + versionIndexReadyActions: Option.none, + sourceIndex: Option.some('.kibana') as Option.Some, + sourceIndexPitId: 'pit_id', + targetIndex: '.kibana_7.11.0_001', + lastHitSortValue: undefined, + }; + test('REINDEX_SOURCE_TO_TEMP_INDEX_BULK -> REINDEX_SOURCE_TO_TEMP_READ if action succeeded', () => { + const res: ResponseType<'REINDEX_SOURCE_TO_TEMP_INDEX_BULK'> = Either.right( + 'bulk_index_succeeded' + ); + const newState = model(reindexSourceToTempIndexBulkState, res); + expect(newState.controlState).toEqual('REINDEX_SOURCE_TO_TEMP_READ'); + expect(newState.retryCount).toEqual(0); + expect(newState.retryDelay).toEqual(0); + }); + test('REINDEX_SOURCE_TO_TEMP_INDEX_BULK should throw a throwBadResponse error if action failed', () => { + const res: ResponseType<'REINDEX_SOURCE_TO_TEMP_INDEX_BULK'> = Either.left({ + type: 'retryable_es_client_error', + message: 'random transform documents bulk error', + }); + const newState = model(reindexSourceToTempIndexBulkState, res); + expect(newState.controlState).toEqual('REINDEX_SOURCE_TO_TEMP_INDEX_BULK'); + expect(newState.retryCount).toEqual(1); + expect(newState.retryDelay).toEqual(2000); + }); + }); describe('SET_TEMP_WRITE_BLOCK', () => { const state: SetTempWriteBlock = { diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index 343db757a80bc..fe0f56a83e06b 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -507,7 +507,7 @@ export const model = (currentState: State, resW: ResponseType): // if documents couldn't be transformed or there were transformation errors we fail the migration const corruptDocumentIdReason = stateP.corruptDocumentIds.length > 0 - ? `The following corrupt saved object documents: ${stateP.corruptDocumentIds.join( + ? `The following saved object documents are corrupt: ${stateP.corruptDocumentIds.join( ',' )}` : ''; @@ -521,7 +521,7 @@ export const model = (currentState: State, resW: ResponseType): return { ...stateP, controlState: 'FATAL', - reason: `Migrations failed. Reason: ${corruptDocumentIdReason} ${transformErrorsReason}. TO allow migrations to proceed, please delete these documents.`, + reason: `Migrations failed. Reason: ${corruptDocumentIdReason} ${transformErrorsReason}. To allow migrations to proceed, please delete these documents.`, }; } else { // we don't have any more outdated documents and we haven't encountered any document transformation issues. From 5131c41bdfe3947d3d4b8bcc66dc51bc4ea3dd96 Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Tue, 27 Apr 2021 10:02:42 -0700 Subject: [PATCH 12/27] Code comment, update to run ci as an initial test --- .../saved_objects/migrationsv2/model.ts | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index fe0f56a83e06b..47958275d4f58 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -586,24 +586,6 @@ export const model = (currentState: State, resW: ResponseType): // should never happen throwBadResponse(stateP, res as never); } - // if ( - // isLeftTypeof(left, 'target_index_had_write_block') || - // (isLeftTypeof(left, 'index_not_found_exception') && left.index === stateP.tempIndex) - // ) { - // index_not_found_exception: - // another instance completed the MARK_VERSION_INDEX_READY and - // removed the temp index. - // target_index_had_write_block - // another instance completed the SET_TEMP_WRITE_BLOCK step adding a - // write block to the temp index. - // - // For simplicity we continue linearly through the next steps even if - // we know another instance already completed these. - // return { - // ...stateP, - // controlState: 'REINDEX_SOURCE_TO_TEMP_READ', - // }; - // } } } else if (stateP.controlState === 'REINDEX_SOURCE_TO_TEMP_INDEX_BULK') { const res = resW as ExcludeRetryableEsError>; @@ -616,6 +598,28 @@ export const model = (currentState: State, resW: ResponseType): transformErrors: [], }; } else { + /** TINA: when the indexing was done in the same control flow state as document transformations, + we used to have these left conditions that were treated as right conditions. + If this is still required, work the logic in somehow. + if ( + isLeftTypeof(left, 'target_index_had_write_block') || + (isLeftTypeof(left, 'index_not_found_exception') && left.index === stateP.tempIndex) + ) { + index_not_found_exception: + another instance completed the MARK_VERSION_INDEX_READY and + removed the temp index. + target_index_had_write_block + another instance completed the SET_TEMP_WRITE_BLOCK step adding a + write block to the temp index. + + For simplicity we continue linearly through the next steps even if + we know another instance already completed these. + return { + ...stateP, + controlState: 'REINDEX_SOURCE_TO_TEMP_READ', + }; + } + */ throwBadResponse(stateP, res); } } else if (stateP.controlState === 'SET_TEMP_WRITE_BLOCK') { From b3ae792fca19f67f7adc2e3107bf8369cb8ff720 Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Thu, 29 Apr 2021 18:00:04 -0700 Subject: [PATCH 13/27] Updates error message phrase --- .../migrationsv2/integration_tests/cleanup.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/server/saved_objects/migrationsv2/integration_tests/cleanup.test.ts b/src/core/server/saved_objects/migrationsv2/integration_tests/cleanup.test.ts index aa2f5cb330d97..79e7d77436ede 100644 --- a/src/core/server/saved_objects/migrationsv2/integration_tests/cleanup.test.ts +++ b/src/core/server/saved_objects/migrationsv2/integration_tests/cleanup.test.ts @@ -100,7 +100,7 @@ describe('migration v2', () => { await root.setup(); await expect(root.start()).rejects.toThrow( - 'Unable to complete saved object migrations for the [.kibana] index: Migrations failed. Reason: The following corrupt saved object documents: index-pattern:test_index* . To allow migrations to proceed, please delete these documents.' + 'Unable to complete saved object migrations for the [.kibana] index: Migrations failed. Reason: The following saved object documents are corrupt: index-pattern:test_index* . To allow migrations to proceed, please delete these documents.' ); const logFileContent = await asyncReadFile(logFilePath, 'utf-8'); From c909b3a2c81c21c680b2c835b47f5ba72590a781 Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Tue, 4 May 2021 15:03:18 -0700 Subject: [PATCH 14/27] Adds check on left response condition for READINDEX_SOURCE_TO_TEMP_INDEX --- .../saved_objects/migrationsv2/model.ts | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index dc6e0dfa8ca70..3ed45b6945e16 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -596,28 +596,27 @@ export const model = (currentState: State, resW: ResponseType): transformErrors: [], }; } else { - /** TINA: when the indexing was done in the same control flow state as document transformations, - we used to have these left conditions that were treated as right conditions. - If this is still required, work the logic in somehow. + const left = Either.left; if ( isLeftTypeof(left, 'target_index_had_write_block') || (isLeftTypeof(left, 'index_not_found_exception') && left.index === stateP.tempIndex) ) { - index_not_found_exception: - another instance completed the MARK_VERSION_INDEX_READY and - removed the temp index. - target_index_had_write_block - another instance completed the SET_TEMP_WRITE_BLOCK step adding a - write block to the temp index. + // index_not_found_exception: + // another instance completed the MARK_VERSION_INDEX_READY and + // removed the temp index. + // target_index_had_write_block + // another instance completed the SET_TEMP_WRITE_BLOCK step adding a + // write block to the temp index. - For simplicity we continue linearly through the next steps even if - we know another instance already completed these. - return { - ...stateP, - controlState: 'REINDEX_SOURCE_TO_TEMP_READ', - }; + // For simplicity we continue linearly through the next steps even if + // we know another instance already completed these. + return { + ...stateP, + controlState: 'REINDEX_SOURCE_TO_TEMP_READ', + corruptDocumentIds: [], + transformErrors: [], + }; } - */ throwBadResponse(stateP, res); } } else if (stateP.controlState === 'SET_TEMP_WRITE_BLOCK') { From d11fd0a88d2c26b234d745427e56b6e628d346a0 Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Tue, 4 May 2021 15:08:43 -0700 Subject: [PATCH 15/27] Updates model unit tests --- src/core/server/saved_objects/migrationsv2/model.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/server/saved_objects/migrationsv2/model.test.ts b/src/core/server/saved_objects/migrationsv2/model.test.ts index 6bb43875edd60..0aa5cc9a6d4ba 100644 --- a/src/core/server/saved_objects/migrationsv2/model.test.ts +++ b/src/core/server/saved_objects/migrationsv2/model.test.ts @@ -1123,7 +1123,7 @@ describe('migrations v2 model', () => { outdatedDocumentsTransformStateWithFailedDocuments, res ) as OutdatedDocumentsSearchRead; - expect(newState.controlState).toEqual('OUTDATED_DOCUMENTS_SEARCH'); + expect(newState.controlState).toEqual('OUTDATED_DOCUMENTS_SEARCH_READ'); expect(newState.corruptDocumentIds).toEqual(corruptDocumentIds); expect(newState.retryCount).toEqual(0); expect(newState.retryDelay).toEqual(0); @@ -1139,7 +1139,7 @@ describe('migrations v2 model', () => { outdatedDocumentsTransformStateWithFailedDocuments, res ) as OutdatedDocumentsSearchRead; - expect(newState.controlState).toEqual('OUTDATED_DOCUMENTS_SEARCH'); + expect(newState.controlState).toEqual('OUTDATED_DOCUMENTS_SEARCH_READ'); expect(newState.corruptDocumentIds.length).toEqual(0); expect(newState.transformErrors.length).toEqual(1); expect(newState.retryCount).toEqual(0); @@ -1158,7 +1158,7 @@ describe('migrations v2 model', () => { outdatedDocumentsTransformState, res ) as OutdatedDocumentsSearchRead; - expect(newState.controlState).toEqual('OUTDATED_DOCUMENTS_SEARCH'); + expect(newState.controlState).toEqual('OUTDATED_DOCUMENTS_SEARCH_READ'); expect(newState.corruptDocumentIds).toEqual(corruptDocumentIds); }); test('OUTDATED_DOCUMENTS_TRANSFORM -> OUTDATED_DOCUMENTS_SEARCH_READ combines newly failed documents with those already on state if documents failed the transform', () => { @@ -1186,7 +1186,7 @@ describe('migrations v2 model', () => { outdatedDocumentsTransformStateWithFailedDocuments, res ) as OutdatedDocumentsSearchRead; - expect(newState.controlState).toEqual('OUTDATED_DOCUMENTS_SEARCH'); + expect(newState.controlState).toEqual('OUTDATED_DOCUMENTS_SEARCH_READ'); expect(newState.corruptDocumentIds).toEqual([ ...corruptDocumentIds, ...newFailedTransformDocumentIds, From c3081e39671e906f07680ff05ea57a986d6f0727 Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Tue, 4 May 2021 16:16:51 -0700 Subject: [PATCH 16/27] Cleanup --- .../migrations/core/migrate_raw_docs.ts | 6 +++--- .../core/transform_saved_object_document_error.ts | 2 +- .../saved_objects/migrationsv2/actions/index.ts | 15 +-------------- .../server/saved_objects/migrationsv2/model.ts | 8 ++++---- .../server/saved_objects/migrationsv2/next.ts | 8 +------- 5 files changed, 10 insertions(+), 29 deletions(-) diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts index 179e74378ae6c..1d92730940fad 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts @@ -30,7 +30,7 @@ export interface DocumentsTransformSuccess { } export interface TransformErrorObjects { rawId: string; - err: TransformSavedObjectDocumentError | Error; // do we want the full error here or just the stack trace? + err: TransformSavedObjectDocumentError | Error; } type MigrateMethod = ( doc: SavedObjectUnsanitizedDoc @@ -112,8 +112,8 @@ export function migrateRawDocsNonThrowing( ); } catch (err) { if (err instanceof TransformSavedObjectDocumentError) { - // the doc id we get from the error is only the uuid part of the saved object - // we want to transform the id to a raw saved object id. + // the doc id we get from the error is only the uuid part + // we transform the id to a raw saved object id. transformErrors.push({ rawId: serializer.generateRawId(err.namespace, err.type, err.id), err, diff --git a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts index 4831f14889833..6e0c96b369fb0 100644 --- a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts +++ b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts @@ -25,7 +25,7 @@ export class TransformSavedObjectDocumentError extends Error { public readonly namespace: string | undefined, public readonly failedTransform: string, // created by document_migrator wrapWithTry as `${type.name}:${version}`; public readonly failedDoc: string, - public readonly originalError: Error // public readonly namespace?: string--> part of the stringified failedDoc + public readonly originalError: Error ) { super(`Failed to transform document ${id}. Transform: ${failedTransform}\nDoc: ${failedDoc}`); this.id = id; diff --git a/src/core/server/saved_objects/migrationsv2/actions/index.ts b/src/core/server/saved_objects/migrationsv2/actions/index.ts index c1f717a6d15da..ad6a0f3ec22fa 100644 --- a/src/core/server/saved_objects/migrationsv2/actions/index.ts +++ b/src/core/server/saved_objects/migrationsv2/actions/index.ts @@ -525,26 +525,13 @@ export const closePit = ( }; /* - * Transform outdated docs and write them to the index. + * Transform outdated docs * */ export const transformDocs = ( - // move the commented out params to bulkOverwriteTransformedDocuments - // client: ElasticsearchClient, transformRawDocs: TransformRawDocs, outdatedDocuments: SavedObjectsRawDoc[] - // index: string, - // refresh: estypes.Refresh ): TaskEither.TaskEither => transformRawDocs(outdatedDocuments); -// pipe( -// TaskEither.tryCatch( -// () => transformRawDocs(outdatedDocuments), -// (e) => { -// throw e; -// } -// ), -// TaskEither.chain((docs) => bulkOverwriteTransformedDocuments(client, index, docs, refresh)) -// ); /** @internal */ export interface ReindexResponse { diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index 3ed45b6945e16..3db6ba76a93c9 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -546,7 +546,7 @@ export const model = (currentState: State, resW: ResponseType): throwBadResponse(stateP, res); } } else if (stateP.controlState === 'REINDEX_SOURCE_TO_TEMP_INDEX') { - // TINA We used to transform and index documents in one action. + // We used to transform and index documents in one action. // This is not split into two steps: One for transforms, the next for the bulk index // We follow a similar control flow as for // outdated document search -> outdated document transform -> transform documents bulk index @@ -561,10 +561,10 @@ export const model = (currentState: State, resW: ResponseType): transformedDocs: [...res.right.processedDocs], }; } else { - // we don't have any transform issues with the current batch of outdated docs BUT + // we don't have any transform issues with the current batch of outdated docs but // we have carried through previous transformation issues. - // The migration will ultimately fail BUT - // search throught remaining docs for more issues and pass the previous failures along on state + // The migration will ultimately fail but before we do that, continue to + // search through remaining docs for more issues and pass the previous failures along on state return { ...stateP, controlState: 'REINDEX_SOURCE_TO_TEMP_READ', diff --git a/src/core/server/saved_objects/migrationsv2/next.ts b/src/core/server/saved_objects/migrationsv2/next.ts index ec64857490f83..07ebf80271d48 100644 --- a/src/core/server/saved_objects/migrationsv2/next.ts +++ b/src/core/server/saved_objects/migrationsv2/next.ts @@ -84,13 +84,7 @@ export const nextActionMap = (client: ElasticsearchClient, transformRawDocs: Tra REINDEX_SOURCE_TO_TEMP_CLOSE_PIT: (state: ReindexSourceToTempClosePit) => Actions.closePit(client, state.sourceIndexPitId), REINDEX_SOURCE_TO_TEMP_INDEX: (state: ReindexSourceToTempIndex) => - Actions.transformDocs( - // client, - transformRawDocs, - state.outdatedDocuments - // state.tempIndex, - // false - ), + Actions.transformDocs(transformRawDocs, state.outdatedDocuments), REINDEX_SOURCE_TO_TEMP_INDEX_BULK: (state: ReindexSourceToTempIndexBulk) => Actions.bulkOverwriteTransformedDocuments( client, From 8360a1b25fb4e71c0089027059bbd2a55209c166 Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Tue, 4 May 2021 18:21:27 -0700 Subject: [PATCH 17/27] changes type to interface --- src/core/server/saved_objects/migrationsv2/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/server/saved_objects/migrationsv2/types.ts b/src/core/server/saved_objects/migrationsv2/types.ts index 24da6131fa43a..f5800a3cd9570 100644 --- a/src/core/server/saved_objects/migrationsv2/types.ts +++ b/src/core/server/saved_objects/migrationsv2/types.ts @@ -277,7 +277,7 @@ export interface OutdatedDocumentsTransform extends PostInitState { readonly corruptDocumentIds: string[]; readonly transformErrors: TransformErrorObjects[]; } -export type TransformedDocumentsBulkIndex = PostInitState & { +export interface TransformedDocumentsBulkIndex extends PostInitState { /** * Write the up-to-date transformed documents to the target index */ @@ -286,7 +286,7 @@ export type TransformedDocumentsBulkIndex = PostInitState & { readonly lastHitSortValue: number[] | undefined; readonly hasTransformedDocs: boolean; readonly pitId: string; -}; +} export interface MarkVersionIndexReady extends PostInitState { /** From 2a6675c79f08b76e9f9a61dfa5f44eb442094501 Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Wed, 5 May 2021 13:41:30 -0700 Subject: [PATCH 18/27] Addresses minor change requests --- .../migrations/core/migrate_raw_docs.test.ts | 12 ++-- .../migrations/core/migrate_raw_docs.ts | 12 ++-- .../transform_saved_object_document_error.ts | 7 --- .../migrations/kibana/kibana_migrator.ts | 4 +- .../saved_objects/migrationsv2/model.test.ts | 59 +++++++++++-------- .../saved_objects/migrationsv2/model.ts | 2 - 6 files changed, 46 insertions(+), 50 deletions(-) diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts index adf0ace563c83..3d7dadfd8027a 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts @@ -10,7 +10,7 @@ import { set } from '@elastic/safer-lodash-set'; import _ from 'lodash'; import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { SavedObjectsSerializer } from '../../serialization'; -import { migrateRawDocs, migrateRawDocsNonThrowing } from './migrate_raw_docs'; +import { migrateRawDocs, migrateRawDocsSafely } from './migrate_raw_docs'; import { TransformSavedObjectDocumentError } from './transform_saved_object_document_error'; describe('migrateRawDocs', () => { @@ -122,7 +122,7 @@ describe('migrateRawDocs', () => { }); }); -describe('migrateRawDocsNonThrowing', () => { +describe('migrateRawDocsSafely', () => { beforeEach(() => { jest.clearAllMocks(); }); @@ -132,7 +132,7 @@ describe('migrateRawDocsNonThrowing', () => { const transform = jest.fn((doc: any) => [ set(_.cloneDeep(doc), 'attributes.name', 'HOI!'), ]); - const task = migrateRawDocsNonThrowing( + const task = migrateRawDocsSafely( new SavedObjectsSerializer(new SavedObjectTypeRegistry()), transform, [ @@ -181,7 +181,7 @@ describe('migrateRawDocsNonThrowing', () => { const transform = jest.fn((doc: any) => [ set(_.cloneDeep(doc), 'attributes.name', 'TADA'), ]); - const task = migrateRawDocsNonThrowing( + const task = migrateRawDocsSafely( new SavedObjectsSerializer(new SavedObjectTypeRegistry()), transform, [ @@ -207,7 +207,7 @@ describe('migrateRawDocsNonThrowing', () => { set(_.cloneDeep(doc), 'attributes.name', 'HOI!'), { id: 'bar', type: 'foo', attributes: { name: 'baz' } }, ]); - const task = migrateRawDocsNonThrowing( + const task = migrateRawDocsSafely( new SavedObjectsSerializer(new SavedObjectTypeRegistry()), transform, [{ _id: 'a:b', _source: { type: 'a', a: { name: 'AAA' } } }] @@ -252,7 +252,7 @@ describe('migrateRawDocsNonThrowing', () => { new Error('error during transform') ); }); - const task = migrateRawDocsNonThrowing( + const task = migrateRawDocsSafely( new SavedObjectsSerializer(new SavedObjectTypeRegistry()), transform, [{ _id: 'a:b', _source: { type: 'a', a: { name: 'AAA' } } }] // this is the raw doc diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts index 1d92730940fad..2a950f4f0cb59 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts @@ -86,29 +86,25 @@ export async function migrateRawDocs( * and converts the saved object to a raw document. * Captures the ids and errors from any documents that are not valid saved objects or * for which the transformation function failed. - * @param {SavedObjectsSerializer} serializer - * @param {TransformFn} migrateDoc - * @param {SavedObjectsRawDoc[]} rawDocs - * @param {SavedObjectsMigrationLogger} log * @returns {TaskEither.TaskEither} */ -export function migrateRawDocsNonThrowing( +export function migrateRawDocsSafely( serializer: SavedObjectsSerializer, migrateDoc: MigrateAndConvertFn, rawDocs: SavedObjectsRawDoc[] ): TaskEither.TaskEither { return async () => { - const migrateDocWithoutBlocking = transformNonBlocking(migrateDoc); + const migrateDocNonBlocking = transformNonBlocking(migrateDoc); const processedDocs: SavedObjectsRawDoc[] = []; const transformErrors: TransformErrorObjects[] = []; const corruptSavedObjectIds: string[] = []; + const options = { namespaceTreatment: 'lax' as const }; for (const raw of rawDocs) { - const options = { namespaceTreatment: 'lax' as const }; if (serializer.isRawSavedObject(raw, options)) { const savedObject = convertToRawAddMigrationVersion(raw, options, serializer); try { processedDocs.push( - ...(await migrateMapToRawDoc(migrateDocWithoutBlocking, savedObject, serializer)) + ...(await migrateMapToRawDoc(migrateDocNonBlocking, savedObject, serializer)) ); } catch (err) { if (err instanceof TransformSavedObjectDocumentError) { diff --git a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts index 6e0c96b369fb0..6a6f87ea1eeb2 100644 --- a/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts +++ b/src/core/server/saved_objects/migrations/core/transform_saved_object_document_error.ts @@ -28,12 +28,5 @@ export class TransformSavedObjectDocumentError extends Error { public readonly originalError: Error ) { super(`Failed to transform document ${id}. Transform: ${failedTransform}\nDoc: ${failedDoc}`); - this.id = id; - this.namespace = namespace; - this.type = type; - // Removed because not including still seems to work, it may have been an old Typescript 2.1 issue: - // Set the prototype explicitly, see: - // https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work - // Object.setPrototypeOf(this, TransformSavedObjectDocumentError.prototype); } } diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts index 9d85b54a379d6..f74fe7e7a6e1c 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts @@ -35,7 +35,7 @@ import { SavedObjectsMigrationConfigType } from '../../saved_objects_config'; import { ISavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { SavedObjectsType } from '../../types'; import { runResilientMigrator } from '../../migrationsv2'; -import { migrateRawDocsNonThrowing } from '../core/migrate_raw_docs'; +import { migrateRawDocsSafely } from '../core/migrate_raw_docs'; export interface KibanaMigratorOptions { client: ElasticsearchClient; @@ -184,7 +184,7 @@ export class KibanaMigrator { logger: this.log, preMigrationScript: indexMap[index].script, transformRawDocs: (rawDocs: SavedObjectsRawDoc[]) => - migrateRawDocsNonThrowing( + migrateRawDocsSafely( this.serializer, this.documentMigrator.migrateAndConvert, rawDocs diff --git a/src/core/server/saved_objects/migrationsv2/model.test.ts b/src/core/server/saved_objects/migrationsv2/model.test.ts index 0aa5cc9a6d4ba..577ec6d32916b 100644 --- a/src/core/server/saved_objects/migrationsv2/model.test.ts +++ b/src/core/server/saved_objects/migrationsv2/model.test.ts @@ -44,7 +44,7 @@ import { AliasAction, RetryableEsClientError } from './actions'; import { createInitialState, model } from './model'; import { ResponseType } from './next'; import { SavedObjectsMigrationConfigType } from '../saved_objects_config'; -import { TransformErrorObjects } from '../migrations/core'; +import { TransformErrorObjects, TransformSavedObjectDocumentError } from '../migrations/core'; describe('migrations v2 model', () => { const baseState: BaseState = { @@ -858,12 +858,12 @@ describe('migrations v2 model', () => { corruptDocumentIds: [], transformErrors: [], }; - const processedDocs = ([ + const processedDocs = [ { _id: 'a:b', _source: { type: 'a', a: { name: 'HOI!' }, migrationVersion: {}, references: [] }, }, - ] as unknown[]) as SavedObjectsRawDoc[]; + ] as SavedObjectsRawDoc[]; it('REINDEX_SOURCE_TO_TEMP_INDEX -> REINDEX_SOURCE_TO_TEMP_INDEX_BULK if action succeeded', () => { const res: ResponseType<'REINDEX_SOURCE_TO_TEMP_INDEX'> = Either.right({ @@ -903,7 +903,12 @@ describe('migrations v2 model', () => { }); }); describe('REINDEX_SOURCE_TO_TEMP_INDEX_BULK', () => { - const transformedDocs = ([Symbol('raw saved object doc')] as unknown) as SavedObjectsRawDoc[]; + const transformedDocs = [ + { + _id: 'a:b', + _source: { type: 'a', a: { name: 'HOI!' }, migrationVersion: {}, references: [] }, + }, + ] as SavedObjectsRawDoc[]; const reindexSourceToTempIndexBulkState: ReindexSourceToTempIndexBulk = { ...baseState, controlState: 'REINDEX_SOURCE_TO_TEMP_INDEX_BULK', @@ -1076,9 +1081,20 @@ describe('migrations v2 model', () => { }); describe('OUTDATED_DOCUMENTS_TRANSFORM', () => { - const outdatedDocuments = ([ - Symbol('raw saved object doc'), - ] as unknown) as SavedObjectsRawDoc[]; + const outdatedDocuments = [{ _id: '1', _source: { type: 'vis' } }]; + const corruptDocumentIds = ['a:somethingelse']; + const originalTransformError = new Error('Dang diggity!'); + const transFormErr = new TransformSavedObjectDocumentError( + 'id', + 'type', + 'namespace', + 'failedTransform', + 'failedDoc', + originalTransformError + ); + const transformationErrors = [ + { rawId: 'bob:tail', err: transFormErr }, + ] as TransformErrorObjects[]; const outdatedDocumentsTransformState: OutdatedDocumentsTransform = { ...baseState, controlState: 'OUTDATED_DOCUMENTS_TRANSFORM', @@ -1093,14 +1109,12 @@ describe('migrations v2 model', () => { hasTransformedDocs: false, }; describe('OUTDATED_DOCUMENTS_TRANSFORM if action succeeds', () => { - const processedDocs = ([Symbol('raw saved object doc')] as unknown) as SavedObjectsRawDoc[]; - const corruptDocumentIds = ([Symbol('raw saved object doc ID')] as unknown) as string[]; - const transformationErrors = ([ + const processedDocs = [ { - rawId: Symbol('transform error object') as unknown, - err: Symbol('transform error itself') as unknown, + _id: 'a:b', + _source: { type: 'a', a: { name: 'HOI!' }, migrationVersion: {}, references: [] }, }, - ] as unknown) as TransformErrorObjects[]; + ] as SavedObjectsRawDoc[]; test('OUTDATED_DOCUMENTS_TRANSFORM -> TRANSFORMED_DOCUMENTS_BULK_INDEX if action succeeds', () => { const res: ResponseType<'OUTDATED_DOCUMENTS_TRANSFORM'> = Either.right({ processedDocs }); const newState = model( @@ -1148,7 +1162,6 @@ describe('migrations v2 model', () => { }); describe('OUTDATED_DOCUMENTS_TRANSFORM if action fails', () => { test('OUTDATED_DOCUMENTS_TRANSFORM -> OUTDATED_DOCUMENTS_SEARCH_READ adding newly failed documents to state if documents failed the transform', () => { - const corruptDocumentIds = ([Symbol('raw saved object doc ID')] as unknown) as string[]; const res: ResponseType<'OUTDATED_DOCUMENTS_TRANSFORM'> = Either.left({ type: 'documents_transform_failed', corruptDocumentIds, @@ -1162,16 +1175,7 @@ describe('migrations v2 model', () => { expect(newState.corruptDocumentIds).toEqual(corruptDocumentIds); }); test('OUTDATED_DOCUMENTS_TRANSFORM -> OUTDATED_DOCUMENTS_SEARCH_READ combines newly failed documents with those already on state if documents failed the transform', () => { - const corruptDocumentIds = ([Symbol('raw saved object doc ID')] as unknown) as string[]; - const transformationErrors = ([ - { - rawId: Symbol('transform error object') as unknown, - err: Symbol('transform error itself') as unknown, - }, - ] as unknown) as TransformErrorObjects[]; - const newFailedTransformDocumentIds = ([ - Symbol('raw saved object doc ID 2'), - ] as unknown) as string[]; + const newFailedTransformDocumentIds = ['b:other', 'c:__']; const outdatedDocumentsTransformStateWithFailedDocuments: OutdatedDocumentsTransform = { ...outdatedDocumentsTransformState, corruptDocumentIds: [...corruptDocumentIds], @@ -1195,7 +1199,12 @@ describe('migrations v2 model', () => { }); }); describe('TRANSFORMED_DOCUMENTS_BULK_INDEX', () => { - const transformedDocs = ([Symbol('raw saved object doc')] as unknown) as SavedObjectsRawDoc[]; + const transformedDocs = [ + { + _id: 'a:b', + _source: { type: 'a', a: { name: 'HOI!' }, migrationVersion: {}, references: [] }, + }, + ] as SavedObjectsRawDoc[]; const transformedDocumentsBulkIndexState: TransformedDocumentsBulkIndex = { ...baseState, controlState: 'TRANSFORMED_DOCUMENTS_BULK_INDEX', diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index 3db6ba76a93c9..87b3dcf332e08 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -546,8 +546,6 @@ export const model = (currentState: State, resW: ResponseType): throwBadResponse(stateP, res); } } else if (stateP.controlState === 'REINDEX_SOURCE_TO_TEMP_INDEX') { - // We used to transform and index documents in one action. - // This is not split into two steps: One for transforms, the next for the bulk index // We follow a similar control flow as for // outdated document search -> outdated document transform -> transform documents bulk index // collecting issues along the way rather than failing From 8d16852de7360e17b94f5de4b9dd8875cd18d3d8 Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Wed, 5 May 2021 16:15:32 -0700 Subject: [PATCH 19/27] Adds TransformationError stack trace to transformation errors migration failure reason --- .../saved_objects/migrationsv2/model.test.ts | 31 +++++++++++++++++++ .../saved_objects/migrationsv2/model.ts | 14 ++++----- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/core/server/saved_objects/migrationsv2/model.test.ts b/src/core/server/saved_objects/migrationsv2/model.test.ts index 577ec6d32916b..701d6184204e0 100644 --- a/src/core/server/saved_objects/migrationsv2/model.test.ts +++ b/src/core/server/saved_objects/migrationsv2/model.test.ts @@ -1042,6 +1042,37 @@ describe('migrations v2 model', () => { expect(newState.controlState).toBe('OUTDATED_DOCUMENTS_SEARCH_CLOSE_PIT'); expect(newState.pitId).toBe('pit_id'); }); + + it('OUTDATED_DOCUMENTS_SEARCH_READ -> FATAL if no outdated documents to transform and we have failed document migrations', () => { + const corruptDocumentIdsCarriedOver = ['a:somethingelse']; + const originalTransformError = new Error('something went wrong'); + const transFormErr = new TransformSavedObjectDocumentError( + '123', + 'vis', + undefined, + 'randomvis: 7.12.0', + 'failedDoc', + originalTransformError + ); + const transformationErrors = [ + { rawId: 'bob:tail', err: transFormErr }, + ] as TransformErrorObjects[]; + const res: ResponseType<'OUTDATED_DOCUMENTS_SEARCH_READ'> = Either.right({ + outdatedDocuments: [], + lastHitSortValue: undefined, + }); + const transformErrorsState: OutdatedDocumentsSearchRead = { + ...state, + corruptDocumentIds: [...corruptDocumentIdsCarriedOver], + transformErrors: [...transformationErrors], + }; + const newState = model(transformErrorsState, res) as FatalState; + expect(newState.controlState).toBe('FATAL'); + expect(newState.reason.includes('Migrations failed. Reason: ')).toBe(true); + expect(newState.reason.includes('Corrupt saved object documents: ')).toBe(true); + expect(newState.reason.includes('Transformation errors: ')).toBe(true); + expect(newState.reason.includes('randomvis: 7.12.0')).toBe(true); + }); }); describe('OUTDATED_DOCUMENTS_SEARCH_CLOSE_PIT', () => { diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index 87b3dcf332e08..d5ef83fd9946a 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -705,22 +705,22 @@ export const model = (currentState: State, resW: ResponseType): // If documents couldn't be transformed or there were transformation errors we fail the migration const corruptDocumentIdReason = stateP.corruptDocumentIds.length > 0 - ? `The following corrupt saved object documents: ${stateP.corruptDocumentIds.join( - ',' - )}` - : ''; + ? ` Corrupt saved object documents: ${stateP.corruptDocumentIds.join(',')}.\n` + : ' '; // we have both the saved object Id and the stack trace in each `transformErrors` item. const transformErrorsReason = stateP.transformErrors.length > 0 - ? 'the following saved object documents could not be transformed:/n' + + ? 'Transformation errors: ' + stateP.transformErrors - .map((errObj) => `${errObj.rawId}: ${errObj.err.message}`) + .map( + (errObj) => `${errObj.rawId}: ${errObj.err.message}\n ${errObj.err.stack ?? ''}` + ) .join('/n') : ''; return { ...stateP, controlState: 'FATAL', - reason: `Migrations failed. Reason: ${corruptDocumentIdReason} ${transformErrorsReason}. To allow migrations to proceed, please delete these documents.`, + reason: `Migrations failed. Reason:${corruptDocumentIdReason}${transformErrorsReason}. To allow migrations to proceed, please delete these documents.`, }; } else { // If there are no more results we have transformed all outdated From 17655133149612f29bdc54205a603615b3780bea Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Thu, 6 May 2021 09:45:16 -0700 Subject: [PATCH 20/27] Ensures model treats response from Actions.bulkOverwriteTransformedDocuments the same way --- .../saved_objects/migrationsv2/model.test.ts | 4 ++-- .../saved_objects/migrationsv2/model.ts | 21 ------------------- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/src/core/server/saved_objects/migrationsv2/model.test.ts b/src/core/server/saved_objects/migrationsv2/model.test.ts index 701d6184204e0..56bbe5f6b4001 100644 --- a/src/core/server/saved_objects/migrationsv2/model.test.ts +++ b/src/core/server/saved_objects/migrationsv2/model.test.ts @@ -931,7 +931,7 @@ describe('migrations v2 model', () => { test('REINDEX_SOURCE_TO_TEMP_INDEX_BULK should throw a throwBadResponse error if action failed', () => { const res: ResponseType<'REINDEX_SOURCE_TO_TEMP_INDEX_BULK'> = Either.left({ type: 'retryable_es_client_error', - message: 'random transform documents bulk error', + message: 'random documents bulk index error', }); const newState = model(reindexSourceToTempIndexBulkState, res); expect(newState.controlState).toEqual('REINDEX_SOURCE_TO_TEMP_INDEX_BULK'); @@ -1250,7 +1250,7 @@ describe('migrations v2 model', () => { test('TRANSFORMED_DOCUMENTS_BULK_INDEX should throw a throwBadResponse error if action failed', () => { const res: ResponseType<'TRANSFORMED_DOCUMENTS_BULK_INDEX'> = Either.left({ type: 'retryable_es_client_error', - message: 'random transform documents bulk error', + message: 'random documents bulk index error', }); const newState = model( transformedDocumentsBulkIndexState, diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index d5ef83fd9946a..be70f44930668 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -594,27 +594,6 @@ export const model = (currentState: State, resW: ResponseType): transformErrors: [], }; } else { - const left = Either.left; - if ( - isLeftTypeof(left, 'target_index_had_write_block') || - (isLeftTypeof(left, 'index_not_found_exception') && left.index === stateP.tempIndex) - ) { - // index_not_found_exception: - // another instance completed the MARK_VERSION_INDEX_READY and - // removed the temp index. - // target_index_had_write_block - // another instance completed the SET_TEMP_WRITE_BLOCK step adding a - // write block to the temp index. - - // For simplicity we continue linearly through the next steps even if - // we know another instance already completed these. - return { - ...stateP, - controlState: 'REINDEX_SOURCE_TO_TEMP_READ', - corruptDocumentIds: [], - transformErrors: [], - }; - } throwBadResponse(stateP, res); } } else if (stateP.controlState === 'SET_TEMP_WRITE_BLOCK') { From 9f8e432ad84396577bd23c709e155aee22778684 Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Thu, 6 May 2021 12:09:06 -0700 Subject: [PATCH 21/27] Adds the saved object id to the transform error object regardless of the error type --- .../migrations/core/migrate_raw_docs.test.ts | 33 ++++++++++++++++--- .../migrations/core/migrate_raw_docs.ts | 9 ++++- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts index 3d7dadfd8027a..c052f7e8f1d6b 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts @@ -240,7 +240,7 @@ describe('migrateRawDocsSafely', () => { expect(transform).toHaveBeenCalledWith(obj); }); - test('rejects when the transform function throws an error', async () => { + test('instance of Either.left containing transform errors when the transform function throws a TransformSavedObjectDocument error', async () => { let result: any; const transform = jest.fn((doc: any) => { throw new TransformSavedObjectDocumentError( @@ -266,11 +266,36 @@ describe('migrateRawDocsSafely', () => { expect(result._tag).toEqual('Left'); expect(result.left.corruptDocumentIds.length).toEqual(0); expect(result.left.transformErrors.length).toEqual(1); - expect(result.left.transformErrors[0].err.message).toMatchInlineSnapshot( - ` + expect(result.left.transformErrors[0].err.message).toMatchInlineSnapshot(` "Failed to transform document b. Transform: a1.2.3 Doc: {\\"type\\":\\"a\\",\\"id\\":\\"b\\",\\"attributes\\":{\\"name\\":\\"AAA\\"},\\"references\\":[],\\"migrationVersion\\":{}}" - ` + `); + }); + + test("instance of Either.left containing errors when the transform function throws an error that isn't a TransformSavedObjectDocument error", async () => { + let result: any; + const transform = jest.fn((doc: any) => { + throw new Error('error during transform'); + }); + const task = migrateRawDocsSafely( + new SavedObjectsSerializer(new SavedObjectTypeRegistry()), + transform, + [{ _id: 'a:b', _source: { type: 'a', a: { name: 'AAA' } } }] // this is the raw doc ); + try { + result = await task(); + } catch (err) { + /* ignore */ + } + expect(transform).toHaveBeenCalledTimes(1); + expect(result._tag).toEqual('Left'); + expect(result.left.corruptDocumentIds.length).toEqual(0); + expect(result.left.transformErrors.length).toEqual(1); + expect(result.left.transformErrors[0]).toMatchInlineSnapshot(` + Object { + "err": [Error: error during transform], + "rawId": "a:b", + } + `); }); }); diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts index 2a950f4f0cb59..d9b690e90e7f7 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts @@ -115,7 +115,14 @@ export function migrateRawDocsSafely( err, }); } else { - transformErrors.push({ rawId: 'unknown', err }); // cases we haven't accounted for yet + transformErrors.push({ + rawId: serializer.generateRawId( + savedObject.namespace, + savedObject.type, + savedObject.id + ), + err, + }); // cases we haven't accounted for yet } } } else { From 0f4c497eb3bf69a5dee5cd7ebb48cd64a25d7b85 Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Thu, 6 May 2021 14:31:57 -0700 Subject: [PATCH 22/27] Addresses remaining smaler PR change requests --- .../migrations/core/document_migrator.ts | 2 +- .../migrations/core/migrate_raw_docs.test.ts | 43 +++----- .../migrations/core/migrate_raw_docs.ts | 18 ++-- .../integration_tests/actions.test.ts | 4 +- .../saved_objects/migrationsv2/model.test.ts | 7 +- .../saved_objects/migrationsv2/model.ts | 100 ++++++++++++------ 6 files changed, 93 insertions(+), 81 deletions(-) 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 847b4a9c6bffb..4f58397866cfb 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.ts @@ -685,7 +685,7 @@ function wrapWithTry( throw new TransformSavedObjectDocumentError( doc.id, doc.type, - doc.namespace ?? undefined, + doc.namespace, failedTransform, failedDoc, error diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts index c052f7e8f1d6b..1d43e2f54a726 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts @@ -7,10 +7,16 @@ */ import { set } from '@elastic/safer-lodash-set'; +import * as Either from 'fp-ts/lib/Either'; import _ from 'lodash'; import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { SavedObjectsSerializer } from '../../serialization'; -import { migrateRawDocs, migrateRawDocsSafely } from './migrate_raw_docs'; +import { + DocumentsTransformFailed, + DocumentsTransformSuccess, + migrateRawDocs, + migrateRawDocsSafely, +} from './migrate_raw_docs'; import { TransformSavedObjectDocumentError } from './transform_saved_object_document_error'; describe('migrateRawDocs', () => { @@ -128,7 +134,6 @@ describe('migrateRawDocsSafely', () => { }); test('converts raw docs to saved objects', async () => { - let result: any; const transform = jest.fn((doc: any) => [ set(_.cloneDeep(doc), 'attributes.name', 'HOI!'), ]); @@ -140,11 +145,7 @@ describe('migrateRawDocsSafely', () => { { _id: 'c:d', _source: { type: 'c', c: { name: 'DDD' } } }, ] ); - try { - result = await task(); - } catch (e) { - /** ignore */ - } + const result = (await task()) as Either.Right; expect(result._tag).toEqual('Right'); expect(result.right.processedDocs).toEqual([ { @@ -177,7 +178,6 @@ describe('migrateRawDocsSafely', () => { }); test('returns a `left` tag when encountering a corrupt saved object document', async () => { - let result: any; const transform = jest.fn((doc: any) => [ set(_.cloneDeep(doc), 'attributes.name', 'TADA'), ]); @@ -189,11 +189,7 @@ describe('migrateRawDocsSafely', () => { { _id: 'c:d', _source: { type: 'c', c: { name: 'DDD' } } }, ] ); - try { - result = await task(); - } catch (e) { - result = e; - } + const result = (await task()) as Either.Left; expect(transform).toHaveBeenCalledTimes(1); expect(result._tag).toEqual('Left'); expect(Object.keys(result.left)).toEqual(['type', 'corruptDocumentIds', 'transformErrors']); @@ -202,7 +198,6 @@ describe('migrateRawDocsSafely', () => { }); test('handles when one document is transformed into multiple documents', async () => { - let result: any; const transform = jest.fn((doc: any) => [ set(_.cloneDeep(doc), 'attributes.name', 'HOI!'), { id: 'bar', type: 'foo', attributes: { name: 'baz' } }, @@ -212,11 +207,7 @@ describe('migrateRawDocsSafely', () => { transform, [{ _id: 'a:b', _source: { type: 'a', a: { name: 'AAA' } } }] ); - try { - result = await task(); - } catch (err) { - /** ignore */ - } + const result = (await task()) as Either.Right; expect(result._tag).toEqual('Right'); expect(result.right.processedDocs).toEqual([ { @@ -241,7 +232,6 @@ describe('migrateRawDocsSafely', () => { }); test('instance of Either.left containing transform errors when the transform function throws a TransformSavedObjectDocument error', async () => { - let result: any; const transform = jest.fn((doc: any) => { throw new TransformSavedObjectDocumentError( `${doc.id}`, @@ -257,11 +247,7 @@ describe('migrateRawDocsSafely', () => { transform, [{ _id: 'a:b', _source: { type: 'a', a: { name: 'AAA' } } }] // this is the raw doc ); - try { - result = await task(); - } catch (err) { - /* ignore */ - } + const result = (await task()) as Either.Left; expect(transform).toHaveBeenCalledTimes(1); expect(result._tag).toEqual('Left'); expect(result.left.corruptDocumentIds.length).toEqual(0); @@ -273,7 +259,6 @@ describe('migrateRawDocsSafely', () => { }); test("instance of Either.left containing errors when the transform function throws an error that isn't a TransformSavedObjectDocument error", async () => { - let result: any; const transform = jest.fn((doc: any) => { throw new Error('error during transform'); }); @@ -282,11 +267,7 @@ describe('migrateRawDocsSafely', () => { transform, [{ _id: 'a:b', _source: { type: 'a', a: { name: 'AAA' } } }] // this is the raw doc ); - try { - result = await task(); - } catch (err) { - /* ignore */ - } + const result = (await task()) as Either.Left; expect(transform).toHaveBeenCalledTimes(1); expect(result._tag).toEqual('Left'); expect(result.left.corruptDocumentIds.length).toEqual(0); diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts index d9b690e90e7f7..c7d56f3912256 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts @@ -32,7 +32,7 @@ export interface TransformErrorObjects { rawId: string; err: TransformSavedObjectDocumentError | Error; } -type MigrateMethod = ( +type MigrateFn = ( doc: SavedObjectUnsanitizedDoc ) => Promise>>; @@ -101,8 +101,9 @@ export function migrateRawDocsSafely( const options = { namespaceTreatment: 'lax' as const }; for (const raw of rawDocs) { if (serializer.isRawSavedObject(raw, options)) { - const savedObject = convertToRawAddMigrationVersion(raw, options, serializer); + // const savedObject = convertToRawAddMigrationVersion(raw, options, serializer); try { + const savedObject = convertToRawAddMigrationVersion(raw, options, serializer); processedDocs.push( ...(await migrateMapToRawDoc(migrateDocNonBlocking, savedObject, serializer)) ); @@ -115,14 +116,7 @@ export function migrateRawDocsSafely( err, }); } else { - transformErrors.push({ - rawId: serializer.generateRawId( - savedObject.namespace, - savedObject.type, - savedObject.id - ), - err, - }); // cases we haven't accounted for yet + transformErrors.push({ rawId: raw._id, err }); // cases we haven't accounted for yet } } } else { @@ -167,12 +161,12 @@ function transformNonBlocking( /** * Applies the specified migration function to every saved object document provided * and converts the saved object to a raw document - * @param {MigrateMethod} transformNonBlocking + * @param {MigrateFn} transformNonBlocking * @param {SavedObjectsRawDoc[]} rawDoc * @returns {Promise} */ async function migrateMapToRawDoc( - migrateMethod: MigrateMethod, + migrateMethod: MigrateFn, savedObject: SavedObjectSanitizedDoc, serializer: SavedObjectsSerializer ): Promise { 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 e87aace0e5183..cefe7d9360af0 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 @@ -1038,8 +1038,10 @@ describe('migration actions', () => { const resultsWithProcessDocs = ((await transformTask()) as Either.Right) .right.processedDocs; - expect(resultsWithProcessDocs.length).toEqual(2); + // const foo2 = hits.find((h) => h._id === 'foo:2'); + const foo2 = resultsWithProcessDocs.find((h) => h._id === 'foo:2'); + expect(foo2?._source?.value).toBe(3); }); }); diff --git a/src/core/server/saved_objects/migrationsv2/model.test.ts b/src/core/server/saved_objects/migrationsv2/model.test.ts index 56bbe5f6b4001..984029366b51b 100644 --- a/src/core/server/saved_objects/migrationsv2/model.test.ts +++ b/src/core/server/saved_objects/migrationsv2/model.test.ts @@ -820,9 +820,10 @@ describe('migrations v2 model', () => { }); const newState = model(testState, res) as FatalState; expect(newState.controlState).toBe('FATAL'); - expect(newState.reason).toMatchInlineSnapshot( - `"Migrations failed. Reason: The following saved object documents are corrupt: a:b . To allow migrations to proceed, please delete these documents."` - ); + expect(newState.reason).toMatchInlineSnapshot(` + "Migrations failed. Reason: Corrupt saved object documents: a:b. + . To allow migrations to proceed, please delete these documents." + `); }); }); diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index be70f44930668..948a5a887c486 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -16,7 +16,7 @@ import { IndexMapping } from '../mappings'; import { ResponseType } from './next'; import { SavedObjectsMigrationVersion } from '../types'; import { disableUnknownTypeMappingFields } from '../migrations/core/migration_context'; -import { excludeUnusedTypesQuery } from '../migrations/core'; +import { excludeUnusedTypesQuery, TransformErrorObjects } from '../migrations/core'; import { SavedObjectsMigrationConfigType } from '../saved_objects_config'; /** @@ -97,6 +97,31 @@ function getAliases(indices: FetchIndexResponse) { }, {} as Record); } +/** + * Creates a record of alias -> index name pairs + */ +function extractTransformFailuresReason( + corruptDocumentIds: string[], + transformErrors: TransformErrorObjects[] +): { corruptDocsReason: string; transformErrsReason: string } { + const corruptDocumentIdReason = + corruptDocumentIds.length > 0 + ? ` Corrupt saved object documents: ${corruptDocumentIds.join(',')}.\n` + : ' '; + // we have both the saved object Id and the stack trace in each `transformErrors` item. + const transformErrorsReason = + transformErrors.length > 0 + ? 'Transformation errors: ' + + transformErrors + .map((errObj) => `${errObj.rawId}: ${errObj.err.message}\n ${errObj.err.stack ?? ''}`) + .join('/n') + : ''; + return { + corruptDocsReason: corruptDocumentIdReason, + transformErrsReason: transformErrorsReason, + }; +} + const delayRetryState = ( state: S, errorMessage: string, @@ -500,26 +525,31 @@ export const model = (currentState: State, resW: ResponseType): lastHitSortValue: res.right.lastHitSortValue, }; } else { - // we don't have any more outdated documents but had issues with transforming docs, we fail the migration + // we don't have any more outdated documents and need to either fail or move on to updating the target mappings. if (stateP.corruptDocumentIds.length > 0 || stateP.transformErrors.length > 0) { - // if documents couldn't be transformed or there were transformation errors we fail the migration - const corruptDocumentIdReason = - stateP.corruptDocumentIds.length > 0 - ? `The following saved object documents are corrupt: ${stateP.corruptDocumentIds.join( - ',' - )}` - : ''; - const transformErrorsReason = - stateP.transformErrors.length > 0 - ? 'The following saved object documents could not be transformed:/n' + - stateP.transformErrors - .map((errObj) => `${errObj.rawId}: ${errObj.err.message}`) - .join('/n') - : ''; + // // If documents couldn't be transformed or there were transformation errors we fail the migration + // const corruptDocumentIdReason = + // stateP.corruptDocumentIds.length > 0 + // ? ` Corrupt saved object documents: ${stateP.corruptDocumentIds.join(',')}.\n` + // : ' '; + // // we have both the saved object Id and the stack trace in each `transformErrors` item. + // const transformErrorsReason = + // stateP.transformErrors.length > 0 + // ? 'Transformation errors: ' + + // stateP.transformErrors + // .map( + // (errObj) => `${errObj.rawId}: ${errObj.err.message}\n ${errObj.err.stack ?? ''}` + // ) + // .join('/n') + // : ''; + const { corruptDocsReason, transformErrsReason } = extractTransformFailuresReason( + stateP.corruptDocumentIds, + stateP.transformErrors + ); return { ...stateP, controlState: 'FATAL', - reason: `Migrations failed. Reason: ${corruptDocumentIdReason} ${transformErrorsReason}. To allow migrations to proceed, please delete these documents.`, + reason: `Migrations failed. Reason: ${corruptDocsReason} ${transformErrsReason}. To allow migrations to proceed, please delete these documents.`, }; } else { // we don't have any more outdated documents and we haven't encountered any document transformation issues. @@ -681,25 +711,29 @@ export const model = (currentState: State, resW: ResponseType): } else { // we don't have any more outdated documents and need to either fail or move on to updating the target mappings. if (stateP.corruptDocumentIds.length > 0 || stateP.transformErrors.length > 0) { - // If documents couldn't be transformed or there were transformation errors we fail the migration - const corruptDocumentIdReason = - stateP.corruptDocumentIds.length > 0 - ? ` Corrupt saved object documents: ${stateP.corruptDocumentIds.join(',')}.\n` - : ' '; - // we have both the saved object Id and the stack trace in each `transformErrors` item. - const transformErrorsReason = - stateP.transformErrors.length > 0 - ? 'Transformation errors: ' + - stateP.transformErrors - .map( - (errObj) => `${errObj.rawId}: ${errObj.err.message}\n ${errObj.err.stack ?? ''}` - ) - .join('/n') - : ''; + const { corruptDocsReason, transformErrsReason } = extractTransformFailuresReason( + stateP.corruptDocumentIds, + stateP.transformErrors + ); + // // If documents couldn't be transformed or there were transformation errors we fail the migration + // const corruptDocumentIdReason = + // stateP.corruptDocumentIds.length > 0 + // ? ` Corrupt saved object documents: ${stateP.corruptDocumentIds.join(',')}.\n` + // : ' '; + // // we have both the saved object Id and the stack trace in each `transformErrors` item. + // const transformErrorsReason = + // stateP.transformErrors.length > 0 + // ? 'Transformation errors: ' + + // stateP.transformErrors + // .map( + // (errObj) => `${errObj.rawId}: ${errObj.err.message}\n ${errObj.err.stack ?? ''}` + // ) + // .join('/n') + // : ''; return { ...stateP, controlState: 'FATAL', - reason: `Migrations failed. Reason:${corruptDocumentIdReason}${transformErrorsReason}. To allow migrations to proceed, please delete these documents.`, + reason: `Migrations failed. Reason:${corruptDocsReason}${transformErrsReason}. To allow migrations to proceed, please delete these documents.`, }; } else { // If there are no more results we have transformed all outdated From 9bb9ec1cd002bb7dda8bf5bf9c0d46fb2d6aad9a Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Thu, 6 May 2021 14:42:27 -0700 Subject: [PATCH 23/27] Deletes commented out code --- .../saved_objects/migrationsv2/model.ts | 32 +------------------ 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index 948a5a887c486..fc098db46d07f 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -98,7 +98,7 @@ function getAliases(indices: FetchIndexResponse) { } /** - * Creates a record of alias -> index name pairs + * Constructs migration failure message strings from corrupt document ids and document transformation errors */ function extractTransformFailuresReason( corruptDocumentIds: string[], @@ -527,21 +527,6 @@ export const model = (currentState: State, resW: ResponseType): } else { // we don't have any more outdated documents and need to either fail or move on to updating the target mappings. if (stateP.corruptDocumentIds.length > 0 || stateP.transformErrors.length > 0) { - // // If documents couldn't be transformed or there were transformation errors we fail the migration - // const corruptDocumentIdReason = - // stateP.corruptDocumentIds.length > 0 - // ? ` Corrupt saved object documents: ${stateP.corruptDocumentIds.join(',')}.\n` - // : ' '; - // // we have both the saved object Id and the stack trace in each `transformErrors` item. - // const transformErrorsReason = - // stateP.transformErrors.length > 0 - // ? 'Transformation errors: ' + - // stateP.transformErrors - // .map( - // (errObj) => `${errObj.rawId}: ${errObj.err.message}\n ${errObj.err.stack ?? ''}` - // ) - // .join('/n') - // : ''; const { corruptDocsReason, transformErrsReason } = extractTransformFailuresReason( stateP.corruptDocumentIds, stateP.transformErrors @@ -715,21 +700,6 @@ export const model = (currentState: State, resW: ResponseType): stateP.corruptDocumentIds, stateP.transformErrors ); - // // If documents couldn't be transformed or there were transformation errors we fail the migration - // const corruptDocumentIdReason = - // stateP.corruptDocumentIds.length > 0 - // ? ` Corrupt saved object documents: ${stateP.corruptDocumentIds.join(',')}.\n` - // : ' '; - // // we have both the saved object Id and the stack trace in each `transformErrors` item. - // const transformErrorsReason = - // stateP.transformErrors.length > 0 - // ? 'Transformation errors: ' + - // stateP.transformErrors - // .map( - // (errObj) => `${errObj.rawId}: ${errObj.err.message}\n ${errObj.err.stack ?? ''}` - // ) - // .join('/n') - // : ''; return { ...stateP, controlState: 'FATAL', From 22a6ca3272670c8cce374d3054abbc15185619a8 Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Thu, 6 May 2021 16:34:54 -0700 Subject: [PATCH 24/27] Error message format changes and updates to snapshots --- .../migrationsv2/integration_tests/cleanup.test.ts | 2 +- src/core/server/saved_objects/migrationsv2/model.test.ts | 9 ++++----- src/core/server/saved_objects/migrationsv2/model.ts | 4 ++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/core/server/saved_objects/migrationsv2/integration_tests/cleanup.test.ts b/src/core/server/saved_objects/migrationsv2/integration_tests/cleanup.test.ts index 79e7d77436ede..78fb685a45165 100644 --- a/src/core/server/saved_objects/migrationsv2/integration_tests/cleanup.test.ts +++ b/src/core/server/saved_objects/migrationsv2/integration_tests/cleanup.test.ts @@ -100,7 +100,7 @@ describe('migration v2', () => { await root.setup(); await expect(root.start()).rejects.toThrow( - 'Unable to complete saved object migrations for the [.kibana] index: Migrations failed. Reason: The following saved object documents are corrupt: index-pattern:test_index* . To allow migrations to proceed, please delete these documents.' + 'Unable to complete saved object migrations for the [.kibana] index: Migrations failed. Reason: Corrupt saved object documents: index-pattern:test_index*. To allow migrations to proceed, please delete these documents.' ); const logFileContent = await asyncReadFile(logFilePath, 'utf-8'); diff --git a/src/core/server/saved_objects/migrationsv2/model.test.ts b/src/core/server/saved_objects/migrationsv2/model.test.ts index 984029366b51b..b98186ce8e3f8 100644 --- a/src/core/server/saved_objects/migrationsv2/model.test.ts +++ b/src/core/server/saved_objects/migrationsv2/model.test.ts @@ -820,10 +820,9 @@ describe('migrations v2 model', () => { }); const newState = model(testState, res) as FatalState; expect(newState.controlState).toBe('FATAL'); - expect(newState.reason).toMatchInlineSnapshot(` - "Migrations failed. Reason: Corrupt saved object documents: a:b. - . To allow migrations to proceed, please delete these documents." - `); + expect(newState.reason).toMatchInlineSnapshot( + `"Migrations failed. Reason: Corrupt saved object documents: a:b. To allow migrations to proceed, please delete these documents."` + ); }); }); @@ -1069,7 +1068,7 @@ describe('migrations v2 model', () => { }; const newState = model(transformErrorsState, res) as FatalState; expect(newState.controlState).toBe('FATAL'); - expect(newState.reason.includes('Migrations failed. Reason: ')).toBe(true); + expect(newState.reason.includes('Migrations failed. Reason:')).toBe(true); expect(newState.reason.includes('Corrupt saved object documents: ')).toBe(true); expect(newState.reason.includes('Transformation errors: ')).toBe(true); expect(newState.reason.includes('randomvis: 7.12.0')).toBe(true); diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index fc098db46d07f..565dde1ba67ed 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -106,7 +106,7 @@ function extractTransformFailuresReason( ): { corruptDocsReason: string; transformErrsReason: string } { const corruptDocumentIdReason = corruptDocumentIds.length > 0 - ? ` Corrupt saved object documents: ${corruptDocumentIds.join(',')}.\n` + ? `Corrupt saved object documents: ${corruptDocumentIds.join(',')}.` : ' '; // we have both the saved object Id and the stack trace in each `transformErrors` item. const transformErrorsReason = @@ -534,7 +534,7 @@ export const model = (currentState: State, resW: ResponseType): return { ...stateP, controlState: 'FATAL', - reason: `Migrations failed. Reason: ${corruptDocsReason} ${transformErrsReason}. To allow migrations to proceed, please delete these documents.`, + reason: `Migrations failed. Reason: ${corruptDocsReason} ${transformErrsReason} To allow migrations to proceed, please delete these documents.`, }; } else { // we don't have any more outdated documents and we haven't encountered any document transformation issues. From 1814c873aaef5ae8ec2d7bd14811a535769e3d6b Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Sun, 9 May 2021 12:51:02 -0700 Subject: [PATCH 25/27] Adds integration test for collecting document migration failures across all batches --- ....0_migrated_with_corrupt_outdated_docs.zip | Bin 0 -> 444632 bytes .../corrupt_outdated_docs.test.ts | 153 ++++++++++++++++++ .../saved_objects/migrationsv2/model.test.ts | 2 +- .../saved_objects/migrationsv2/model.ts | 8 +- 4 files changed, 158 insertions(+), 5 deletions(-) create mode 100644 src/core/server/saved_objects/migrationsv2/integration_tests/archives/8.0.0_migrated_with_corrupt_outdated_docs.zip create mode 100644 src/core/server/saved_objects/migrationsv2/integration_tests/corrupt_outdated_docs.test.ts diff --git a/src/core/server/saved_objects/migrationsv2/integration_tests/archives/8.0.0_migrated_with_corrupt_outdated_docs.zip b/src/core/server/saved_objects/migrationsv2/integration_tests/archives/8.0.0_migrated_with_corrupt_outdated_docs.zip new file mode 100644 index 0000000000000000000000000000000000000000..726df7782cda3f4afdae7b214eaa482ece1fd725 GIT binary patch literal 444632 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 z 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 z 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

#84I5c!S+XrcDuTtHMwr*?59I@K3nn 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%0AMUEmSCXn#UD*gb>J|ID;yx4=s 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�pyPH0|Vh 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

Q225q)$+?Zm_!9&-z`nI3iXQ$L{_K?{^I6EsOY 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 z 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%0D!g9rAPw9FLzIMQcx|jPGKymBL9bGr=4{H=tI2}( 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%0A}t^h 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 MH void 0); +} + +describe('migration v2 with corrupt saved object documents', () => { + let esServer: kbnTestServer.TestElasticsearchUtils; + let root: Root; + + beforeAll(async () => { + await removeLogFile(); + }); + + afterAll(async () => { + if (root) { + await root.shutdown(); + } + if (esServer) { + await esServer.stop(); + } + + await new Promise((resolve) => setTimeout(resolve, 10000)); + }); + + it('collects corrupt saved object documents accross batches', async () => { + const { startES } = kbnTestServer.createTestServers({ + adjustTimeout: (t: number) => jest.setTimeout(t), + settings: { + es: { + license: 'basic', + // original uncorrupt SO: + // { + // type: 'foo', // 'bar', 'baz' + // foo: {}, // bar: {}, baz: {} + // migrationVersion: { + // foo: '7.13.0', + // }, + // }, + // original corrupt SO example: + // { + // id: 'bar:123' + // type: 'foo', + // foo: {}, + // migrationVersion: { + // foo: '7.13.0', + // }, + // }, + // contains migrated index with 8.0 aliases to skip migration, but run outdated doc search + dataArchive: Path.join( + __dirname, + 'archives', + '8.0.0_migrated_with_corrupt_outdated_docs.zip' + ), + }, + }, + }); + + root = createRoot(); + + esServer = await startES(); + const coreSetup = await root.setup(); + + coreSetup.savedObjects.registerType({ + name: 'foo', + hidden: false, + mappings: { properties: {} }, + namespaceType: 'agnostic', + migrations: { + '7.14.0': (doc) => doc, + }, + }); + coreSetup.savedObjects.registerType({ + name: 'bar', + hidden: false, + mappings: { properties: {} }, + namespaceType: 'agnostic', + migrations: { + '7.14.0': (doc) => doc, + }, + }); + coreSetup.savedObjects.registerType({ + name: 'baz', + hidden: false, + mappings: { properties: {} }, + namespaceType: 'agnostic', + migrations: { + '7.14.0': (doc) => doc, + }, + }); + try { + await root.start(); + } catch (err) { + const corruptFooSOs = /foo:/g; + const corruptBarSOs = /bar:/g; + const corruptBazSOs = /baz:/g; + expect( + [...err.message.matchAll(corruptFooSOs)].concat( + [...err.message.matchAll(corruptBarSOs)], + [...err.message.matchAll(corruptBazSOs)] + ).length + ).toEqual(16); + } + }); +}); + +function createRoot() { + return kbnTestServer.createRootWithCorePlugins( + { + migrations: { + skip: false, + enableV2: true, + batchSize: 5, + }, + logging: { + appenders: { + file: { + type: 'file', + fileName: logFilePath, + layout: { + type: 'json', + }, + }, + }, + loggers: [ + { + name: 'root', + appenders: ['file'], + }, + ], + }, + }, + { + oss: true, + } + ); +} diff --git a/src/core/server/saved_objects/migrationsv2/model.test.ts b/src/core/server/saved_objects/migrationsv2/model.test.ts index b98186ce8e3f8..bdaedba9c9ea3 100644 --- a/src/core/server/saved_objects/migrationsv2/model.test.ts +++ b/src/core/server/saved_objects/migrationsv2/model.test.ts @@ -821,7 +821,7 @@ describe('migrations v2 model', () => { const newState = model(testState, res) as FatalState; expect(newState.controlState).toBe('FATAL'); expect(newState.reason).toMatchInlineSnapshot( - `"Migrations failed. Reason: Corrupt saved object documents: a:b. To allow migrations to proceed, please delete these documents."` + `"Migrations failed. Reason: Corrupt saved object documents: a:b. To allow migrations to proceed, please delete these documents."` ); }); }); diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts index 565dde1ba67ed..cf9d6aec6b5b0 100644 --- a/src/core/server/saved_objects/migrationsv2/model.ts +++ b/src/core/server/saved_objects/migrationsv2/model.ts @@ -106,12 +106,12 @@ function extractTransformFailuresReason( ): { corruptDocsReason: string; transformErrsReason: string } { const corruptDocumentIdReason = corruptDocumentIds.length > 0 - ? `Corrupt saved object documents: ${corruptDocumentIds.join(',')}.` - : ' '; + ? ` Corrupt saved object documents: ${corruptDocumentIds.join(',')}` + : ''; // we have both the saved object Id and the stack trace in each `transformErrors` item. const transformErrorsReason = transformErrors.length > 0 - ? 'Transformation errors: ' + + ? ' Transformation errors: ' + transformErrors .map((errObj) => `${errObj.rawId}: ${errObj.err.message}\n ${errObj.err.stack ?? ''}`) .join('/n') @@ -534,7 +534,7 @@ export const model = (currentState: State, resW: ResponseType): return { ...stateP, controlState: 'FATAL', - reason: `Migrations failed. Reason: ${corruptDocsReason} ${transformErrsReason} To allow migrations to proceed, please delete these documents.`, + reason: `Migrations failed. Reason:${corruptDocsReason}${transformErrsReason}. To allow migrations to proceed, please delete these documents.`, }; } else { // we don't have any more outdated documents and we haven't encountered any document transformation issues. From 671b2863318ff176ff35fce6645353de42354c23 Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Sun, 9 May 2021 13:36:27 -0700 Subject: [PATCH 26/27] Updates expected test string --- .../migrationsv2/integration_tests/cleanup.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/server/saved_objects/migrationsv2/integration_tests/cleanup.test.ts b/src/core/server/saved_objects/migrationsv2/integration_tests/cleanup.test.ts index 78fb685a45165..1e494d4b55861 100644 --- a/src/core/server/saved_objects/migrationsv2/integration_tests/cleanup.test.ts +++ b/src/core/server/saved_objects/migrationsv2/integration_tests/cleanup.test.ts @@ -100,7 +100,7 @@ describe('migration v2', () => { await root.setup(); await expect(root.start()).rejects.toThrow( - 'Unable to complete saved object migrations for the [.kibana] index: Migrations failed. Reason: Corrupt saved object documents: index-pattern:test_index*. To allow migrations to proceed, please delete these documents.' + 'Unable to complete saved object migrations for the [.kibana] index: Migrations failed. Reason: Corrupt saved object documents: index-pattern:test_index*. To allow migrations to proceed, please delete these documents.' ); const logFileContent = await asyncReadFile(logFilePath, 'utf-8'); From 39f9f282c2ecb31d706d756d1ca88c94b387a3f1 Mon Sep 17 00:00:00 2001 From: Christiane Heiligers Date: Mon, 10 May 2021 12:10:53 -0700 Subject: [PATCH 27/27] Addresses minor changes requested --- .../migrations/core/migrate_raw_docs.ts | 19 +++++++++---------- .../integration_tests/actions.test.ts | 1 - .../corrupt_outdated_docs.test.ts | 9 +++++---- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts index c7d56f3912256..461ae1df6bc3d 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts @@ -21,16 +21,16 @@ import { MigrateAndConvertFn } from './document_migrator'; import { TransformSavedObjectDocumentError } from '.'; export interface DocumentsTransformFailed { - type: string; - corruptDocumentIds: string[]; - transformErrors: TransformErrorObjects[]; + readonly type: string; + readonly corruptDocumentIds: string[]; + readonly transformErrors: TransformErrorObjects[]; } export interface DocumentsTransformSuccess { - processedDocs: SavedObjectsRawDoc[]; + readonly processedDocs: SavedObjectsRawDoc[]; } export interface TransformErrorObjects { - rawId: string; - err: TransformSavedObjectDocumentError | Error; + readonly rawId: string; + readonly err: TransformSavedObjectDocumentError | Error; } type MigrateFn = ( doc: SavedObjectUnsanitizedDoc @@ -101,7 +101,6 @@ export function migrateRawDocsSafely( const options = { namespaceTreatment: 'lax' as const }; for (const raw of rawDocs) { if (serializer.isRawSavedObject(raw, options)) { - // const savedObject = convertToRawAddMigrationVersion(raw, options, serializer); try { const savedObject = convertToRawAddMigrationVersion(raw, options, serializer); processedDocs.push( @@ -110,9 +109,9 @@ export function migrateRawDocsSafely( } catch (err) { if (err instanceof TransformSavedObjectDocumentError) { // the doc id we get from the error is only the uuid part - // we transform the id to a raw saved object id. + // we use the original raw document _id instead transformErrors.push({ - rawId: serializer.generateRawId(err.namespace, err.type, err.id), + rawId: raw._id, err, }); } else { @@ -179,7 +178,7 @@ async function migrateMapToRawDoc( } /** - * Sanitizes the raw saved object document and sets the migration version + * Sanitizes the raw saved object document * @param {SavedObjectRawDoc} rawDoc * @param options * @param {SavedObjectsSerializer} serializer 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 cefe7d9360af0..d0158a4c68f24 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 @@ -1039,7 +1039,6 @@ describe('migration actions', () => { const resultsWithProcessDocs = ((await transformTask()) as Either.Right) .right.processedDocs; expect(resultsWithProcessDocs.length).toEqual(2); - // const foo2 = hits.find((h) => h._id === 'foo:2'); const foo2 = resultsWithProcessDocs.find((h) => h._id === 'foo:2'); expect(foo2?._source?.value).toBe(3); }); diff --git a/src/core/server/saved_objects/migrationsv2/integration_tests/corrupt_outdated_docs.test.ts b/src/core/server/saved_objects/migrationsv2/integration_tests/corrupt_outdated_docs.test.ts index 244cd4b1c21c9..e48f1e65c120f 100644 --- a/src/core/server/saved_objects/migrationsv2/integration_tests/corrupt_outdated_docs.test.ts +++ b/src/core/server/saved_objects/migrationsv2/integration_tests/corrupt_outdated_docs.test.ts @@ -111,10 +111,11 @@ describe('migration v2 with corrupt saved object documents', () => { const corruptBarSOs = /bar:/g; const corruptBazSOs = /baz:/g; expect( - [...err.message.matchAll(corruptFooSOs)].concat( - [...err.message.matchAll(corruptBarSOs)], - [...err.message.matchAll(corruptBazSOs)] - ).length + [ + ...err.message.matchAll(corruptFooSOs), + ...err.message.matchAll(corruptBarSOs), + ...err.message.matchAll(corruptBazSOs), + ].length ).toEqual(16); } });