Skip to content

Commit

Permalink
[Discover] Migrate es query legacy rule params (#129179)
Browse files Browse the repository at this point in the history
* [Alerting] migrate es query legacy rule params

* [Discover] add closing bracket

* [Discover] apply suggestions

* [Discover] resolve comments

* [Discover] change version

* [Discover] apply suggestions

* [Discover] apply suggestions
  • Loading branch information
dimaanj authored May 6, 2022
1 parent 0d4cc4d commit 2c09170
Show file tree
Hide file tree
Showing 12 changed files with 572 additions and 135 deletions.
10 changes: 10 additions & 0 deletions src/plugins/data/common/search/search_source/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,13 @@ export interface ShardFailure {
};
shard: number;
}

export function isSerializedSearchSource(
maybeSerializedSearchSource: unknown
): maybeSerializedSearchSource is SerializedSearchSourceFields {
return (
typeof maybeSerializedSearchSource === 'object' &&
maybeSerializedSearchSource !== null &&
!Array.isArray(maybeSerializedSearchSource)
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ Object {
testMigrateMatchAllQuery(migrationFn);
});
});

it('should apply search source migrations within saved search', () => {
const savedSearch = {
attributes: {
Expand Down Expand Up @@ -379,4 +380,27 @@ Object {
},
});
});

it('should not apply search source migrations within saved search when searchSourceJSON is not an object', () => {
const savedSearch = {
attributes: {
kibanaSavedObjectMeta: {
searchSourceJSON: '5',
},
},
} as SavedObjectUnsanitizedDoc;

const versionToTest = '9.1.2';
const migrations = getAllMigrations({
[versionToTest]: (state) => ({ ...state, migrated: true }),
});

expect(migrations[versionToTest](savedSearch, {} as SavedObjectMigrationContext)).toEqual({
attributes: {
kibanaSavedObjectMeta: {
searchSourceJSON: '5',
},
},
});
});
});
40 changes: 22 additions & 18 deletions src/plugins/discover/server/saved_objects/search_migrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import type {
import { mergeSavedObjectMigrationMaps } from '@kbn/core/server';
import { DEFAULT_QUERY_LANGUAGE } from '@kbn/data-plugin/server';
import { MigrateFunctionsObject, MigrateFunction } from '@kbn/kibana-utils-plugin/common';
import type { SerializedSearchSourceFields } from '@kbn/data-plugin/common';
import { isSerializedSearchSource, SerializedSearchSourceFields } from '@kbn/data-plugin/common';

export interface SavedSearchMigrationAttributes extends SavedObjectAttributes {
kibanaSavedObjectMeta: {
Expand Down Expand Up @@ -135,27 +135,31 @@ const migrateSearchSortToNestedArray: SavedObjectMigrationFn<any, any> = (doc) =
/**
* This creates a migration map that applies search source migrations
*/
const getSearchSourceMigrations = (searchSourceMigrations: MigrateFunctionsObject) =>
const getSearchSourceMigrations = (
searchSourceMigrations: MigrateFunctionsObject
): MigrateFunctionsObject =>
mapValues<MigrateFunctionsObject, MigrateFunction>(
searchSourceMigrations,
(migrate: MigrateFunction<SerializedSearchSourceFields>): MigrateFunction =>
(state) => {
const _state = state as unknown as { attributes: SavedSearchMigrationAttributes };

const parsedSearchSourceJSON = _state.attributes.kibanaSavedObjectMeta.searchSourceJSON;

if (!parsedSearchSourceJSON) return _state;

return {
..._state,
attributes: {
..._state.attributes,
kibanaSavedObjectMeta: {
..._state.attributes.kibanaSavedObjectMeta,
searchSourceJSON: JSON.stringify(migrate(JSON.parse(parsedSearchSourceJSON))),
const _state = state as { attributes: SavedSearchMigrationAttributes };

const parsedSearchSourceJSON = JSON.parse(
_state.attributes.kibanaSavedObjectMeta.searchSourceJSON
);
if (isSerializedSearchSource(parsedSearchSourceJSON)) {
return {
..._state,
attributes: {
..._state.attributes,
kibanaSavedObjectMeta: {
..._state.attributes.kibanaSavedObjectMeta,
searchSourceJSON: JSON.stringify(migrate(parsedSearchSourceJSON)),
},
},
},
};
};
}
return _state;
}
);

Expand All @@ -171,6 +175,6 @@ export const getAllMigrations = (
): SavedObjectMigrationMap => {
return mergeSavedObjectMigrationMaps(
searchMigrations,
getSearchSourceMigrations(searchSourceMigrations) as unknown as SavedObjectMigrationMap
getSearchSourceMigrations(searchSourceMigrations) as SavedObjectMigrationMap
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -2470,6 +2470,31 @@ describe('migration visualization', () => {
});
});

it('should not apply search source migrations within visualization when searchSourceJSON is not an object', () => {
const visualizationDoc = {
attributes: {
kibanaSavedObjectMeta: {
searchSourceJSON: '5',
},
},
} as SavedObjectUnsanitizedDoc;

const versionToTest = '1.2.4';
const visMigrations = getAllMigrations({
[versionToTest]: (state) => ({ ...state, migrated: true }),
});

expect(
visMigrations[versionToTest](visualizationDoc, {} as SavedObjectMigrationContext)
).toEqual({
attributes: {
kibanaSavedObjectMeta: {
searchSourceJSON: '5',
},
},
});
});

describe('8.1.0 pie - labels and addLegend migration', () => {
const getDoc = (addLegend: boolean, lastLevel: boolean = false) => ({
attributes: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ import type { SavedObjectMigrationFn, SavedObjectMigrationMap } from '@kbn/core/
import { mergeSavedObjectMigrationMaps } from '@kbn/core/server';
import { MigrateFunctionsObject, MigrateFunction } from '@kbn/kibana-utils-plugin/common';

import { DEFAULT_QUERY_LANGUAGE, SerializedSearchSourceFields } from '@kbn/data-plugin/common';
import {
DEFAULT_QUERY_LANGUAGE,
isSerializedSearchSource,
SerializedSearchSourceFields,
} from '@kbn/data-plugin/common';
import { DATA_VIEW_SAVED_OBJECT_TYPE } from '@kbn/data-views-plugin/common';
import {
commonAddSupportOfDualIndexSelectionModeInTSVB,
Expand Down Expand Up @@ -1215,27 +1219,31 @@ const visualizationSavedObjectTypeMigrations = {
/**
* This creates a migration map that applies search source migrations to legacy visualization SOs
*/
const getVisualizationSearchSourceMigrations = (searchSourceMigrations: MigrateFunctionsObject) =>
const getVisualizationSearchSourceMigrations = (
searchSourceMigrations: MigrateFunctionsObject
): MigrateFunctionsObject =>
mapValues<MigrateFunctionsObject, MigrateFunction>(
searchSourceMigrations,
(migrate: MigrateFunction<SerializedSearchSourceFields>): MigrateFunction =>
(state) => {
const _state = state as unknown as { attributes: VisualizationSavedObjectAttributes };

const parsedSearchSourceJSON = _state.attributes.kibanaSavedObjectMeta.searchSourceJSON;

if (!parsedSearchSourceJSON) return _state;

return {
..._state,
attributes: {
..._state.attributes,
kibanaSavedObjectMeta: {
..._state.attributes.kibanaSavedObjectMeta,
searchSourceJSON: JSON.stringify(migrate(JSON.parse(parsedSearchSourceJSON))),
const _state = state as { attributes: VisualizationSavedObjectAttributes };

const parsedSearchSourceJSON = JSON.parse(
_state.attributes.kibanaSavedObjectMeta.searchSourceJSON
);
if (isSerializedSearchSource(parsedSearchSourceJSON)) {
return {
..._state,
attributes: {
..._state.attributes,
kibanaSavedObjectMeta: {
..._state.attributes.kibanaSavedObjectMeta,
searchSourceJSON: JSON.stringify(migrate(parsedSearchSourceJSON)),
},
},
},
};
};
}
return _state;
}
);

Expand All @@ -1244,7 +1252,5 @@ export const getAllMigrations = (
): SavedObjectMigrationMap =>
mergeSavedObjectMigrationMaps(
visualizationSavedObjectTypeMigrations,
getVisualizationSearchSourceMigrations(
searchSourceMigrations
) as unknown as SavedObjectMigrationMap
getVisualizationSearchSourceMigrations(searchSourceMigrations) as SavedObjectMigrationMap
);
5 changes: 5 additions & 0 deletions x-pack/plugins/alerting/server/plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { eventLogMock } from '@kbn/event-log-plugin/server/mocks';
import { actionsMock } from '@kbn/actions-plugin/server/mocks';
import { dataPluginMock } from '@kbn/data-plugin/server/mocks';
import { monitoringCollectionMock } from '@kbn/monitoring-collection-plugin/server/mocks';
import { PluginSetup as DataPluginSetup } from '@kbn/data-plugin/server';
import { spacesMock } from '@kbn/spaces-plugin/server/mocks';

const generateAlertingConfig = (): AlertingConfig => ({
Expand Down Expand Up @@ -66,6 +67,7 @@ describe('Alerting Plugin', () => {
actions: actionsMock.createSetup(),
statusService: statusServiceMock.createSetupContract(),
monitoringCollection: monitoringCollectionMock.createSetup(),
data: dataPluginMock.createSetupContract() as unknown as DataPluginSetup,
};

let plugin: AlertingPlugin;
Expand Down Expand Up @@ -207,6 +209,7 @@ describe('Alerting Plugin', () => {
actions: actionsMock.createSetup(),
statusService: statusServiceMock.createSetupContract(),
monitoringCollection: monitoringCollectionMock.createSetup(),
data: dataPluginMock.createSetupContract() as unknown as DataPluginSetup,
});

const startContract = plugin.start(coreMock.createStart(), {
Expand Down Expand Up @@ -246,6 +249,7 @@ describe('Alerting Plugin', () => {
actions: actionsMock.createSetup(),
statusService: statusServiceMock.createSetupContract(),
monitoringCollection: monitoringCollectionMock.createSetup(),
data: dataPluginMock.createSetupContract() as unknown as DataPluginSetup,
});

const startContract = plugin.start(coreMock.createStart(), {
Expand Down Expand Up @@ -296,6 +300,7 @@ describe('Alerting Plugin', () => {
actions: actionsMock.createSetup(),
statusService: statusServiceMock.createSetupContract(),
monitoringCollection: monitoringCollectionMock.createSetup(),
data: dataPluginMock.createSetupContract() as unknown as DataPluginSetup,
});

const startContract = plugin.start(coreMock.createStart(), {
Expand Down
8 changes: 7 additions & 1 deletion x-pack/plugins/alerting/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { BehaviorSubject } from 'rxjs';
import { pick } from 'lodash';
import { UsageCollectionSetup, UsageCounter } from '@kbn/usage-collection-plugin/server';
import { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server';
import { PluginSetup as DataPluginSetup } from '@kbn/data-plugin/server';
import {
EncryptedSavedObjectsPluginSetup,
EncryptedSavedObjectsPluginStart,
Expand Down Expand Up @@ -140,6 +141,7 @@ export interface AlertingPluginsSetup {
eventLog: IEventLogService;
statusService: StatusServiceSetup;
monitoringCollection: MonitoringCollectionSetup;
data: DataPluginSetup;
}

export interface AlertingPluginsStart {
Expand Down Expand Up @@ -247,12 +249,16 @@ export class AlertingPlugin {
// Usage counter for telemetry
this.usageCounter = plugins.usageCollection?.createUsageCounter(ALERTS_FEATURE_ID);

const getSearchSourceMigrations = plugins.data.search.searchSource.getAllMigrations.bind(
plugins.data.search.searchSource
);
setupSavedObjects(
core.savedObjects,
plugins.encryptedSavedObjects,
this.ruleTypeRegistry,
this.logger,
plugins.actions.isPreconfiguredConnector
plugins.actions.isPreconfiguredConnector,
getSearchSourceMigrations
);

initializeApiKeyInvalidator(
Expand Down
6 changes: 4 additions & 2 deletions x-pack/plugins/alerting/server/saved_objects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
SavedObjectsServiceSetup,
} from '@kbn/core/server';
import { EncryptedSavedObjectsPluginSetup } from '@kbn/encrypted-saved-objects-plugin/server';
import { MigrateFunctionsObject } from '@kbn/kibana-utils-plugin/common';
import { alertMappings } from './mappings';
import { getMigrations } from './migrations';
import { transformRulesForExport } from './transform_rule_for_export';
Expand Down Expand Up @@ -51,14 +52,15 @@ export function setupSavedObjects(
encryptedSavedObjects: EncryptedSavedObjectsPluginSetup,
ruleTypeRegistry: RuleTypeRegistry,
logger: Logger,
isPreconfigured: (connectorId: string) => boolean
isPreconfigured: (connectorId: string) => boolean,
getSearchSourceMigrations: () => MigrateFunctionsObject
) {
savedObjects.registerType({
name: 'alert',
hidden: true,
namespaceType: 'multiple-isolated',
convertToMultiNamespaceTypeVersion: '8.0.0',
migrations: getMigrations(encryptedSavedObjects, isPreconfigured),
migrations: getMigrations(encryptedSavedObjects, getSearchSourceMigrations(), isPreconfigured),
mappings: alertMappings,
management: {
displayName: 'rule',
Expand Down
Loading

0 comments on commit 2c09170

Please sign in to comment.