diff --git a/src/core/server/saved_objects/import/check_conflicts.test.ts b/src/core/server/saved_objects/import/check_conflicts.test.ts index 0d58970eee2c..5029d8ffa620 100644 --- a/src/core/server/saved_objects/import/check_conflicts.test.ts +++ b/src/core/server/saved_objects/import/check_conflicts.test.ts @@ -19,7 +19,7 @@ import { mockUuidv4 } from './__mocks__'; import { savedObjectsClientMock } from '../../mocks'; -import { SavedObjectReference, SavedObjectsImportRetry } from 'kibana/public'; +import { SavedObjectReference, SavedObjectsImportRetry } from 'opensearch-dashboards/public'; import { SavedObjectsClientContract, SavedObject } from '../types'; import { SavedObjectsErrorHelpers } from '..'; import { checkConflicts } from './check_conflicts'; diff --git a/src/core/server/saved_objects/import/validate_references.test.ts b/src/core/server/saved_objects/import/validate_references.test.ts index 6efd1b28b199..afcaa620b017 100644 --- a/src/core/server/saved_objects/import/validate_references.test.ts +++ b/src/core/server/saved_objects/import/validate_references.test.ts @@ -88,7 +88,7 @@ describe('getNonExistingReferenceAsKeys()', () => { expect(savedObjectsClient.bulkGet).toHaveBeenCalledTimes(0); }); - test('removes references that exist within es', async () => { + test('removes references that exist within opensearch', async () => { const savedObjects = [ { id: '2', @@ -477,7 +477,7 @@ describe('validateReferences()', () => { expect(savedObjectsClient.bulkGet).not.toHaveBeenCalled(); }); - test(`doesn't return errors when references exist in Elasticsearch`, async () => { + test(`doesn't return errors when references exist in OpenSearch`, async () => { savedObjectsClient.bulkGet.mockResolvedValue({ saved_objects: [ { diff --git a/src/core/server/saved_objects/mappings/lib/get_root_properties.ts b/src/core/server/saved_objects/mappings/lib/get_root_properties.ts index 3357e84e16ae..4d3657c2b2d2 100644 --- a/src/core/server/saved_objects/mappings/lib/get_root_properties.ts +++ b/src/core/server/saved_objects/mappings/lib/get_root_properties.ts @@ -20,19 +20,19 @@ import { IndexMapping } from '../types'; /** - * Get the property mappings for the root type in the EsMappingsDsl + * Get the property mappings for the root type in the OpenSearchMappingsDsl * * If the mappings don't have a root type, or the root type is not * an object type (it's a keyword or something) this function will * throw an error. * - * EsPropertyMappings objects have the root property names as their + * OpenSearchPropertyMappings objects have the root property names as their * first level keys which map to the mappings object for each property. * If the property is of type object it too could have a `properties` * key whose value follows the same format. * * This data can be found at `{indexName}.mappings.{typeName}.properties` - * in the es indices.get() response. + * in the opensearch indices.get() response. */ export function getRootProperties(mapping: IndexMapping) { if (!mapping.properties) { diff --git a/src/core/server/saved_objects/mappings/lib/get_root_properties_objects.ts b/src/core/server/saved_objects/mappings/lib/get_root_properties_objects.ts index a998dbee0259..cf482cddd160 100644 --- a/src/core/server/saved_objects/mappings/lib/get_root_properties_objects.ts +++ b/src/core/server/saved_objects/mappings/lib/get_root_properties_objects.ts @@ -25,7 +25,7 @@ import { import { getRootProperties } from './get_root_properties'; /** - * Get the property mappings for the root type in the EsMappingsDsl + * Get the property mappings for the root type in the OpenSearchMappingsDsl * where the properties are objects * * If the mappings don't have a root type, or the root type is not @@ -33,10 +33,10 @@ import { getRootProperties } from './get_root_properties'; * throw an error. * * This data can be found at `{indexName}.mappings.{typeName}.properties` - * in the es indices.get() response where the properties are objects. + * in the opensearch indices.get() response where the properties are objects. * - * @param {EsMappingsDsl} mappings - * @return {EsPropertyMappings} + * @param {OpenSearchMappingsDsl} mappings + * @return {OpenSearchPropertyMappings} */ const omittedRootProps = ['migrationVersion', 'references']; diff --git a/src/core/server/saved_objects/mappings/lib/get_types.ts b/src/core/server/saved_objects/mappings/lib/get_types.ts index 66d54aede365..1274958688c3 100644 --- a/src/core/server/saved_objects/mappings/lib/get_types.ts +++ b/src/core/server/saved_objects/mappings/lib/get_types.ts @@ -20,7 +20,7 @@ import { IndexMapping } from '../types'; /** - * Get the names of the types defined in the EsMappingsDsl + * Get the names of the types defined in the OpenSearchMappingsDsl */ export function getTypes(mappings: IndexMapping) { return Object.keys(mappings).filter((type) => type !== '_default_'); diff --git a/src/core/server/saved_objects/migrations/README.md b/src/core/server/saved_objects/migrations/README.md index 91249024358a..880404e2ab40 100644 --- a/src/core/server/saved_objects/migrations/README.md +++ b/src/core/server/saved_objects/migrations/README.md @@ -1,48 +1,48 @@ # Saved Object Migrations -Migrations are the mechanism by which saved object indices are kept up to date with the Kibana system. Plugin authors write their plugins to work with a certain set of mappings, and documents of a certain shape. Migrations ensure that the index actually conforms to those expectations. +Migrations are the mechanism by which saved object indices are kept up to date with the OpenSearch Dashboards system. Plugin authors write their plugins to work with a certain set of mappings, and documents of a certain shape. Migrations ensure that the index actually conforms to those expectations. ## Migrating the index -When Kibana boots, prior to serving any requests, it performs a check to see if the kibana index needs to be migrated. +When OpenSearch Dashboards boots, prior to serving any requests, it performs a check to see if the opensearch-dashboards index needs to be migrated. - If there are out of date docs, or mapping changes, or the current index is not aliased, the index is migrated. -- If the Kibana index does not exist, it is created. +- If the OpenSearch Dashboards index does not exist, it is created. -All of this happens prior to Kibana serving any http requests. +All of this happens prior to OpenSearch Dashboards serving any http requests. Here is the gist of what happens if an index migration is necessary: -* If `.kibana` (or whatever the Kibana index is named) is not an alias, it will be converted to one: - * Reindex `.kibana` into `.kibana_1` - * Delete `.kibana` - * Create an alias `.kibana` that points to `.kibana_1` -* Create a `.kibana_2` index -* Copy all documents from `.kibana_1` into `.kibana_2`, running them through any applicable migrations -* Point the `.kibana` alias to `.kibana_2` +* If `.opensearch-dashboards` (or whatever the OpenSearch Dashboards index is named) is not an alias, it will be converted to one: + * Reindex `.opensearch-dashboards` into `.opensearch-dashboards_1` + * Delete `.opensearch-dashboards` + * Create an alias `.opensearch-dashboards` that points to `.opensearch-dashboards_1` +* Create a `.opensearch-dashboards_2` index +* Copy all documents from `.opensearch-dashboards_1` into `.opensearch-dashboards_2`, running them through any applicable migrations +* Point the `.opensearch-dashboards` alias to `.opensearch-dashboards_2` -## Migrating Kibana clusters +## Migrating OpenSearch Dashboards clusters -If Kibana is being run in a cluster, migrations will be coordinated so that they only run on one Kibana instance at a time. This is done in a fairly rudimentary way. Let's say we have two Kibana instances, kibana1 and kibana2. +If OpenSearch Dashboards is being run in a cluster, migrations will be coordinated so that they only run on one OpenSearch Dashboards instance at a time. This is done in a fairly rudimentary way. Let's say we have two OpenSearch Dashboards instances, opensearch-dashboards-1 and opensearch-dashboards-2. -* kibana1 and kibana2 both start simultaneously and detect that the index requires migration -* kibana1 begins the migration and creates index `.kibana_4` -* kibana2 tries to begin the migration, but fails with the error `.kibana_4 already exists` -* kibana2 logs that it failed to create the migration index, and instead begins polling - * Every few seconds, kibana2 instance checks the `.kibana` index to see if it is done migrating - * Once `.kibana` is determined to be up to date, the kibana2 instance continues booting +* opensearch-dashboards-1 and opensearch-dashboards-2 both start simultaneously and detect that the index requires migration +* opensearch-dashboards-1 begins the migration and creates index `.opensearch-dashboards_4` +* opensearch-dashboards-2 tries to begin the migration, but fails with the error `.opensearch-dashboards_4 already exists` +* opensearch-dashboards-2 logs that it failed to create the migration index, and instead begins polling + * Every few seconds, opensearch-dashboards-2 instance checks the `.opensearch-dashboards` index to see if it is done migrating + * Once `.opensearch-dashboards` is determined to be up to date, the opensearch-dashboards-2 instance continues booting -In this example, if the `.kibana_4` index existed prior to Kibana booting, the entire migration process will fail, as all Kibana instances will assume another instance is migrating to the `.kibana_4` index. This problem is only fixable by deleting the `.kibana_4` index. +In this example, if the `.opensearch-dashboards_4` index existed prior to OpenSearch Dashboards booting, the entire migration process will fail, as all OpenSearch Dashboards instances will assume another instance is migrating to the `.opensearch-dashboards_4` index. This problem is only fixable by deleting the `.opensearch-dashboards_4` index. ## Import / export -If a user attempts to import FanciPlugin 1.0 documents into a Kibana system that is running FanciPlugin 2.0, those documents will be migrated prior to being persisted in the Kibana index. If a user attempts to import documents having a migration version that is _greater_ than the current Kibana version, the documents will fail to import. +If a user attempts to import FanciPlugin 1.0 documents into a OpenSearch Dashboards system that is running FanciPlugin 2.0, those documents will be migrated prior to being persisted in the OpenSearch Dashboards index. If a user attempts to import documents having a migration version that is _greater_ than the current OpenSearch Dashboards version, the documents will fail to import. ## Validation -It might happen that a user modifies their FanciPlugin 1.0 export file to have documents with a migrationVersion of 2.0.0. In this scenario, Kibana will store those documents as if they are up to date, even though they are not, and the result will be unknown, but probably undesirable behavior. +It might happen that a user modifies their FanciPlugin 1.0 export file to have documents with a migrationVersion of 2.0.0. In this scenario, OpenSearch Dashboards will store those documents as if they are up to date, even though they are not, and the result will be unknown, but probably undesirable behavior. -Similarly, Kibana server APIs assume that they are sent up to date documents unless a document specifies a migrationVersion. This means that out-of-date callers of our APIs will send us out-of-date documents, and those documents will be accepted and stored as if they are up-to-date. +Similarly, OpenSearch Dashboards server APIs assume that they are sent up to date documents unless a document specifies a migrationVersion. This means that out-of-date callers of our APIs will send us out-of-date documents, and those documents will be accepted and stored as if they are up-to-date. To prevent this from happening, migration authors should _always_ write a [validation](../validation) function that throws an error if a document is not up to date, and this validation function should always be updated any time a new migration is added for the relevent document types. @@ -60,7 +60,7 @@ So, let's say we have a document that looks like this: } ``` -In this document, one plugin might own the `dashboard` type, and another plugin might own the `securityKey` type. If two or more plugins define securityKey migrations `{ migrations: { securityKey: { ... } } }`, Kibana will fail to start. +In this document, one plugin might own the `dashboard` type, and another plugin might own the `securityKey` type. If two or more plugins define securityKey migrations `{ migrations: { securityKey: { ... } } }`, OpenSearch Dashboards will fail to start. To write a migration for this document, the dashboard plugin might look something like this: @@ -86,17 +86,17 @@ uiExports: { } ``` -After Kibana migrates the index, our example document would have `{ attributes: { title: 'WHATEVER!!' } }`. +After OpenSearch Dashboards migrates the index, our example document would have `{ attributes: { title: 'WHATEVER!!' } }`. Each migration function only needs to be able to handle documents belonging to the previous version. The initial migration function (in this example, `1.9.0`) needs to be more flexible, as it may be passed documents of any pre `1.9.0` shape. ## Disabled plugins -If a plugin is disbled, all of its documents are retained in the Kibana index. They can be imported and exported. When the plugin is re-enabled, Kibana will migrate any out of date documents that were imported or retained while it was disabled. +If a plugin is disbled, all of its documents are retained in the OpenSearch Dashboards index. They can be imported and exported. When the plugin is re-enabled, OpenSearch Dashboards will migrate any out of date documents that were imported or retained while it was disabled. ## Configuration -Kibana index migrations expose a few config settings which might be tweaked: +OpenSearch Dashboards index migrations expose a few config settings which might be tweaked: * `migrations.scrollDuration` - The [scroll](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html#scroll-search-context) @@ -104,13 +104,13 @@ Kibana index migrations expose a few config settings which might be tweaked: `15m`. * `migrations.batchSize` - The number of documents to read / transform / write at a time during index migrations -* `migrations.pollInterval` - How often, in milliseconds, secondary Kibana - instances will poll to see if the primary Kibana instance has finished +* `migrations.pollInterval` - How often, in milliseconds, secondary OpenSearchDashboards + instances will poll to see if the primary OpenSearch Dashboards instance has finished migrating the index. * `migrations.skip` - Skip running migrations on startup (defaults to false). This should only be used for running integration tests without a running - elasticsearch cluster. Note: even though migrations won't run on startup, - individual docs will still be migrated when read from ES. + opensearch cluster. Note: even though migrations won't run on startup, + individual docs will still be migrated when read from OpenSearch. ## Example @@ -170,9 +170,9 @@ uiExports: { } ``` -Now, whenever Kibana boots, if FanciPlugin is enabled, Kibana scans its index for any documents that have type 'fanci' and have a `migrationVersion.fanci` property that is anything other than `2.0.0`. If any such documents are found, the index is determined to be out of date (or at least of the wrong version), and Kibana attempts to migrate the index. +Now, whenever OpenSearch Dashboards boots, if FanciPlugin is enabled, OpenSearch Dashboards scans its index for any documents that have type 'fanci' and have a `migrationVersion.fanci` property that is anything other than `2.0.0`. If any such documents are found, the index is determined to be out of date (or at least of the wrong version), and OpenSearch Dashboards attempts to migrate the index. -At the end of the migration, Kibana's fanci documents will look something like this: +At the end of the migration, OpenSearchDashboards's fanci documents will look something like this: ```js { @@ -191,10 +191,10 @@ Note, the migrationVersion property has been added, and it contains information The migrations source code is grouped into two folders: -* `core` - Contains index-agnostic, general migration logic, which could be reused for indices other than `.kibana` -* `kibana` - Contains a relatively light-weight wrapper around core, which provides `.kibana` index-specific logic +* `core` - Contains index-agnostic, general migration logic, which could be reused for indices other than `.opensearch-dashboards` +* `opensearch-dashboards` - Contains a relatively light-weight wrapper around core, which provides `.opensearch-dashboards` index-specific logic -Generally, the code eschews classes in favor of functions and basic data structures. The publicly exported code is all class-based, however, in an attempt to conform to Kibana norms. +Generally, the code eschews classes in favor of functions and basic data structures. The publicly exported code is all class-based, however, in an attempt to conform to OpenSearch Dashboards norms. ### Core diff --git a/src/core/server/saved_objects/migrations/core/__snapshots__/elastic_index.test.ts.snap b/src/core/server/saved_objects/migrations/core/__snapshots__/opensearch_index.test.ts.snap similarity index 100% rename from src/core/server/saved_objects/migrations/core/__snapshots__/elastic_index.test.ts.snap rename to src/core/server/saved_objects/migrations/core/__snapshots__/opensearch_index.test.ts.snap diff --git a/src/core/server/saved_objects/migrations/core/build_active_mappings.ts b/src/core/server/saved_objects/migrations/core/build_active_mappings.ts index 2f4427b27b6b..aded5a4928ad 100644 --- a/src/core/server/saved_objects/migrations/core/build_active_mappings.ts +++ b/src/core/server/saved_objects/migrations/core/build_active_mappings.ts @@ -54,7 +54,7 @@ export function buildActiveMappings( /** * Diffs the actual vs expected mappings. The properties are compared using md5 hashes stored in _meta, because * actual and expected mappings *can* differ, but if the md5 hashes stored in actual._meta.migrationMappingPropertyHashes - * match our expectations, we don't require a migration. This allows ES to tack on additional mappings that Kibana + * match our expectations, we don't require a migration. This allows OpenSearch to tack on additional mappings that OpenSearchDashboards * doesn't know about or expect, without triggering continual migrations. */ export function diffMappings(actual: IndexMapping, expected: IndexMapping) { diff --git a/src/core/server/saved_objects/migrations/core/build_index_map.test.ts b/src/core/server/saved_objects/migrations/core/build_index_map.test.ts index 031d63a565e8..d12e9f4dce48 100644 --- a/src/core/server/saved_objects/migrations/core/build_index_map.test.ts +++ b/src/core/server/saved_objects/migrations/core/build_index_map.test.ts @@ -38,7 +38,7 @@ const createRegistry = (...types: Array>) => { test('mappings without index pattern goes to default index', () => { const result = createIndexMap({ - kibanaIndexName: '.kibana', + opensearchDashboardsIndexName: '.opensearch-dashboards', registry: createRegistry({ name: 'type1', namespaceType: 'single', @@ -54,7 +54,7 @@ test('mappings without index pattern goes to default index', () => { }, }); expect(result).toEqual({ - '.kibana': { + '.opensearch-dashboards': { typeMappings: { type1: { properties: { @@ -70,11 +70,11 @@ test('mappings without index pattern goes to default index', () => { test(`mappings with custom index pattern doesn't go to default index`, () => { const result = createIndexMap({ - kibanaIndexName: '.kibana', + opensearchDashboardsIndexName: '.opensearch-dashboards', registry: createRegistry({ name: 'type1', namespaceType: 'single', - indexPattern: '.other_kibana', + indexPattern: '.other_opensearch_dashboards', }), indexMap: { type1: { @@ -87,7 +87,7 @@ test(`mappings with custom index pattern doesn't go to default index`, () => { }, }); expect(result).toEqual({ - '.other_kibana': { + '.other_opensearch_dashboards': { typeMappings: { type1: { properties: { @@ -103,11 +103,11 @@ test(`mappings with custom index pattern doesn't go to default index`, () => { test('creating a script gets added to the index pattern', () => { const result = createIndexMap({ - kibanaIndexName: '.kibana', + opensearchDashboardsIndexName: '.opensearch-dashboards', registry: createRegistry({ name: 'type1', namespaceType: 'single', - indexPattern: '.other_kibana', + indexPattern: '.other_opensearch_dashboards', convertToAliasScript: `ctx._id = ctx._source.type + ':' + ctx._id`, }), indexMap: { @@ -121,7 +121,7 @@ test('creating a script gets added to the index pattern', () => { }, }); expect(result).toEqual({ - '.other_kibana': { + '.other_opensearch_dashboards': { script: `ctx._id = ctx._source.type + ':' + ctx._id`, typeMappings: { type1: { @@ -137,7 +137,7 @@ test('creating a script gets added to the index pattern', () => { }); test('throws when two scripts are defined for an index pattern', () => { - const defaultIndex = '.kibana'; + const defaultIndex = '.opensearch-dashboards'; const registry = createRegistry( { name: 'type1', @@ -169,11 +169,11 @@ test('throws when two scripts are defined for an index pattern', () => { }; expect(() => createIndexMap({ - kibanaIndexName: defaultIndex, + opensearchDashboardsIndexName: defaultIndex, registry, indexMap, }) ).toThrowErrorMatchingInlineSnapshot( - `"convertToAliasScript has been defined more than once for index pattern \\".kibana\\""` + `"convertToAliasScript has been defined more than once for index pattern \\".opensearch-dashboards\\""` ); }); diff --git a/src/core/server/saved_objects/migrations/core/build_index_map.ts b/src/core/server/saved_objects/migrations/core/build_index_map.ts index 0848fcf56d9f..acb324ed6a59 100644 --- a/src/core/server/saved_objects/migrations/core/build_index_map.ts +++ b/src/core/server/saved_objects/migrations/core/build_index_map.ts @@ -21,7 +21,7 @@ import { SavedObjectsTypeMappingDefinitions } from '../../mappings'; import { ISavedObjectTypeRegistry } from '../../saved_objects_type_registry'; export interface CreateIndexMapOptions { - kibanaIndexName: string; + opensearchDashboardsIndexName: string; registry: ISavedObjectTypeRegistry; indexMap: SavedObjectsTypeMappingDefinitions; } @@ -36,13 +36,13 @@ export interface IndexMap { /* * This file contains logic to convert savedObjectSchemas into a dictionary of indexes and documents */ -export function createIndexMap({ kibanaIndexName, registry, indexMap }: CreateIndexMapOptions) { +export function createIndexMap({ opensearchDashboardsIndexName, registry, indexMap }: CreateIndexMapOptions) { const map: IndexMap = {}; Object.keys(indexMap).forEach((type) => { const typeDef = registry.getType(type); const script = typeDef?.convertToAliasScript; - // Defaults to kibanaIndexName if indexPattern isn't defined - const indexPattern = typeDef?.indexPattern || kibanaIndexName; + // Defaults to opensearchDashboardsIndexName if indexPattern isn't defined + const indexPattern = typeDef?.indexPattern || opensearchDashboardsIndexName; if (!map.hasOwnProperty(indexPattern as string)) { map[indexPattern] = { typeMappings: {} }; } 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 4cc4f696d307..42623a50d2b8 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 @@ -46,7 +46,7 @@ const createRegistry = (...types: Array>) => { describe('DocumentMigrator', () => { function testOpts() { return { - kibanaVersion: '25.2.3', + opensearchDashboardsVersion: '25.2.3', typeRegistry: createRegistry(), log: mockLogger, }; @@ -54,7 +54,7 @@ describe('DocumentMigrator', () => { it('validates individual migration definitions', () => { const invalidDefinition = { - kibanaVersion: '3.2.3', + opensearchDashboardsVersion: '3.2.3', typeRegistry: createRegistry({ name: 'foo', migrations: _.noop as any, @@ -68,7 +68,7 @@ describe('DocumentMigrator', () => { it('validates individual migration semvers', () => { const invalidDefinition = { - kibanaVersion: '3.2.3', + opensearchDashboardsVersion: '3.2.3', typeRegistry: createRegistry({ name: 'foo', migrations: { @@ -84,7 +84,7 @@ describe('DocumentMigrator', () => { it('validates the migration function', () => { const invalidDefinition = { - kibanaVersion: '3.2.3', + opensearchDashboardsVersion: '3.2.3', typeRegistry: createRegistry({ name: 'foo', migrations: { @@ -277,10 +277,10 @@ describe('DocumentMigrator', () => { }); }); - it('rejects docs that belong to a newer Kibana instance', () => { + it('rejects docs that belong to a newer OpenSearch Dashboards instance', () => { const migrator = new DocumentMigrator({ ...testOpts(), - kibanaVersion: '8.0.1', + opensearchDashboardsVersion: '8.0.1', }); expect(() => migrator.migrate({ @@ -290,7 +290,7 @@ describe('DocumentMigrator', () => { migrationVersion: { dog: '10.2.0' }, }) ).toThrow( - /Document "smelly" has property "dog" which belongs to a more recent version of Kibana \[10\.2\.0\]\. The last known version is \[undefined\]/i + /Document "smelly" has property "dog" which belongs to a more recent version of OpenSearch Dashboards \[10\.2\.0\]\. The last known version is \[undefined\]/i ); }); @@ -312,7 +312,7 @@ describe('DocumentMigrator', () => { migrationVersion: { dawg: '1.2.4' }, }) ).toThrow( - /Document "fleabag" has property "dawg" which belongs to a more recent version of Kibana \[1\.2\.4\]\. The last known version is \[1\.2\.3\]/i + /Document "fleabag" has property "dawg" which belongs to a more recent version of OpenSearch Dashboards \[1\.2\.4\]\. The last known version is \[1\.2\.3\]/i ); }); 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 345704fbfd78..8320b06e3941 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.ts @@ -49,7 +49,7 @@ * they could transform a type from "foo 1.0.0" to "bar 3.0.0". * * One last gotcha is that any docs which have no migrationVersion are assumed to be up-to-date. - * This is because Kibana UI and other clients really can't be expected build the migrationVersion + * This is because OpenSearch Dashboards UI and other clients really can't be expected build the migrationVersion * in a reliable way. Instead, callers of our APIs are expected to send us up-to-date documents, * and those documents are simply given a stamp of approval by this transformer. This is why it is * important for migration authors to *also* write a saved object validation that will prevent this @@ -74,7 +74,7 @@ import { SavedObjectMigrationFn } from '../types'; export type TransformFn = (doc: SavedObjectUnsanitizedDoc) => SavedObjectUnsanitizedDoc; interface DocumentMigratorOptions { - kibanaVersion: string; + opensearchDashboardsVersion: string; typeRegistry: ISavedObjectTypeRegistry; log: Logger; } @@ -108,17 +108,17 @@ export class DocumentMigrator implements VersionedTransformer { * Creates an instance of DocumentMigrator. * * @param {DocumentMigratorOptions} opts - * @prop {string} kibanaVersion - The current version of Kibana + * @prop {string} opensearchDashboardsVersion - The current version of OpenSearchDashboards * @prop {SavedObjectTypeRegistry} typeRegistry - The type registry to get type migrations from * @prop {Logger} log - The migration logger * @memberof DocumentMigrator */ - constructor({ typeRegistry, kibanaVersion, log }: DocumentMigratorOptions) { + constructor({ typeRegistry, opensearchDashboardsVersion, log }: DocumentMigratorOptions) { validateMigrationDefinition(typeRegistry); this.migrations = buildActiveMigrations(typeRegistry, log); this.transformDoc = buildDocumentTransform({ - kibanaVersion, + opensearchDashboardsVersion, migrations: this.migrations, }); } @@ -227,7 +227,7 @@ function buildActiveMigrations( function buildDocumentTransform({ migrations, }: { - kibanaVersion: string; + opensearchDashboardsVersion: string; migrations: ActiveMigrations; }): TransformFn { return function transformAndValidate(doc: SavedObjectUnsanitizedDoc) { @@ -331,15 +331,15 @@ function nextUnmigratedProp(doc: SavedObjectUnsanitizedDoc, migrations: ActiveMi return false; } - // We verify that the version is not greater than the version supported by Kibana. + // We verify that the version is not greater than the version supported by OpenSearchDashboards. // If we didn't, this would cause an infinite loop, as we'd be unable to migrate the property // but it would continue to show up as unmigrated. // If we have a docVersion and the latestVersion is smaller than it or does not exist, - // we are dealing with a document that belongs to a future Kibana / plugin version. + // we are dealing with a document that belongs to a future OpenSearch Dashboards / plugin version. if (docVersion && (!latestVersion || Semver.gt(docVersion, latestVersion))) { throw Boom.badData( `Document "${doc.id}" has property "${p}" which belongs to a more recent` + - ` version of Kibana [${docVersion}]. The last known version is [${latestVersion}]`, + ` version of OpenSearch Dashboards [${docVersion}]. The last known version is [${latestVersion}]`, doc ); } diff --git a/src/core/server/saved_objects/migrations/core/index.ts b/src/core/server/saved_objects/migrations/core/index.ts index c9d3d2a71c9a..81ae9852e9e2 100644 --- a/src/core/server/saved_objects/migrations/core/index.ts +++ b/src/core/server/saved_objects/migrations/core/index.ts @@ -23,4 +23,4 @@ export { buildActiveMappings } from './build_active_mappings'; export { CallCluster } from './call_cluster'; export { LogFn, SavedObjectsMigrationLogger } from './migration_logger'; export { MigrationResult, MigrationStatus } from './migration_coordinator'; -export { createMigrationEsClient, MigrationEsClient } from './migration_es_client'; +export { createMigrationOpenSearchClient, MigrationOpenSearchClient } from './migration_opensearch_client'; diff --git a/src/core/server/saved_objects/migrations/core/index_migrator.test.ts b/src/core/server/saved_objects/migrations/core/index_migrator.test.ts index 13f771c16bc6..8530316a27c7 100644 --- a/src/core/server/saved_objects/migrations/core/index_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/core/index_migrator.test.ts @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import { elasticsearchClientMock } from '../../../elasticsearch/client/mocks'; +import { opensearchClientMock } from '../../../opensearch/client/mocks'; import { SavedObjectUnsanitizedDoc, SavedObjectsSerializer } from '../../serialization'; import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { IndexMigrator } from './index_migrator'; @@ -27,14 +27,14 @@ import { loggingSystemMock } from '../../../logging/logging_system.mock'; describe('IndexMigrator', () => { let testOpts: jest.Mocked & { - client: ReturnType; + client: ReturnType; }; beforeEach(() => { testOpts = { batchSize: 10, - client: elasticsearchClientMock.createElasticsearchClient(), - index: '.kibana', + client: opensearchClientMock.createOpenSearchClient(), + index: '.opensearch-dashboards', log: loggingSystemMock.create().get(), mappingProperties: {}, pollInterval: 1, @@ -92,7 +92,7 @@ describe('IndexMigrator', () => { }, settings: { number_of_shards: 1, auto_expand_replicas: '0-1' }, }, - index: '.kibana_1', + index: '.opensearch-dashboards_1', }); }); @@ -104,8 +104,8 @@ describe('IndexMigrator', () => { const result = await new IndexMigrator(testOpts).migrate(); expect(result).toMatchObject({ - destIndex: '.kibana_1', - sourceIndex: '.kibana', + destIndex: '.opensearch-dashboards_1', + sourceIndex: '.opensearch-dashboards', status: 'migrated', }); }); @@ -115,7 +115,7 @@ describe('IndexMigrator', () => { withIndex(client, { index: { - '.kibana_1': { + '.opensearch-dashboards_1': { aliases: {}, mappings: { foo: { properties: {} }, @@ -139,7 +139,7 @@ describe('IndexMigrator', () => { withIndex(client, { index: { - '.kibana_1': { + '.opensearch-dashboards_1': { aliases: {}, mappings: { poc: { @@ -164,7 +164,7 @@ describe('IndexMigrator', () => { withIndex(client, { index: { - '.kibana_1': { + '.opensearch-dashboards_1': { aliases: {}, mappings: { properties: { @@ -214,7 +214,7 @@ describe('IndexMigrator', () => { }, settings: { number_of_shards: 1, auto_expand_replicas: '0-1' }, }, - index: '.kibana_2', + index: '.opensearch-dashboards_2', }); }); @@ -225,7 +225,7 @@ describe('IndexMigrator', () => { withIndex(client, { index: { - '.kibana_1': { + '.opensearch-dashboards_1': { aliases: {}, mappings: { properties: { @@ -275,7 +275,7 @@ describe('IndexMigrator', () => { }, settings: { number_of_shards: 1, auto_expand_replicas: '0-1' }, }, - index: '.kibana_2', + index: '.opensearch-dashboards_2', }); }); @@ -288,7 +288,7 @@ describe('IndexMigrator', () => { expect(client.indices.create).toHaveBeenCalledWith(expect.any(Object)); expect(client.indices.updateAliases).toHaveBeenCalledWith({ - body: { actions: [{ add: { alias: '.kibana', index: '.kibana_1' } }] }, + body: { actions: [{ add: { alias: '.opensearch-dashboards', index: '.opensearch-dashboards_1' } }] }, }); }); @@ -307,8 +307,8 @@ describe('IndexMigrator', () => { expect(client.indices.updateAliases).toHaveBeenCalledWith({ body: { actions: [ - { remove: { alias: '.kibana', index: '.kibana_1' } }, - { add: { alias: '.kibana', index: '.kibana_2' } }, + { remove: { alias: '.opensearch-dashboards', index: '.opensearch-dashboards_1' } }, + { add: { alias: '.opensearch-dashboards', index: '.opensearch-dashboards_2' } }, ], }, }); @@ -358,13 +358,13 @@ describe('IndexMigrator', () => { expect(client.bulk).toHaveBeenCalledTimes(2); expect(client.bulk).toHaveBeenNthCalledWith(1, { body: [ - { index: { _id: 'foo:1', _index: '.kibana_2' } }, + { index: { _id: 'foo:1', _index: '.opensearch-dashboards_2' } }, { foo: { name: 1 }, type: 'foo', migrationVersion: {}, references: [] }, ], }); expect(client.bulk).toHaveBeenNthCalledWith(2, { body: [ - { index: { _id: 'foo:2', _index: '.kibana_2' } }, + { index: { _id: 'foo:2', _index: '.opensearch-dashboards_2' } }, { foo: { name: 2 }, type: 'foo', migrationVersion: {}, references: [] }, ], }); @@ -396,12 +396,12 @@ describe('IndexMigrator', () => { }); function withIndex( - client: ReturnType, + client: ReturnType, opts: any = {} ) { const defaultIndex = { - '.kibana_1': { - aliases: { '.kibana': {} }, + '.opensearch-dashboards_1': { + aliases: { '.opensearch-dashboards': {} }, mappings: { dynamic: 'strict', properties: { @@ -411,7 +411,7 @@ function withIndex( }, }; const defaultAlias = { - '.kibana_1': {}, + '.opensearch-dashboards_1': {}, }; const { numOutOfDate = 0 } = opts; const { alias = defaultAlias } = opts; @@ -431,32 +431,32 @@ function withIndex( let scrollCallCounter = 1; client.indices.get.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(index, { + opensearchClientMock.createSuccessTransportRequestPromise(index, { statusCode: index.statusCode, }) ); client.indices.getAlias.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(alias, { + opensearchClientMock.createSuccessTransportRequestPromise(alias, { statusCode: index.statusCode, }) ); client.reindex.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ task: 'zeid', _shards: { successful: 1, total: 1 }, }) ); client.tasks.get.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ completed: true }) + opensearchClientMock.createSuccessTransportRequestPromise({ completed: true }) ); client.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(searchResult(0)) + opensearchClientMock.createSuccessTransportRequestPromise(searchResult(0)) ); client.bulk.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ items: [] }) + opensearchClientMock.createSuccessTransportRequestPromise({ items: [] }) ); client.count.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ count: numOutOfDate, _shards: { successful: 1, total: 1 }, }) @@ -465,8 +465,8 @@ function withIndex( if (scrollCallCounter <= docs.length) { const result = searchResult(scrollCallCounter); scrollCallCounter++; - return elasticsearchClientMock.createSuccessTransportRequestPromise(result); + return opensearchClientMock.createSuccessTransportRequestPromise(result); } - return elasticsearchClientMock.createSuccessTransportRequestPromise({}); + return opensearchClientMock.createSuccessTransportRequestPromise({}); }); } diff --git a/src/core/server/saved_objects/migrations/core/index_migrator.ts b/src/core/server/saved_objects/migrations/core/index_migrator.ts index ceca27fa8772..dacab79fdb69 100644 --- a/src/core/server/saved_objects/migrations/core/index_migrator.ts +++ b/src/core/server/saved_objects/migrations/core/index_migrator.ts @@ -17,7 +17,7 @@ * under the License. */ import { diffMappings } from './build_active_mappings'; -import * as Index from './elastic_index'; +import * as Index from './opensearch_index'; import { migrateRawDocs } from './migrate_raw_docs'; import { Context, migrationContext, MigrationOpts } from './migration_context'; import { coordinateMigration, MigrationResult } from './migration_coordinator'; @@ -38,7 +38,7 @@ export class IndexMigrator { } /** - * Migrates the index, or, if another Kibana instance appears to be running the migration, + * Migrates the index, or, if another OpenSearch Dashboards instance appears to be running the migration, * waits for the migration to complete. * * @returns {Promise} 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 5a5048d8ad88..96f280211c47 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 @@ -57,7 +57,7 @@ export async function migrateRawDocs( ); } else { log.error( - `Error: Unable to migrate the corrupt Saved Object document ${raw._id}. To prevent Kibana from performing a migration on every restart, please delete or fix this document by ensuring that the namespace and type in the document's id matches the values in the namespace and type fields.`, + `Error: Unable to migrate the corrupt Saved Object document ${raw._id}. To prevent OpenSearch Dashboards from performing a migration on every restart, please delete or fix this document by ensuring that the namespace and type in the document's id matches the values in the namespace and type fields.`, { rawDocument: raw } ); processedDocs.push(raw); diff --git a/src/core/server/saved_objects/migrations/core/migration_context.ts b/src/core/server/saved_objects/migrations/core/migration_context.ts index 0ea362d65623..4e419aa01a2d 100644 --- a/src/core/server/saved_objects/migrations/core/migration_context.ts +++ b/src/core/server/saved_objects/migrations/core/migration_context.ts @@ -25,7 +25,7 @@ */ import { Logger } from 'src/core/server/logging'; -import { MigrationEsClient } from './migration_es_client'; +import { MigrationOpenSearchClient } from './migration_opensearch_client'; import { SavedObjectsSerializer } from '../../serialization'; import { SavedObjectsTypeMappingDefinitions, @@ -34,14 +34,14 @@ import { } from '../../mappings'; import { buildActiveMappings } from './build_active_mappings'; import { VersionedTransformer } from './document_migrator'; -import * as Index from './elastic_index'; +import * as Index from './opensearch_index'; import { SavedObjectsMigrationLogger, MigrationLogger } from './migration_logger'; export interface MigrationOpts { batchSize: number; pollInterval: number; scrollDuration: string; - client: MigrationEsClient; + client: MigrationOpenSearchClient; index: string; log: Logger; mappingProperties: SavedObjectsTypeMappingDefinitions; @@ -51,7 +51,7 @@ export interface MigrationOpts { /** * If specified, templates matching the specified pattern will be removed - * prior to running migrations. For example: 'kibana_index_template*' + * prior to running migrations. For example: 'opensearch_dashboards_index_template*' */ obsoleteIndexTemplatePattern?: string; } @@ -60,7 +60,7 @@ export interface MigrationOpts { * @internal */ export interface Context { - client: MigrationEsClient; + client: MigrationOpenSearchClient; alias: string; source: Index.FullIndexInfo; dest: Index.FullIndexInfo; @@ -148,7 +148,7 @@ function createDestContext( * target index.) * * @param activeMappings The mappings compiled from all the Saved Object types - * known to this Kibana node. + * known to this OpenSearch Dashboards node. * @param sourceMappings The mappings of index used as the migration source. * @returns The mappings that should be applied to the target index. */ @@ -182,7 +182,7 @@ export function disableUnknownTypeMappingFields( /** * Gets the next index name in a sequence, based on specified current index's info. - * We're using a numeric counter to create new indices. So, `.kibana_1`, `.kibana_2`, etc + * We're using a numeric counter to create new indices. So, `.opensearch-dashboards_1`, `.opensearch-dashboards_2`, etc * There are downsides to this, but it seemed like a simple enough approach. */ function nextIndexName(indexName: string, alias: string) { diff --git a/src/core/server/saved_objects/migrations/core/migration_coordinator.ts b/src/core/server/saved_objects/migrations/core/migration_coordinator.ts index 2e32763f4e63..3d9385b4c6e0 100644 --- a/src/core/server/saved_objects/migrations/core/migration_coordinator.ts +++ b/src/core/server/saved_objects/migrations/core/migration_coordinator.ts @@ -18,20 +18,20 @@ */ /* - * This provides a mechanism for preventing multiple Kibana instances from + * This provides a mechanism for preventing multiple OpenSearch Dashboards instances from * simultaneously running migrations on the same index. It synchronizes this * by handling index creation conflicts, and putting this instance into a * poll loop that periodically checks to see if the index is migrated. * - * The reason we have to coordinate this, rather than letting each Kibana instance - * perform duplicate work, is that if we allowed each Kibana to simply run migrations in + * The reason we have to coordinate this, rather than letting each OpenSearch Dashboards instance + * perform duplicate work, is that if we allowed each OpenSearch Dashboards to simply run migrations in * parallel, they would each try to reindex and each try to create the destination index. - * If those indices already exist, it may be due to contention between multiple Kibana + * If those indices already exist, it may be due to contention between multiple OpenSearchDashboards * instances (which is safe to ignore), but it may be due to a partially completed migration, - * or someone tampering with the Kibana alias. In these cases, it's not clear that we should + * or someone tampering with the OpenSearch Dashboards alias. In these cases, it's not clear that we should * just migrate data into an existing index. Such an action could result in data loss. Instead, - * we should probably fail, and the Kibana sys-admin should clean things up before relaunching - * Kibana. + * we should probably fail, and the OpenSearch Dashboards sys-admin should clean things up before relaunching + * OpenSearchDashboards. */ import _ from 'lodash'; @@ -86,7 +86,7 @@ export async function coordinateMigration(opts: Opts): Promise /** * If the specified error is an index exists error, this logs a warning, * and is the cue for us to fall into a polling loop, waiting for some - * other Kibana instance to complete the migration. + * other OpenSearch Dashboards instance to complete the migration. */ function handleIndexExists(error: any, log: SavedObjectsMigrationLogger) { const isIndexExistsError = @@ -98,10 +98,10 @@ function handleIndexExists(error: any, log: SavedObjectsMigrationLogger) { const index = _.get(error, 'body.error.index'); log.warning( - `Another Kibana instance appears to be migrating the index. Waiting for ` + - `that migration to complete. If no other Kibana instance is attempting ` + + `Another OpenSearch Dashboards instance appears to be migrating the index. Waiting for ` + + `that migration to complete. If no other OpenSearch Dashboards instance is attempting ` + `migrations, you can get past this message by deleting index ${index} and ` + - `restarting Kibana.` + `restarting OpenSearchDashboards.` ); return true; diff --git a/src/core/server/saved_objects/migrations/core/migration_es_client.test.mock.ts b/src/core/server/saved_objects/migrations/core/migration_opensearch_client.test.mock.ts similarity index 92% rename from src/core/server/saved_objects/migrations/core/migration_es_client.test.mock.ts rename to src/core/server/saved_objects/migrations/core/migration_opensearch_client.test.mock.ts index 8ebed25d87cb..9a08f463cd38 100644 --- a/src/core/server/saved_objects/migrations/core/migration_es_client.test.mock.ts +++ b/src/core/server/saved_objects/migrations/core/migration_opensearch_client.test.mock.ts @@ -17,6 +17,6 @@ * under the License. */ export const migrationRetryCallClusterMock = jest.fn((fn) => fn()); -jest.doMock('../../../elasticsearch/client/retry_call_cluster', () => ({ +jest.doMock('../../../opensearch/client/retry_call_cluster', () => ({ migrationRetryCallCluster: migrationRetryCallClusterMock, })); diff --git a/src/core/server/saved_objects/migrations/core/migration_es_client.test.ts b/src/core/server/saved_objects/migrations/core/migration_opensearch_client.test.ts similarity index 59% rename from src/core/server/saved_objects/migrations/core/migration_es_client.test.ts rename to src/core/server/saved_objects/migrations/core/migration_opensearch_client.test.ts index a6da62095060..7015f4c60636 100644 --- a/src/core/server/saved_objects/migrations/core/migration_es_client.test.ts +++ b/src/core/server/saved_objects/migrations/core/migration_opensearch_client.test.ts @@ -16,48 +16,48 @@ * specific language governing permissions and limitations * under the License. */ -import { migrationRetryCallClusterMock } from './migration_es_client.test.mock'; +import { migrationRetryCallClusterMock } from './migration_opensearch_client.test.mock'; -import { createMigrationEsClient, MigrationEsClient } from './migration_es_client'; -import { elasticsearchClientMock } from '../../../elasticsearch/client/mocks'; +import { createMigrationOpenSearchClient, MigrationOpenSearchClient } from './migration_opensearch_client'; +import { opensearchClientMock } from '../../../opensearch/client/mocks'; import { loggerMock } from '../../../logging/logger.mock'; import { SavedObjectsErrorHelpers } from '../../service/lib/errors'; -describe('MigrationEsClient', () => { - let client: ReturnType; - let migrationEsClient: MigrationEsClient; +describe('MigrationOpenSearchClient', () => { + let client: ReturnType; + let migrationOpenSearchClient: MigrationOpenSearchClient; beforeEach(() => { - client = elasticsearchClientMock.createElasticsearchClient(); - migrationEsClient = createMigrationEsClient(client, loggerMock.create()); + client = opensearchClientMock.createOpenSearchClient(); + migrationOpenSearchClient = createMigrationOpenSearchClient(client, loggerMock.create()); migrationRetryCallClusterMock.mockClear(); }); - it('delegates call to ES client method', async () => { - expect(migrationEsClient.bulk).toStrictEqual(expect.any(Function)); - await migrationEsClient.bulk({ body: [] }); + it('delegates call to OpenSearch client method', async () => { + expect(migrationOpenSearchClient.bulk).toStrictEqual(expect.any(Function)); + await migrationOpenSearchClient.bulk({ body: [] }); expect(client.bulk).toHaveBeenCalledTimes(1); }); it('wraps a method call in migrationRetryCallClusterMock', async () => { - await migrationEsClient.bulk({ body: [] }); + await migrationOpenSearchClient.bulk({ body: [] }); expect(migrationRetryCallClusterMock).toHaveBeenCalledTimes(1); }); it('sets maxRetries: 0 to delegate retry logic to migrationRetryCallCluster', async () => { - expect(migrationEsClient.bulk).toStrictEqual(expect.any(Function)); - await migrationEsClient.bulk({ body: [] }); + expect(migrationOpenSearchClient.bulk).toStrictEqual(expect.any(Function)); + await migrationOpenSearchClient.bulk({ body: [] }); expect(client.bulk).toHaveBeenCalledWith( expect.any(Object), expect.objectContaining({ maxRetries: 0 }) ); }); - it('do not transform elasticsearch errors into saved objects errors', async () => { + it('do not transform opensearch errors into saved objects errors', async () => { expect.assertions(1); client.bulk = jest.fn().mockRejectedValue(new Error('reason')); try { - await migrationEsClient.bulk({ body: [] }); + await migrationOpenSearchClient.bulk({ body: [] }); } catch (e) { expect(SavedObjectsErrorHelpers.isSavedObjectsClientError(e)).toBe(false); } diff --git a/src/core/server/saved_objects/migrations/core/migration_es_client.ts b/src/core/server/saved_objects/migrations/core/migration_opensearch_client.ts similarity index 58% rename from src/core/server/saved_objects/migrations/core/migration_es_client.ts rename to src/core/server/saved_objects/migrations/core/migration_opensearch_client.ts index e8482e6352a8..16db03f52a61 100644 --- a/src/core/server/saved_objects/migrations/core/migration_es_client.ts +++ b/src/core/server/saved_objects/migrations/core/migration_opensearch_client.ts @@ -20,8 +20,8 @@ import type { TransportRequestOptions } from '@elastic/elasticsearch/lib/Transpo import { get } from 'lodash'; import { set } from '@elastic/safer-lodash-set'; -import { ElasticsearchClient } from '../../../elasticsearch'; -import { migrationRetryCallCluster } from '../../../elasticsearch/client/retry_call_cluster'; +import { OpenSearchClient } from '../../../opensearch'; +import { migrationRetryCallCluster } from '../../../opensearch/client/retry_call_cluster'; import { Logger } from '../../../logging'; const methods = [ @@ -44,40 +44,40 @@ const methods = [ type MethodName = typeof methods[number]; -export interface MigrationEsClient { - bulk: ElasticsearchClient['bulk']; +export interface MigrationOpenSearchClient { + bulk: OpenSearchClient['bulk']; cat: { - templates: ElasticsearchClient['cat']['templates']; + templates: OpenSearchClient['cat']['templates']; }; - clearScroll: ElasticsearchClient['clearScroll']; - count: ElasticsearchClient['count']; + clearScroll: OpenSearchClient['clearScroll']; + count: OpenSearchClient['count']; indices: { - create: ElasticsearchClient['indices']['create']; - delete: ElasticsearchClient['indices']['delete']; - deleteTemplate: ElasticsearchClient['indices']['deleteTemplate']; - get: ElasticsearchClient['indices']['get']; - getAlias: ElasticsearchClient['indices']['getAlias']; - refresh: ElasticsearchClient['indices']['refresh']; - updateAliases: ElasticsearchClient['indices']['updateAliases']; + create: OpenSearchClient['indices']['create']; + delete: OpenSearchClient['indices']['delete']; + deleteTemplate: OpenSearchClient['indices']['deleteTemplate']; + get: OpenSearchClient['indices']['get']; + getAlias: OpenSearchClient['indices']['getAlias']; + refresh: OpenSearchClient['indices']['refresh']; + updateAliases: OpenSearchClient['indices']['updateAliases']; }; - reindex: ElasticsearchClient['reindex']; - search: ElasticsearchClient['search']; - scroll: ElasticsearchClient['scroll']; + reindex: OpenSearchClient['reindex']; + search: OpenSearchClient['search']; + scroll: OpenSearchClient['scroll']; tasks: { - get: ElasticsearchClient['tasks']['get']; + get: OpenSearchClient['tasks']['get']; }; } -export function createMigrationEsClient( - client: ElasticsearchClient, +export function createMigrationOpenSearchClient( + client: OpenSearchClient, log: Logger, delay?: number -): MigrationEsClient { - return methods.reduce((acc: MigrationEsClient, key: MethodName) => { +): MigrationOpenSearchClient { + return methods.reduce((acc: MigrationOpenSearchClient, key: MethodName) => { set(acc, key, async (params?: unknown, options?: TransportRequestOptions) => { const fn = get(client, key); if (!fn) { - throw new Error(`unknown ElasticsearchClient client method [${key}]`); + throw new Error(`unknown OpenSearchClient client method [${key}]`); } return await migrationRetryCallCluster( () => fn.call(client, params, { maxRetries: 0, ...options }), @@ -86,5 +86,5 @@ export function createMigrationEsClient( ); }); return acc; - }, {} as MigrationEsClient); + }, {} as MigrationOpenSearchClient); } diff --git a/src/core/server/saved_objects/migrations/core/elastic_index.test.ts b/src/core/server/saved_objects/migrations/core/opensearch_index.test.ts similarity index 88% rename from src/core/server/saved_objects/migrations/core/elastic_index.test.ts rename to src/core/server/saved_objects/migrations/core/opensearch_index.test.ts index 0b3ad1b6e3cc..aef3a3490450 100644 --- a/src/core/server/saved_objects/migrations/core/elastic_index.test.ts +++ b/src/core/server/saved_objects/migrations/core/opensearch_index.test.ts @@ -18,36 +18,36 @@ */ import _ from 'lodash'; -import { elasticsearchClientMock } from '../../../elasticsearch/client/mocks'; -import * as Index from './elastic_index'; +import { opensearchClientMock } from '../../../opensearch/client/mocks'; +import * as Index from './opensearch_index'; describe('ElasticIndex', () => { - let client: ReturnType; + let client: ReturnType; beforeEach(() => { - client = elasticsearchClientMock.createElasticsearchClient(); + client = opensearchClientMock.createOpenSearchClient(); }); describe('fetchInfo', () => { test('it handles 404', async () => { client.indices.get.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + opensearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) ); - const info = await Index.fetchInfo(client, '.kibana-test'); + const info = await Index.fetchInfo(client, '.opensearch-dashboards-test'); expect(info).toEqual({ aliases: {}, exists: false, - indexName: '.kibana-test', + indexName: '.opensearch-dashboards-test', mappings: { dynamic: 'strict', properties: {} }, }); - expect(client.indices.get).toHaveBeenCalledWith({ index: '.kibana-test' }, { ignore: [404] }); + expect(client.indices.get).toHaveBeenCalledWith({ index: '.opensearch-dashboards-test' }, { ignore: [404] }); }); test('fails if the index doc type is unsupported', async () => { client.indices.get.mockImplementation((params) => { const index = params!.index as string; - return elasticsearchClientMock.createSuccessTransportRequestPromise({ + return opensearchClientMock.createSuccessTransportRequestPromise({ [index]: { aliases: { foo: index }, mappings: { spock: { dynamic: 'strict', properties: { a: 'b' } } }, @@ -63,7 +63,7 @@ describe('ElasticIndex', () => { test('fails if there are multiple root types', async () => { client.indices.get.mockImplementation((params) => { const index = params!.index as string; - return elasticsearchClientMock.createSuccessTransportRequestPromise({ + return opensearchClientMock.createSuccessTransportRequestPromise({ [index]: { aliases: { foo: index }, mappings: { @@ -82,7 +82,7 @@ describe('ElasticIndex', () => { test('decorates index info with exists and indexName', async () => { client.indices.get.mockImplementation((params) => { const index = params!.index as string; - return elasticsearchClientMock.createSuccessTransportRequestPromise({ + return opensearchClientMock.createSuccessTransportRequestPromise({ [index]: { aliases: { foo: index }, mappings: { dynamic: 'strict', properties: { a: 'b' } }, @@ -132,7 +132,7 @@ describe('ElasticIndex', () => { describe('claimAlias', () => { test('handles unaliased indices', async () => { client.indices.getAlias.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + opensearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) ); await Index.claimAlias(client, '.hola-42', '.hola'); @@ -155,7 +155,7 @@ describe('ElasticIndex', () => { test('removes existing alias', async () => { client.indices.getAlias.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ '.my-fanci-index': '.muchacha', }) ); @@ -178,7 +178,7 @@ describe('ElasticIndex', () => { test('allows custom alias actions', async () => { client.indices.getAlias.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ '.my-fanci-index': '.muchacha', }) ); @@ -206,15 +206,15 @@ describe('ElasticIndex', () => { describe('convertToAlias', () => { test('it creates the destination index, then reindexes to it', async () => { client.indices.getAlias.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ '.my-fanci-index': '.muchacha', }) ); client.reindex.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ task: 'abc' }) + opensearchClientMock.createSuccessTransportRequestPromise({ task: 'abc' }) ); client.tasks.get.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ completed: true }) + opensearchClientMock.createSuccessTransportRequestPromise({ completed: true }) ); const info = { @@ -280,15 +280,15 @@ describe('ElasticIndex', () => { test('throws error if re-index task fails', async () => { client.indices.getAlias.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ '.my-fanci-index': '.muchacha', }) ); client.reindex.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ task: 'abc' }) + opensearchClientMock.createSuccessTransportRequestPromise({ task: 'abc' }) ); client.tasks.get.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ completed: true, error: { type: 'search_phase_execution_exception', @@ -341,7 +341,7 @@ describe('ElasticIndex', () => { describe('write', () => { test('writes documents in bulk to the index', async () => { client.bulk.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ items: [] }) + opensearchClientMock.createSuccessTransportRequestPromise({ items: [] }) ); const index = '.myalias'; @@ -376,7 +376,7 @@ describe('ElasticIndex', () => { test('fails if any document fails', async () => { client.bulk.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ items: [{ index: { error: { type: 'shazm', reason: 'dern' } } }], }) ); @@ -424,7 +424,7 @@ describe('ElasticIndex', () => { ]; client.search = jest.fn().mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ _scroll_id: 'x', _shards: { success: 1, total: 1 }, hits: { hits: _.cloneDeep(batch1) }, @@ -433,14 +433,14 @@ describe('ElasticIndex', () => { client.scroll = jest .fn() .mockReturnValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ _scroll_id: 'y', _shards: { success: 1, total: 1 }, hits: { hits: _.cloneDeep(batch2) }, }) ) .mockReturnValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ _scroll_id: 'z', _shards: { success: 1, total: 1 }, hits: { hits: [] }, @@ -486,14 +486,14 @@ describe('ElasticIndex', () => { ]; client.search = jest.fn().mockReturnValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ _scroll_id: 'x', _shards: { success: 1, total: 1 }, hits: { hits: _.cloneDeep(batch) }, }) ); client.scroll = jest.fn().mockReturnValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ _scroll_id: 'z', _shards: { success: 1, total: 1 }, hits: { hits: [] }, @@ -512,7 +512,7 @@ describe('ElasticIndex', () => { const index = '.myalias'; client.search = jest.fn().mockReturnValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ _shards: { successful: 1, total: 2 }, }) ); @@ -540,13 +540,13 @@ describe('ElasticIndex', () => { ]; client.search = jest.fn().mockReturnValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ _scroll_id: 'x', hits: { hits: _.cloneDeep(batch) }, }) ); client.scroll = jest.fn().mockReturnValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ _scroll_id: 'z', hits: { hits: [] }, }) @@ -570,12 +570,12 @@ describe('ElasticIndex', () => { migrations, }: any) { client.indices.get = jest.fn().mockReturnValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ [index]: { mappings }, }) ); client.count = jest.fn().mockReturnValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ count, _shards: { success: 1, total: 1 }, }) diff --git a/src/core/server/saved_objects/migrations/core/elastic_index.ts b/src/core/server/saved_objects/migrations/core/opensearch_index.ts similarity index 89% rename from src/core/server/saved_objects/migrations/core/elastic_index.ts rename to src/core/server/saved_objects/migrations/core/opensearch_index.ts index d5093bfd8dc4..ce2bb7011bdc 100644 --- a/src/core/server/saved_objects/migrations/core/elastic_index.ts +++ b/src/core/server/saved_objects/migrations/core/opensearch_index.ts @@ -19,12 +19,12 @@ /* * This module contains various functions for querying and manipulating - * elasticsearch indices. + * opensearch indices. */ import _ from 'lodash'; -import { MigrationEsClient } from './migration_es_client'; -import { CountResponse, SearchResponse } from '../../../elasticsearch'; +import { MigrationOpenSearchClient } from './migration_opensearch_client'; +import { CountResponse, SearchResponse } from '../../../opensearch'; import { IndexMapping } from '../../mappings'; import { SavedObjectsMigrationVersion } from '../../types'; import { AliasAction, RawDoc, ShardsInfo } from './call_cluster'; @@ -43,7 +43,7 @@ export interface FullIndexInfo { * A slight enhancement to indices.get, that adds indexName, and validates that the * index mappings are somewhat what we expect. */ -export async function fetchInfo(client: MigrationEsClient, index: string): Promise { +export async function fetchInfo(client: MigrationOpenSearchClient, index: string): Promise { const { body, statusCode } = await client.indices.get({ index }, { ignore: [404] }); if (statusCode === 404) { @@ -62,7 +62,7 @@ export async function fetchInfo(client: MigrationEsClient, index: string): Promi /** * Creates a reader function that serves up batches of documents from the index. We aren't using - * an async generator, as that feature currently breaks Kibana's tooling. + * an async generator, as that feature currently breaks OpenSearchDashboards's tooling. * * @param {CallCluster} callCluster - The elastic search connection * @param {string} - The index to be read from @@ -71,7 +71,7 @@ export async function fetchInfo(client: MigrationEsClient, index: string): Promi * @prop {string} scrollDuration - The scroll duration used for scrolling through the index */ export function reader( - client: MigrationEsClient, + client: MigrationOpenSearchClient, index: string, { batchSize = 10, scrollDuration = '15m' }: { batchSize: number; scrollDuration: string } ) { @@ -114,7 +114,7 @@ export function reader( * @param {string} index * @param {RawDoc[]} docs */ -export async function write(client: MigrationEsClient, index: string, docs: RawDoc[]) { +export async function write(client: MigrationOpenSearchClient, index: string, docs: RawDoc[]) { const { body } = await client.bulk({ body: docs.reduce((acc: object[], doc: RawDoc) => { acc.push({ @@ -155,7 +155,7 @@ export async function write(client: MigrationEsClient, index: string, docs: RawD * @param {SavedObjectsMigrationVersion} migrationVersion - The latest versions of the migrations */ export async function migrationsUpToDate( - client: MigrationEsClient, + client: MigrationOpenSearchClient, index: string, migrationVersion: SavedObjectsMigrationVersion, retryCount: number = 10 @@ -210,7 +210,7 @@ export async function migrationsUpToDate( } export async function createIndex( - client: MigrationEsClient, + client: MigrationOpenSearchClient, index: string, mappings?: IndexMapping ) { @@ -220,7 +220,7 @@ export async function createIndex( }); } -export async function deleteIndex(client: MigrationEsClient, index: string) { +export async function deleteIndex(client: MigrationOpenSearchClient, index: string) { await client.indices.delete({ index }); } @@ -229,12 +229,12 @@ export async function deleteIndex(client: MigrationEsClient, index: string) { * is a concrete index. This function will reindex `alias` into a new index, delete the `alias` * index, and then create an alias `alias` that points to the new index. * - * @param {CallCluster} callCluster - The connection to ElasticSearch + * @param {CallCluster} callCluster - The connection to OpenSearch * @param {FullIndexInfo} info - Information about the mappings and name of the new index * @param {string} alias - The name of the index being converted to an alias */ export async function convertToAlias( - client: MigrationEsClient, + client: MigrationOpenSearchClient, info: FullIndexInfo, alias: string, batchSize: number, @@ -261,7 +261,7 @@ export async function convertToAlias( * @param {AliasAction[]} aliasActions - Optional actions to be added to the updateAliases call */ export async function claimAlias( - client: MigrationEsClient, + client: MigrationOpenSearchClient, index: string, alias: string, aliasActions: AliasAction[] = [] @@ -281,10 +281,10 @@ export async function claimAlias( /** * This is a rough check to ensure that the index being migrated satisfies at least - * some rudimentary expectations. Past Kibana indices had multiple root documents, etc + * some rudimentary expectations. Past OpenSearch Dashboards indices had multiple root documents, etc * and the migration system does not (yet?) handle those indices. They need to be upgraded * via v5 -> v6 upgrade tools first. This file contains index-agnostic logic, and this - * check is itself index-agnostic, though the error hint is a bit Kibana specific. + * check is itself index-agnostic, though the error hint is a bit OpenSearch Dashboards specific. * * @param {FullIndexInfo} indexInfo */ @@ -294,7 +294,7 @@ function assertIsSupportedIndex(indexInfo: FullIndexInfo) { if (!isV7Index) { throw new Error( - `Index ${indexInfo.indexName} belongs to a version of Kibana ` + + `Index ${indexInfo.indexName} belongs to a version of OpenSearch Dashboards ` + `that cannot be automatically migrated. Reset it or use the X-Pack upgrade assistant.` ); } @@ -318,7 +318,7 @@ function assertResponseIncludeAllShards({ _shards }: { _shards: ShardsInfo }) { if (failed > 0) { throw new Error( `Re-index failed :: ${failed} of ${_shards.total} shards failed. ` + - `Check Elasticsearch cluster health for more information.` + `Check OpenSearch cluster health for more information.` ); } } @@ -327,14 +327,14 @@ function assertResponseIncludeAllShards({ _shards }: { _shards: ShardsInfo }) { * Reindexes from source to dest, polling for the reindex completion. */ async function reindex( - client: MigrationEsClient, + client: MigrationOpenSearchClient, source: string, dest: string, batchSize: number, script?: string ) { // We poll instead of having the request wait for completion, as for large indices, - // the request times out on the Elasticsearch side of things. We have a relatively tight + // the request times out on the OpenSearch side of things. We have a relatively tight // polling interval, as the request is fairly efficent, and we don't // want to block index migrations for too long on this. const pollInterval = 250; diff --git a/src/core/server/saved_objects/migrations/index.ts b/src/core/server/saved_objects/migrations/index.ts index 8ddaed3707eb..7fdbc427499a 100644 --- a/src/core/server/saved_objects/migrations/index.ts +++ b/src/core/server/saved_objects/migrations/index.ts @@ -18,7 +18,7 @@ */ export { MigrationResult } from './core'; -export { KibanaMigrator, IKibanaMigrator } from './kibana'; +export { OpenSearchDashboardsMigrator, IOpenSearchDashboardsMigrator } from './opensearch-dashboards'; export { SavedObjectMigrationFn, SavedObjectMigrationMap, diff --git a/src/core/server/saved_objects/migrations/kibana/__mocks__/kibana_migrator.ts b/src/core/server/saved_objects/migrations/opensearch-dashboards/__mocks__/opensearch_dashboards_migrator.ts similarity index 69% rename from src/core/server/saved_objects/migrations/kibana/__mocks__/kibana_migrator.ts rename to src/core/server/saved_objects/migrations/opensearch-dashboards/__mocks__/opensearch_dashboards_migrator.ts index d9f745810412..441e01807eaf 100644 --- a/src/core/server/saved_objects/migrations/kibana/__mocks__/kibana_migrator.ts +++ b/src/core/server/saved_objects/migrations/opensearch-dashboards/__mocks__/opensearch_dashboards_migrator.ts @@ -17,10 +17,10 @@ * under the License. */ -import { mockKibanaMigrator } from '../kibana_migrator.mock'; +import { mockOpenSearchDashboardsMigrator } from '../opensearch_dashboards_migrator.mock'; -export const mockKibanaMigratorInstance = mockKibanaMigrator.create(); +export const mockOpenSearchDashboardsMigratorInstance = mockOpenSearchDashboardsMigrator.create(); -const mockConstructor = jest.fn().mockImplementation(() => mockKibanaMigratorInstance); +const mockConstructor = jest.fn().mockImplementation(() => mockOpenSearchDashboardsMigratorInstance); -export const KibanaMigrator = mockConstructor; +export const OpenSearchDashboardsMigrator = mockConstructor; diff --git a/src/core/server/saved_objects/migrations/kibana/__snapshots__/kibana_migrator.test.ts.snap b/src/core/server/saved_objects/migrations/opensearch-dashboards/__snapshots__/opensearch_dashboards_migrator.test.ts.snap similarity index 100% rename from src/core/server/saved_objects/migrations/kibana/__snapshots__/kibana_migrator.test.ts.snap rename to src/core/server/saved_objects/migrations/opensearch-dashboards/__snapshots__/opensearch_dashboards_migrator.test.ts.snap diff --git a/src/core/server/saved_objects/migrations/kibana/index.ts b/src/core/server/saved_objects/migrations/opensearch-dashboards/index.ts similarity index 84% rename from src/core/server/saved_objects/migrations/kibana/index.ts rename to src/core/server/saved_objects/migrations/opensearch-dashboards/index.ts index df4751521ac5..5f79b90a54b5 100644 --- a/src/core/server/saved_objects/migrations/kibana/index.ts +++ b/src/core/server/saved_objects/migrations/opensearch-dashboards/index.ts @@ -17,4 +17,4 @@ * under the License. */ -export { KibanaMigrator, IKibanaMigrator, KibanaMigratorStatus } from './kibana_migrator'; +export { OpenSearchDashboardsMigrator, IOpenSearchDashboardsMigrator, OpenSearchDashboardsMigratorStatus } from './opensearch_dashboards_migrator'; diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.mock.ts b/src/core/server/saved_objects/migrations/opensearch-dashboards/opensearch_dashboards_migrator.mock.ts similarity index 76% rename from src/core/server/saved_objects/migrations/kibana/kibana_migrator.mock.ts rename to src/core/server/saved_objects/migrations/opensearch-dashboards/opensearch_dashboards_migrator.mock.ts index 23d8c4518d3a..b64b68ce3c41 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.mock.ts +++ b/src/core/server/saved_objects/migrations/opensearch-dashboards/opensearch_dashboards_migrator.mock.ts @@ -16,11 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -import type { PublicMethodsOf } from '@kbn/utility-types'; +import type { PublicMethodsOf } from '@osd/utility-types'; -import { KibanaMigrator, KibanaMigratorStatus } from './kibana_migrator'; +import { OpenSearchDashboardsMigrator, OpenSearchDashboardsMigratorStatus } from './opensearch_dashboards_migrator'; import { buildActiveMappings } from '../core'; -const { mergeTypes } = jest.requireActual('./kibana_migrator'); +const { mergeTypes } = jest.requireActual('./opensearch_dashboards_migrator'); import { SavedObjectsType } from '../../types'; import { BehaviorSubject } from 'rxjs'; @@ -45,19 +45,19 @@ const createMigrator = ( types: SavedObjectsType[]; } = { types: defaultSavedObjectTypes } ) => { - const mockMigrator: jest.Mocked> = { + const mockMigrator: jest.Mocked> = { runMigrations: jest.fn(), getActiveMappings: jest.fn(), migrateDocument: jest.fn(), getStatus$: jest.fn( () => - new BehaviorSubject({ + new BehaviorSubject({ status: 'completed', result: [ { status: 'migrated', - destIndex: '.test-kibana_2', - sourceIndex: '.test-kibana_1', + destIndex: '.test-opensearch-dashboards_2', + sourceIndex: '.test-opensearch-dashboards_1', elapsedMs: 10, }, ], @@ -70,6 +70,6 @@ const createMigrator = ( return mockMigrator; }; -export const mockKibanaMigrator = { +export const mockOpenSearchDashboardsMigrator = { create: createMigrator, }; diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts b/src/core/server/saved_objects/migrations/opensearch-dashboards/opensearch_dashboards_migrator.test.ts similarity index 76% rename from src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts rename to src/core/server/saved_objects/migrations/opensearch-dashboards/opensearch_dashboards_migrator.test.ts index 7eb2cfefe462..0dac31990bd1 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/opensearch-dashboards/opensearch_dashboards_migrator.test.ts @@ -18,8 +18,8 @@ */ import { take } from 'rxjs/operators'; -import { elasticsearchClientMock } from '../../../elasticsearch/client/mocks'; -import { KibanaMigratorOptions, KibanaMigrator } from './kibana_migrator'; +import { opensearchClientMock } from '../../../opensearch/client/mocks'; +import { OpenSearchDashboardsMigratorOptions, OpenSearchDashboardsMigrator } from './opensearch_dashboards_migrator'; import { loggingSystemMock } from '../../../logging/logging_system.mock'; import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { SavedObjectsType } from '../../types'; @@ -39,7 +39,7 @@ const createRegistry = (types: Array>) => { return registry; }; -describe('KibanaMigrator', () => { +describe('OpenSearchDashboardsMigrator', () => { describe('getActiveMappings', () => { it('returns full index mappings w/ core properties', () => { const options = mockOptions(); @@ -59,7 +59,7 @@ describe('KibanaMigrator', () => { }, ]); - const mappings = new KibanaMigrator(options).getActiveMappings(); + const mappings = new OpenSearchDashboardsMigrator(options).getActiveMappings(); expect(mappings).toMatchSnapshot(); }); }); @@ -69,19 +69,19 @@ describe('KibanaMigrator', () => { const options = mockOptions(); options.client.cat.templates.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise( + opensearchClientMock.createSuccessTransportRequestPromise( { templates: [] }, { statusCode: 404 } ) ); options.client.indices.get.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + opensearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) ); options.client.indices.getAlias.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + opensearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) ); - const migrator = new KibanaMigrator(options); + const migrator = new OpenSearchDashboardsMigrator(options); await migrator.runMigrations(); await migrator.runMigrations(); @@ -93,19 +93,19 @@ describe('KibanaMigrator', () => { const options = mockOptions(); options.client.cat.templates.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise( + opensearchClientMock.createSuccessTransportRequestPromise( { templates: [] }, { statusCode: 404 } ) ); options.client.indices.get.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + opensearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) ); options.client.indices.getAlias.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + opensearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) ); - const migrator = new KibanaMigrator(options); + const migrator = new OpenSearchDashboardsMigrator(options); const migratorStatus = migrator.getStatus$().pipe(take(3)).toPromise(); await migrator.runMigrations(); const { status, result } = await migratorStatus; @@ -126,14 +126,14 @@ describe('KibanaMigrator', () => { }); }); -type MockedOptions = KibanaMigratorOptions & { - client: ReturnType; +type MockedOptions = OpenSearchDashboardsMigratorOptions & { + client: ReturnType; }; const mockOptions = () => { const options: MockedOptions = { logger: loggingSystemMock.create().get(), - kibanaVersion: '8.2.3', + opensearchDashboardsVersion: '8.2.3', typeRegistry: createRegistry([ { name: 'testtype', @@ -159,17 +159,17 @@ const mockOptions = () => { migrations: {}, }, ]), - kibanaConfig: { + opensearchDashboardsConfig: { enabled: true, index: '.my-index', - } as KibanaMigratorOptions['kibanaConfig'], + } as OpenSearchDashboardsMigratorOptions['opensearchDashboardsConfig'], savedObjectsConfig: { batchSize: 20, pollInterval: 20000, scrollDuration: '10m', skip: false, }, - client: elasticsearchClientMock.createElasticsearchClient(), + client: opensearchClientMock.createOpenSearchClient(), }; return options; }; diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts b/src/core/server/saved_objects/migrations/opensearch-dashboards/opensearch_dashboards_migrator.ts similarity index 75% rename from src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts rename to src/core/server/saved_objects/migrations/opensearch-dashboards/opensearch_dashboards_migrator.ts index 18a385c6994b..46146326a7ef 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts +++ b/src/core/server/saved_objects/migrations/opensearch-dashboards/opensearch_dashboards_migrator.ts @@ -18,11 +18,11 @@ */ /* - * This file contains the logic for managing the Kibana index version + * This file contains the logic for managing the OpenSearch Dashboards index version * (the shape of the mappings and documents in the index). */ -import { KibanaConfigType } from 'src/core/server/kibana_config'; +import { OpenSearchDashboardsConfigType } from 'src/core/server/opensearch_dashboards_config'; import { BehaviorSubject } from 'rxjs'; import { Logger } from '../../../logging'; @@ -30,66 +30,66 @@ import { IndexMapping, SavedObjectsTypeMappingDefinitions } from '../../mappings import { SavedObjectUnsanitizedDoc, SavedObjectsSerializer } from '../../serialization'; import { buildActiveMappings, IndexMigrator, MigrationResult, MigrationStatus } from '../core'; import { DocumentMigrator, VersionedTransformer } from '../core/document_migrator'; -import { MigrationEsClient } from '../core/'; +import { MigrationOpenSearchClient } from '../core/'; import { createIndexMap } from '../core/build_index_map'; import { SavedObjectsMigrationConfigType } from '../../saved_objects_config'; import { ISavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { SavedObjectsType } from '../../types'; -export interface KibanaMigratorOptions { - client: MigrationEsClient; +export interface OpenSearchDashboardsMigratorOptions { + client: MigrationOpenSearchClient; typeRegistry: ISavedObjectTypeRegistry; savedObjectsConfig: SavedObjectsMigrationConfigType; - kibanaConfig: KibanaConfigType; - kibanaVersion: string; + opensearchDashboardsConfig: OpenSearchDashboardsConfigType; + opensearchDashboardsVersion: string; logger: Logger; } -export type IKibanaMigrator = Pick; +export type IOpenSearchDashboardsMigrator = Pick; -export interface KibanaMigratorStatus { +export interface OpenSearchDashboardsMigratorStatus { status: MigrationStatus; result?: MigrationResult[]; } /** - * Manages the shape of mappings and documents in the Kibana index. + * Manages the shape of mappings and documents in the OpenSearch Dashboards index. */ -export class KibanaMigrator { - private readonly client: MigrationEsClient; +export class OpenSearchDashboardsMigrator { + private readonly client: MigrationOpenSearchClient; private readonly savedObjectsConfig: SavedObjectsMigrationConfigType; private readonly documentMigrator: VersionedTransformer; - private readonly kibanaConfig: KibanaConfigType; + private readonly opensearchDashboardsConfig: OpenSearchDashboardsConfigType; private readonly log: Logger; private readonly mappingProperties: SavedObjectsTypeMappingDefinitions; private readonly typeRegistry: ISavedObjectTypeRegistry; private readonly serializer: SavedObjectsSerializer; private migrationResult?: Promise; - private readonly status$ = new BehaviorSubject({ + private readonly status$ = new BehaviorSubject({ status: 'waiting', }); private readonly activeMappings: IndexMapping; /** - * Creates an instance of KibanaMigrator. + * Creates an instance of OpenSearchDashboardsMigrator. */ constructor({ client, typeRegistry, - kibanaConfig, + opensearchDashboardsConfig, savedObjectsConfig, - kibanaVersion, + opensearchDashboardsVersion, logger, - }: KibanaMigratorOptions) { + }: OpenSearchDashboardsMigratorOptions) { this.client = client; - this.kibanaConfig = kibanaConfig; + this.opensearchDashboardsConfig = opensearchDashboardsConfig; this.savedObjectsConfig = savedObjectsConfig; this.typeRegistry = typeRegistry; this.serializer = new SavedObjectsSerializer(this.typeRegistry); this.mappingProperties = mergeTypes(this.typeRegistry.getAllTypes()); this.log = logger; this.documentMigrator = new DocumentMigrator({ - kibanaVersion, + opensearchDashboardsVersion, typeRegistry, log: this.log, }); @@ -99,13 +99,13 @@ export class KibanaMigrator { } /** - * Migrates the mappings and documents in the Kibana index. By default, this will run only + * Migrates the mappings and documents in the OpenSearch Dashboards index. By default, this will run only * once and subsequent calls will return the result of the original call. * * @param rerun - If true, method will run a new migration when called again instead of * returning the result of the initial migration. This should only be used when factors external - * to Kibana itself alter the kibana index causing the saved objects mappings or data to change - * after the Kibana server performed the initial migration. + * to OpenSearch Dashboards itself alter the .opensearch-dashboards index causing the saved objects mappings or data to change + * after the OpenSearch Dashboards server performed the initial migration. * * @remarks When the `rerun` parameter is set to true, no checks are performed to ensure that no migration * is currently running. Chained or concurrent calls to `runMigrations({ rerun: true })` can lead to @@ -114,13 +114,13 @@ export class KibanaMigrator { * * @returns - A promise which resolves once all migrations have been applied. * The promise resolves with an array of migration statuses, one for each - * elasticsearch index which was migrated. + * opensearch index which was migrated. */ public runMigrations({ rerun = false }: { rerun?: boolean } = {}): Promise< Array<{ status: string }> > { if (this.migrationResult === undefined || rerun) { - // Reruns are only used by CI / EsArchiver. Publishing status updates on reruns results in slowing down CI + // Reruns are only used by CI / OpenSearchArchiver. Publishing status updates on reruns results in slowing down CI // unnecessarily, so we skip it in this case. if (!rerun) { this.status$.next({ status: 'running' }); @@ -143,9 +143,9 @@ export class KibanaMigrator { } private runMigrationsInternal() { - const kibanaIndexName = this.kibanaConfig.index; + const opensearchDashboardsIndexName = this.opensearchDashboardsConfig.index; const indexMap = createIndexMap({ - kibanaIndexName, + opensearchDashboardsIndexName, indexMap: this.mappingProperties, registry: this.typeRegistry, }); @@ -161,9 +161,9 @@ export class KibanaMigrator { pollInterval: this.savedObjectsConfig.pollInterval, scrollDuration: this.savedObjectsConfig.scrollDuration, serializer: this.serializer, - // Only necessary for the migrator of the kibana index. + // Only necessary for the migrator of the opensearch-dashboards index. obsoleteIndexTemplatePattern: - index === kibanaIndexName ? 'kibana_index_template*' : undefined, + index === opensearchDashboardsIndexName ? 'opensearch_dashboards_index_template*' : undefined, convertToAliasScript: indexMap[index].script, }); }); @@ -172,7 +172,7 @@ export class KibanaMigrator { } /** - * Gets all the index mappings defined by Kibana's enabled plugins. + * Gets all the index mappings defined by OpenSearchDashboards's enabled plugins. * */ public getActiveMappings(): IndexMapping { diff --git a/src/core/server/saved_objects/es_query.js b/src/core/server/saved_objects/opensearch_query.js similarity index 87% rename from src/core/server/saved_objects/es_query.js rename to src/core/server/saved_objects/opensearch_query.js index 68d582e3cae0..9bc6407df62e 100644 --- a/src/core/server/saved_objects/es_query.js +++ b/src/core/server/saved_objects/opensearch_query.js @@ -17,5 +17,5 @@ * under the License. */ // a temporary file to remove circular deps in TS code between platform & data plugin -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -export { esKuery } from '../../../plugins/data/server'; +// eslint-disable-next-line @osd/eslint/no-restricted-paths +export { opensearchKuery } from '../../../plugins/data/server'; diff --git a/src/core/server/saved_objects/routes/bulk_create.ts b/src/core/server/saved_objects/routes/bulk_create.ts index b048c5d8f99b..a9c1f3779a34 100644 --- a/src/core/server/saved_objects/routes/bulk_create.ts +++ b/src/core/server/saved_objects/routes/bulk_create.ts @@ -17,7 +17,7 @@ * under the License. */ -import { schema } from '@kbn/config-schema'; +import { schema } from '@osd/config-schema'; import { IRouter } from '../../http'; export const registerBulkCreateRoute = (router: IRouter) => { diff --git a/src/core/server/saved_objects/routes/bulk_get.ts b/src/core/server/saved_objects/routes/bulk_get.ts index 067388dcf922..94c04a8bb149 100644 --- a/src/core/server/saved_objects/routes/bulk_get.ts +++ b/src/core/server/saved_objects/routes/bulk_get.ts @@ -17,7 +17,7 @@ * under the License. */ -import { schema } from '@kbn/config-schema'; +import { schema } from '@osd/config-schema'; import { IRouter } from '../../http'; export const registerBulkGetRoute = (router: IRouter) => { diff --git a/src/core/server/saved_objects/routes/bulk_update.ts b/src/core/server/saved_objects/routes/bulk_update.ts index 882213644146..b55342267dcc 100644 --- a/src/core/server/saved_objects/routes/bulk_update.ts +++ b/src/core/server/saved_objects/routes/bulk_update.ts @@ -17,7 +17,7 @@ * under the License. */ -import { schema } from '@kbn/config-schema'; +import { schema } from '@osd/config-schema'; import { IRouter } from '../../http'; export const registerBulkUpdateRoute = (router: IRouter) => { diff --git a/src/core/server/saved_objects/routes/create.ts b/src/core/server/saved_objects/routes/create.ts index 816315705a37..c84d951dd3ea 100644 --- a/src/core/server/saved_objects/routes/create.ts +++ b/src/core/server/saved_objects/routes/create.ts @@ -17,7 +17,7 @@ * under the License. */ -import { schema } from '@kbn/config-schema'; +import { schema } from '@osd/config-schema'; import { IRouter } from '../../http'; export const registerCreateRoute = (router: IRouter) => { diff --git a/src/core/server/saved_objects/routes/delete.ts b/src/core/server/saved_objects/routes/delete.ts index d99397d2a050..73bdd234251e 100644 --- a/src/core/server/saved_objects/routes/delete.ts +++ b/src/core/server/saved_objects/routes/delete.ts @@ -17,7 +17,7 @@ * under the License. */ -import { schema } from '@kbn/config-schema'; +import { schema } from '@osd/config-schema'; import { IRouter } from '../../http'; export const registerDeleteRoute = (router: IRouter) => { diff --git a/src/core/server/saved_objects/routes/export.ts b/src/core/server/saved_objects/routes/export.ts index 35a65d8d9651..228891bbf135 100644 --- a/src/core/server/saved_objects/routes/export.ts +++ b/src/core/server/saved_objects/routes/export.ts @@ -17,7 +17,7 @@ * under the License. */ -import { schema } from '@kbn/config-schema'; +import { schema } from '@osd/config-schema'; import stringify from 'json-stable-stringify'; import { createPromiseFromStreams, createMapStream, createConcatStream } from '../../utils/streams'; import { IRouter } from '../../http'; diff --git a/src/core/server/saved_objects/routes/find.ts b/src/core/server/saved_objects/routes/find.ts index 6313a95b1fef..a2e0a989192b 100644 --- a/src/core/server/saved_objects/routes/find.ts +++ b/src/core/server/saved_objects/routes/find.ts @@ -17,7 +17,7 @@ * under the License. */ -import { schema } from '@kbn/config-schema'; +import { schema } from '@osd/config-schema'; import { IRouter } from '../../http'; export const registerFindRoute = (router: IRouter) => { diff --git a/src/core/server/saved_objects/routes/get.ts b/src/core/server/saved_objects/routes/get.ts index f1b974c70b1a..7c2670370b16 100644 --- a/src/core/server/saved_objects/routes/get.ts +++ b/src/core/server/saved_objects/routes/get.ts @@ -17,7 +17,7 @@ * under the License. */ -import { schema } from '@kbn/config-schema'; +import { schema } from '@osd/config-schema'; import { IRouter } from '../../http'; export const registerGetRoute = (router: IRouter) => { diff --git a/src/core/server/saved_objects/routes/import.ts b/src/core/server/saved_objects/routes/import.ts index 291da5a5f018..0a94a728589b 100644 --- a/src/core/server/saved_objects/routes/import.ts +++ b/src/core/server/saved_objects/routes/import.ts @@ -19,7 +19,7 @@ import { Readable } from 'stream'; import { extname } from 'path'; -import { schema } from '@kbn/config-schema'; +import { schema } from '@osd/config-schema'; import { IRouter } from '../../http'; import { importSavedObjectsFromStream } from '../import'; import { SavedObjectConfig } from '../saved_objects_config'; diff --git a/src/core/server/saved_objects/routes/index.ts b/src/core/server/saved_objects/routes/index.ts index fd57a9f3059e..a0cc4125609c 100644 --- a/src/core/server/saved_objects/routes/index.ts +++ b/src/core/server/saved_objects/routes/index.ts @@ -20,7 +20,7 @@ import { InternalHttpServiceSetup } from '../../http'; import { Logger } from '../../logging'; import { SavedObjectConfig } from '../saved_objects_config'; -import { IKibanaMigrator } from '../migrations'; +import { IOpenSearchDashboardsMigrator } from '../migrations'; import { registerGetRoute } from './get'; import { registerCreateRoute } from './create'; import { registerDeleteRoute } from './delete'; @@ -44,7 +44,7 @@ export function registerRoutes({ http: InternalHttpServiceSetup; logger: Logger; config: SavedObjectConfig; - migratorPromise: Promise; + migratorPromise: Promise; }) { const router = http.createRouter('/api/saved_objects/'); diff --git a/src/core/server/saved_objects/routes/integration_tests/bulk_create.test.ts b/src/core/server/saved_objects/routes/integration_tests/bulk_create.test.ts index 3d455ff9d594..090448ff0f85 100644 --- a/src/core/server/saved_objects/routes/integration_tests/bulk_create.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/bulk_create.test.ts @@ -18,7 +18,7 @@ */ import supertest from 'supertest'; -import { UnwrapPromise } from '@kbn/utility-types'; +import { UnwrapPromise } from '@osd/utility-types'; import { registerBulkCreateRoute } from '../bulk_create'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; import { setupServer } from '../test_utils'; diff --git a/src/core/server/saved_objects/routes/integration_tests/bulk_get.test.ts b/src/core/server/saved_objects/routes/integration_tests/bulk_get.test.ts index 5deea94299d7..d7aa5fc52f5e 100644 --- a/src/core/server/saved_objects/routes/integration_tests/bulk_get.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/bulk_get.test.ts @@ -18,7 +18,7 @@ */ import supertest from 'supertest'; -import { UnwrapPromise } from '@kbn/utility-types'; +import { UnwrapPromise } from '@osd/utility-types'; import { registerBulkGetRoute } from '../bulk_get'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; import { setupServer } from '../test_utils'; diff --git a/src/core/server/saved_objects/routes/integration_tests/bulk_update.test.ts b/src/core/server/saved_objects/routes/integration_tests/bulk_update.test.ts index 45f310ecc3fa..2e64fc794417 100644 --- a/src/core/server/saved_objects/routes/integration_tests/bulk_update.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/bulk_update.test.ts @@ -18,7 +18,7 @@ */ import supertest from 'supertest'; -import { UnwrapPromise } from '@kbn/utility-types'; +import { UnwrapPromise } from '@osd/utility-types'; import { registerBulkUpdateRoute } from '../bulk_update'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; import { setupServer } from '../test_utils'; diff --git a/src/core/server/saved_objects/routes/integration_tests/create.test.ts b/src/core/server/saved_objects/routes/integration_tests/create.test.ts index 9e69c3dbc64e..fdcb627d3a04 100644 --- a/src/core/server/saved_objects/routes/integration_tests/create.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/create.test.ts @@ -18,7 +18,7 @@ */ import supertest from 'supertest'; -import { UnwrapPromise } from '@kbn/utility-types'; +import { UnwrapPromise } from '@osd/utility-types'; import { registerCreateRoute } from '../create'; import { savedObjectsClientMock } from '../../service/saved_objects_client.mock'; import { setupServer } from '../test_utils'; diff --git a/src/core/server/saved_objects/routes/integration_tests/delete.test.ts b/src/core/server/saved_objects/routes/integration_tests/delete.test.ts index ff8642a34929..4826cafe057c 100644 --- a/src/core/server/saved_objects/routes/integration_tests/delete.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/delete.test.ts @@ -18,7 +18,7 @@ */ import supertest from 'supertest'; -import { UnwrapPromise } from '@kbn/utility-types'; +import { UnwrapPromise } from '@osd/utility-types'; import { registerDeleteRoute } from '../delete'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; import { setupServer } from '../test_utils'; diff --git a/src/core/server/saved_objects/routes/integration_tests/export.test.ts b/src/core/server/saved_objects/routes/integration_tests/export.test.ts index d0fcd4b8b66d..57a99f85ec11 100644 --- a/src/core/server/saved_objects/routes/integration_tests/export.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/export.test.ts @@ -24,7 +24,7 @@ jest.mock('../../export', () => ({ import * as exportMock from '../../export'; import { createListStream } from '../../../utils/streams'; import supertest from 'supertest'; -import { UnwrapPromise } from '@kbn/utility-types'; +import { UnwrapPromise } from '@osd/utility-types'; import { SavedObjectConfig } from '../../saved_objects_config'; import { registerExportRoute } from '../export'; import { setupServer, createExportableType } from '../test_utils'; diff --git a/src/core/server/saved_objects/routes/integration_tests/find.test.ts b/src/core/server/saved_objects/routes/integration_tests/find.test.ts index 4fe9cbe415cd..91bda1971ce1 100644 --- a/src/core/server/saved_objects/routes/integration_tests/find.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/find.test.ts @@ -20,7 +20,7 @@ import supertest from 'supertest'; import querystring from 'querystring'; -import { UnwrapPromise } from '@kbn/utility-types'; +import { UnwrapPromise } from '@osd/utility-types'; import { registerFindRoute } from '../find'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; import { setupServer } from '../test_utils'; diff --git a/src/core/server/saved_objects/routes/integration_tests/import.test.ts b/src/core/server/saved_objects/routes/integration_tests/import.test.ts index 34cd449f3196..e2af84ff2a51 100644 --- a/src/core/server/saved_objects/routes/integration_tests/import.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/import.test.ts @@ -19,7 +19,7 @@ import { mockUuidv4 } from '../../import/__mocks__'; import supertest from 'supertest'; -import { UnwrapPromise } from '@kbn/utility-types'; +import { UnwrapPromise } from '@osd/utility-types'; import { registerImportRoute } from '../import'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; import { SavedObjectConfig } from '../../saved_objects_config'; diff --git a/src/core/server/saved_objects/routes/integration_tests/log_legacy_import.test.ts b/src/core/server/saved_objects/routes/integration_tests/log_legacy_import.test.ts index d86ac985d9da..18d1339720f0 100644 --- a/src/core/server/saved_objects/routes/integration_tests/log_legacy_import.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/log_legacy_import.test.ts @@ -18,7 +18,7 @@ */ import supertest from 'supertest'; -import { UnwrapPromise } from '@kbn/utility-types'; +import { UnwrapPromise } from '@osd/utility-types'; import { registerLogLegacyImportRoute } from '../log_legacy_import'; import { loggingSystemMock } from '../../../logging/logging_system.mock'; import { setupServer } from '../test_utils'; diff --git a/src/core/server/saved_objects/routes/integration_tests/migrate.test.mocks.ts b/src/core/server/saved_objects/routes/integration_tests/migrate.test.mocks.ts index 870d50426904..a9235ce8018e 100644 --- a/src/core/server/saved_objects/routes/integration_tests/migrate.test.mocks.ts +++ b/src/core/server/saved_objects/routes/integration_tests/migrate.test.mocks.ts @@ -17,10 +17,10 @@ * under the License. */ -import { mockKibanaMigrator } from '../../migrations/kibana/kibana_migrator.mock'; +import { mockOpenSearchDashboardsMigrator } from '../../migrations/kibana/opensearch_dashboards_migrator.mock'; -export const migratorInstanceMock = mockKibanaMigrator.create(); -export const KibanaMigratorMock = jest.fn().mockImplementation(() => migratorInstanceMock); -jest.doMock('../../migrations/kibana/kibana_migrator', () => ({ - KibanaMigrator: KibanaMigratorMock, +export const migratorInstanceMock = mockOpenSearchDashboardsMigrator.create(); +export const OpenSearchDashboardsMigratorMock = jest.fn().mockImplementation(() => migratorInstanceMock); +jest.doMock('../../migrations/opensearch-dashboards/opensearch_dashboards_migrator', () => ({ + OpenSearchDashboardsMigrator: OpenSearchDashboardsMigratorMock, })); diff --git a/src/core/server/saved_objects/routes/integration_tests/migrate.test.ts b/src/core/server/saved_objects/routes/integration_tests/migrate.test.ts index e003d564c1ea..4fb76a52c27b 100644 --- a/src/core/server/saved_objects/routes/integration_tests/migrate.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/migrate.test.ts @@ -18,13 +18,13 @@ */ import { migratorInstanceMock } from './migrate.test.mocks'; -import * as kbnTestServer from '../../../../test_helpers/kbn_server'; +import * as osdTestServer from '../../../../test_helpers/osd_server'; describe('SavedObjects /_migrate endpoint', () => { - let root: ReturnType; + let root: ReturnType; beforeEach(async () => { - root = kbnTestServer.createRoot({ migrations: { skip: true }, plugins: { initialize: false } }); + root = osdTestServer.createRoot({ migrations: { skip: true }, plugins: { initialize: false } }); await root.setup(); await root.start(); migratorInstanceMock.runMigrations.mockClear(); @@ -35,18 +35,18 @@ describe('SavedObjects /_migrate endpoint', () => { }); it('calls runMigrations on the migrator with rerun=true when accessed', async () => { - await kbnTestServer.request.post(root, '/internal/saved_objects/_migrate').send({}).expect(200); + await osdTestServer.request.post(root, '/internal/saved_objects/_migrate').send({}).expect(200); expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(1); expect(migratorInstanceMock.runMigrations).toHaveBeenCalledWith({ rerun: true }); }); it('calls runMigrations multiple time when multiple access', async () => { - await kbnTestServer.request.post(root, '/internal/saved_objects/_migrate').send({}).expect(200); + await osdTestServer.request.post(root, '/internal/saved_objects/_migrate').send({}).expect(200); expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(1); - await kbnTestServer.request.post(root, '/internal/saved_objects/_migrate').send({}).expect(200); + await osdTestServer.request.post(root, '/internal/saved_objects/_migrate').send({}).expect(200); expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(2); }); diff --git a/src/core/server/saved_objects/routes/integration_tests/resolve_import_errors.test.ts b/src/core/server/saved_objects/routes/integration_tests/resolve_import_errors.test.ts index 0e8fb0e563db..9452ca65411a 100644 --- a/src/core/server/saved_objects/routes/integration_tests/resolve_import_errors.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/resolve_import_errors.test.ts @@ -19,7 +19,7 @@ import { mockUuidv4 } from '../../import/__mocks__'; import supertest from 'supertest'; -import { UnwrapPromise } from '@kbn/utility-types'; +import { UnwrapPromise } from '@osd/utility-types'; import { registerResolveImportErrorsRoute } from '../resolve_import_errors'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; import { setupServer, createExportableType } from '../test_utils'; diff --git a/src/core/server/saved_objects/routes/integration_tests/update.test.ts b/src/core/server/saved_objects/routes/integration_tests/update.test.ts index dfccb651d72d..dc8a6fc6b0d9 100644 --- a/src/core/server/saved_objects/routes/integration_tests/update.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/update.test.ts @@ -18,7 +18,7 @@ */ import supertest from 'supertest'; -import { UnwrapPromise } from '@kbn/utility-types'; +import { UnwrapPromise } from '@osd/utility-types'; import { registerUpdateRoute } from '../update'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; import { setupServer } from '../test_utils'; diff --git a/src/core/server/saved_objects/routes/migrate.ts b/src/core/server/saved_objects/routes/migrate.ts index 69e99d10acd0..b57724aeec73 100644 --- a/src/core/server/saved_objects/routes/migrate.ts +++ b/src/core/server/saved_objects/routes/migrate.ts @@ -18,11 +18,11 @@ */ import { IRouter } from '../../http'; -import { IKibanaMigrator } from '../migrations'; +import { IOpenSearchDashboardsMigrator } from '../migrations'; export const registerMigrateRoute = ( router: IRouter, - migratorPromise: Promise + migratorPromise: Promise ) => { router.post( { diff --git a/src/core/server/saved_objects/routes/resolve_import_errors.ts b/src/core/server/saved_objects/routes/resolve_import_errors.ts index 03b4322b27cb..bcf31577a6f5 100644 --- a/src/core/server/saved_objects/routes/resolve_import_errors.ts +++ b/src/core/server/saved_objects/routes/resolve_import_errors.ts @@ -19,7 +19,7 @@ import { extname } from 'path'; import { Readable } from 'stream'; -import { schema } from '@kbn/config-schema'; +import { schema } from '@osd/config-schema'; import { IRouter } from '../../http'; import { resolveSavedObjectsImportErrors } from '../import'; import { SavedObjectConfig } from '../saved_objects_config'; diff --git a/src/core/server/saved_objects/routes/update.ts b/src/core/server/saved_objects/routes/update.ts index c0d94d362e64..85191e734b8a 100644 --- a/src/core/server/saved_objects/routes/update.ts +++ b/src/core/server/saved_objects/routes/update.ts @@ -17,7 +17,7 @@ * under the License. */ -import { schema } from '@kbn/config-schema'; +import { schema } from '@osd/config-schema'; import { IRouter } from '../../http'; export const registerUpdateRoute = (router: IRouter) => { diff --git a/src/core/server/saved_objects/saved_objects_config.ts b/src/core/server/saved_objects/saved_objects_config.ts index d292d021b470..1fb654680e8f 100644 --- a/src/core/server/saved_objects/saved_objects_config.ts +++ b/src/core/server/saved_objects/saved_objects_config.ts @@ -17,7 +17,7 @@ * under the License. */ -import { schema, TypeOf } from '@kbn/config-schema'; +import { schema, TypeOf } from '@osd/config-schema'; export type SavedObjectsMigrationConfigType = TypeOf; diff --git a/src/core/server/saved_objects/saved_objects_service.mock.ts b/src/core/server/saved_objects/saved_objects_service.mock.ts index c56cdabf6e4c..1ca07e4b387e 100644 --- a/src/core/server/saved_objects/saved_objects_service.mock.ts +++ b/src/core/server/saved_objects/saved_objects_service.mock.ts @@ -18,7 +18,7 @@ */ import { BehaviorSubject } from 'rxjs'; -import type { PublicMethodsOf } from '@kbn/utility-types'; +import type { PublicMethodsOf } from '@osd/utility-types'; import { SavedObjectsService, diff --git a/src/core/server/saved_objects/saved_objects_service.test.mocks.ts b/src/core/server/saved_objects/saved_objects_service.test.mocks.ts index 8c1cd3411203..ff547ea8d008 100644 --- a/src/core/server/saved_objects/saved_objects_service.test.mocks.ts +++ b/src/core/server/saved_objects/saved_objects_service.test.mocks.ts @@ -17,14 +17,14 @@ * under the License. */ -import { mockKibanaMigrator } from './migrations/kibana/kibana_migrator.mock'; +import { mockOpenSearchDashboardsMigrator } from './migrations/opensearch-dashboards/opensearch_dashboards_migrator.mock'; import { savedObjectsClientProviderMock } from './service/lib/scoped_client_provider.mock'; import { typeRegistryMock } from './saved_objects_type_registry.mock'; -export const migratorInstanceMock = mockKibanaMigrator.create(); -export const KibanaMigratorMock = jest.fn().mockImplementation(() => migratorInstanceMock); -jest.doMock('./migrations/kibana/kibana_migrator', () => ({ - KibanaMigrator: KibanaMigratorMock, +export const migratorInstanceMock = mockOpenSearchDashboardsMigrator.create(); +export const OpenSearchDashboardsMigratorMock = jest.fn().mockImplementation(() => migratorInstanceMock); +jest.doMock('./migrations/opensearch-dashboards/opensearch_dashboards_migrator', () => ({ + OpenSearchDashboardsMigrator: OpenSearchDashboardsMigratorMock, })); export const clientProviderInstanceMock = savedObjectsClientProviderMock.create(); diff --git a/src/core/server/saved_objects/saved_objects_service.test.ts b/src/core/server/saved_objects/saved_objects_service.test.ts index d6b30889eba5..6b4417b85b7d 100644 --- a/src/core/server/saved_objects/saved_objects_service.test.ts +++ b/src/core/server/saved_objects/saved_objects_service.test.ts @@ -18,25 +18,25 @@ */ import { - KibanaMigratorMock, + OpenSearchDashboardsMigratorMock, migratorInstanceMock, clientProviderInstanceMock, typeRegistryInstanceMock, } from './saved_objects_service.test.mocks'; import { BehaviorSubject } from 'rxjs'; -import { ByteSizeValue } from '@kbn/config-schema'; -import { errors as esErrors } from '@elastic/elasticsearch'; +import { ByteSizeValue } from '@osd/config-schema'; +import { errors as opensearchErrors } from '@elastic/elasticsearch'; import { SavedObjectsService } from './saved_objects_service'; import { mockCoreContext } from '../core_context.mock'; import { Env } from '../config'; import { configServiceMock } from '../mocks'; -import { elasticsearchServiceMock } from '../elasticsearch/elasticsearch_service.mock'; -import { elasticsearchClientMock } from '../elasticsearch/client/mocks'; +import { opensearchServiceMock } from '../opensearch/opensearch_service.mock'; +import { opensearchClientMock } from '../opensearch/client/mocks'; import { httpServiceMock } from '../http/http_service.mock'; import { httpServerMock } from '../http/http_server.mocks'; import { SavedObjectsClientFactoryProvider } from './service/lib'; -import { NodesVersionCompatibility } from '../elasticsearch/version_check/ensure_es_version'; +import { NodesVersionCompatibility } from '../opensearch/version_check/ensure_opensearch_version'; import { SavedObjectsRepository } from './service/lib/repository'; jest.mock('./service/lib/repository'); @@ -60,17 +60,17 @@ describe('SavedObjectsService', () => { }; const createSetupDeps = () => { - const elasticsearchMock = elasticsearchServiceMock.createInternalSetup(); + const opensearchMock = opensearchServiceMock.createInternalSetup(); return { http: httpServiceMock.createInternalSetupContract(), - elasticsearch: elasticsearchMock, + opensearch: opensearchMock, }; }; const createStartDeps = (pluginsInitialized: boolean = true) => { return { pluginsInitialized, - elasticsearch: elasticsearchServiceMock.createInternalStart(), + opensearch: opensearchServiceMock.createInternalStart(), }; }; @@ -161,30 +161,30 @@ describe('SavedObjectsService', () => { }); describe('#start()', () => { - it('creates a KibanaMigrator which retries NoLivingConnectionsError errors from ES client', async () => { + it('creates a OpenSearchDashboardsMigrator which retries NoLivingConnectionsError errors from OpenSearch client', async () => { const coreContext = createCoreContext(); const soService = new SavedObjectsService(coreContext); const coreSetup = createSetupDeps(); const coreStart = createStartDeps(); - coreStart.elasticsearch.client.asInternalUser.indices.create = jest + coreStart.opensearch.client.asInternalUser.indices.create = jest .fn() .mockImplementationOnce(() => - Promise.reject(new esErrors.NoLivingConnectionsError('reason', {} as any)) + Promise.reject(new opensearchErrors.NoLivingConnectionsError('reason', {} as any)) ) .mockImplementationOnce(() => - elasticsearchClientMock.createSuccessTransportRequestPromise('success') + opensearchClientMock.createSuccessTransportRequestPromise('success') ); await soService.setup(coreSetup); await soService.start(coreStart, 1); - const response = await KibanaMigratorMock.mock.calls[0][0].client.indices.create(); + const response = await OpenSearchDashboardsMigratorMock.mock.calls[0][0].client.indices.create(); return expect(response.body).toBe('success'); }); - it('skips KibanaMigrator migrations when pluginsInitialized=false', async () => { + it('skips OpenSearchDashboardsMigrator migrations when pluginsInitialized=false', async () => { const coreContext = createCoreContext({ skipMigration: false }); const soService = new SavedObjectsService(coreContext); @@ -193,7 +193,7 @@ describe('SavedObjectsService', () => { expect(migratorInstanceMock.runMigrations).not.toHaveBeenCalled(); }); - it('skips KibanaMigrator migrations when migrations.skip=true', async () => { + it('skips OpenSearchDashboardsMigrator migrations when migrations.skip=true', async () => { const coreContext = createCoreContext({ skipMigration: true }); const soService = new SavedObjectsService(coreContext); await soService.setup(createSetupDeps()); @@ -201,29 +201,29 @@ describe('SavedObjectsService', () => { expect(migratorInstanceMock.runMigrations).not.toHaveBeenCalled(); }); - it('waits for all es nodes to be compatible before running migrations', async (done) => { + it('waits for all opensearch nodes to be compatible before running migrations', async (done) => { expect.assertions(2); const coreContext = createCoreContext({ skipMigration: false }); const soService = new SavedObjectsService(coreContext); const setupDeps = createSetupDeps(); // Create an new subject so that we can control when isCompatible=true // is emitted. - setupDeps.elasticsearch.esNodesCompatibility$ = new BehaviorSubject({ + setupDeps.opensearch.opensearchNodesCompatibility$ = new BehaviorSubject({ isCompatible: false, incompatibleNodes: [], warningNodes: [], - kibanaVersion: '8.0.0', + opensearchDashboardsVersion: '8.0.0', }); await soService.setup(setupDeps); soService.start(createStartDeps()); expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(0); - ((setupDeps.elasticsearch.esNodesCompatibility$ as any) as BehaviorSubject< + ((setupDeps.opensearopensearch.opensearchNodesCompatibility$ as any) as BehaviorSubject< NodesVersionCompatibility >).next({ isCompatible: true, incompatibleNodes: [], warningNodes: [], - kibanaVersion: '8.0.0', + opensearchDashboardsVersion: '8.0.0', }); setImmediate(() => { expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(1); @@ -231,7 +231,7 @@ describe('SavedObjectsService', () => { }); }); - it('resolves with KibanaMigrator after waiting for migrations to complete', async () => { + it('resolves with OpenSearchDashboardsMigrator after waiting for migrations to complete', async () => { const coreContext = createCoreContext({ skipMigration: false }); const soService = new SavedObjectsService(coreContext); await soService.setup(createSetupDeps()); @@ -291,10 +291,10 @@ describe('SavedObjectsService', () => { const coreStart = createStartDeps(); const { createScopedRepository } = await soService.start(coreStart); - const req = httpServerMock.createKibanaRequest(); + const req = httpServerMock.createOpenSearchDashboardsRequest(); createScopedRepository(req); - expect(coreStart.elasticsearch.client.asScoped).toHaveBeenCalledWith(req); + expect(coreStart.opensearch.client.asScoped).toHaveBeenCalledWith(req); const [ [, , , , includedHiddenTypes], @@ -311,7 +311,7 @@ describe('SavedObjectsService', () => { const coreStart = createStartDeps(); const { createScopedRepository } = await soService.start(coreStart); - const req = httpServerMock.createKibanaRequest(); + const req = httpServerMock.createOpenSearchDashboardsRequest(); createScopedRepository(req, ['someHiddenType']); const [ @@ -337,7 +337,7 @@ describe('SavedObjectsService', () => { [, , , client, includedHiddenTypes], ] = (SavedObjectsRepository.createRepository as jest.Mocked).mock.calls; - expect(coreStart.elasticsearch.client.asInternalUser).toBe(client); + expect(coreStart.opensearch.client.asInternalUser).toBe(client); expect(includedHiddenTypes).toEqual([]); }); diff --git a/src/core/server/saved_objects/saved_objects_service.ts b/src/core/server/saved_objects/saved_objects_service.ts index 5cc59d55a254..cfa94ffdbfbd 100644 --- a/src/core/server/saved_objects/saved_objects_service.ts +++ b/src/core/server/saved_objects/saved_objects_service.ts @@ -25,21 +25,21 @@ import { SavedObjectsClientProvider, SavedObjectsClientProviderOptions, } from './'; -import { KibanaMigrator, IKibanaMigrator } from './migrations'; +import { OpenSearchDashboardsMigrator, IOpenSearchDashboardsMigrator } from './migrations'; import { CoreContext } from '../core_context'; import { - ElasticsearchClient, + OpenSearchClient, IClusterClient, - InternalElasticsearchServiceSetup, - InternalElasticsearchServiceStart, -} from '../elasticsearch'; -import { KibanaConfigType } from '../kibana_config'; + InternalOpenSearchServiceSetup, + InternalOpenSearchServiceStart, +} from '../opensearch'; +import { OpenSearchDashboardsConfigType } from '../opensearch_dashboards_config'; import { SavedObjectsConfigType, SavedObjectsMigrationConfigType, SavedObjectConfig, } from './saved_objects_config'; -import { KibanaRequest, InternalHttpServiceSetup } from '../http'; +import { OpenSearchDashboardsRequest, InternalHttpServiceSetup } from '../http'; import { SavedObjectsClientContract, SavedObjectsType, SavedObjectStatusMeta } from './types'; import { ISavedObjectsRepository, SavedObjectsRepository } from './service/lib/repository'; import { @@ -52,10 +52,10 @@ import { SavedObjectsSerializer } from './serialization'; import { registerRoutes } from './routes'; import { ServiceStatus } from '../status'; import { calculateStatus$ } from './status'; -import { createMigrationEsClient } from './migrations/core/'; +import { createMigrationOpenSearchClient } from './migrations/core/'; /** - * Saved Objects is Kibana's data persistence mechanism allowing plugins to - * use Elasticsearch for storing and querying state. The SavedObjectsServiceSetup API exposes methods + * Saved Objects is OpenSearchDashboards's data persistence mechanism allowing plugins to + * use OpenSearch for storing and querying state. The SavedObjectsServiceSetup API exposes methods * for registering Saved Object types, creating and registering Saved Object client wrappers and factories. * * @remarks @@ -69,7 +69,7 @@ import { createMigrationEsClient } from './migrations/core/'; * * export class Plugin() { * setup: (core: CoreSetup) => { - * core.savedObjects.setClientFactory(({ request: KibanaRequest }) => { + * core.savedObjects.setClientFactory(({ request: OpenSearchDashboardsRequest }) => { * return new SavedObjectsClient(core.savedObjects.scopedRepository(request)); * }) * } @@ -165,8 +165,8 @@ export interface InternalSavedObjectsServiceSetup extends SavedObjectsServiceSet } /** - * Saved Objects is Kibana's data persisentence mechanism allowing plugins to - * use Elasticsearch for storing and querying state. The + * Saved Objects is OpenSearchDashboards's data persisentence mechanism allowing plugins to + * use OpenSearch for storing and querying state. The * SavedObjectsServiceStart API provides a scoped Saved Objects client for * interacting with Saved Objects. * @@ -176,20 +176,20 @@ export interface SavedObjectsServiceStart { /** * Creates a {@link SavedObjectsClientContract | Saved Objects client} that * uses the credentials from the passed in request to authenticate with - * Elasticsearch. If other plugins have registered Saved Objects client + * OpenSearch. If other plugins have registered Saved Objects client * wrappers, these will be applied to extend the functionality of the client. * * A client that is already scoped to the incoming request is also exposed * from the route handler context see {@link RequestHandlerContext}. */ getScopedClient: ( - req: KibanaRequest, + req: OpenSearchDashboardsRequest, options?: SavedObjectsClientProviderOptions ) => SavedObjectsClientContract; /** * Creates a {@link ISavedObjectsRepository | Saved Objects repository} that * uses the credentials from the passed in request to authenticate with - * Elasticsearch. + * OpenSearch. * * @param req - The request to create the scoped repository from. * @param includedHiddenTypes - A list of additional hidden types the repository should have access to. @@ -199,12 +199,12 @@ export interface SavedObjectsServiceStart { * not exposed on {@link SavedObjectsClientContract} */ createScopedRepository: ( - req: KibanaRequest, + req: OpenSearchDashboardsRequest, includedHiddenTypes?: string[] ) => ISavedObjectsRepository; /** * Creates a {@link ISavedObjectsRepository | Saved Objects repository} that - * uses the internal Kibana user for authenticating with Elasticsearch. + * uses the internal OpenSearch Dashboards user for authenticating with OpenSearch. * * @param includedHiddenTypes - A list of additional hidden types the repository should have access to. */ @@ -232,17 +232,17 @@ export interface SavedObjectsRepositoryFactory { /** * Creates a {@link ISavedObjectsRepository | Saved Objects repository} that * uses the credentials from the passed in request to authenticate with - * Elasticsearch. + * OpenSearch. * * @param includedHiddenTypes - A list of additional hidden types the repository should have access to. */ createScopedRepository: ( - req: KibanaRequest, + req: OpenSearchDashboardsRequest, includedHiddenTypes?: string[] ) => ISavedObjectsRepository; /** * Creates a {@link ISavedObjectsRepository | Saved Objects repository} that - * uses the internal Kibana user for authenticating with Elasticsearch. + * uses the internal OpenSearch Dashboards user for authenticating with OpenSearch. * * @param includedHiddenTypes - A list of additional hidden types the repository should have access to. */ @@ -252,7 +252,7 @@ export interface SavedObjectsRepositoryFactory { /** @internal */ export interface SavedObjectsSetupDeps { http: InternalHttpServiceSetup; - elasticsearch: InternalElasticsearchServiceSetup; + opensearch: InternalOpenSearchServiceSetup; } interface WrappedClientFactoryWrapper { @@ -263,7 +263,7 @@ interface WrappedClientFactoryWrapper { /** @internal */ export interface SavedObjectsStartDeps { - elasticsearch: InternalElasticsearchServiceStart; + opensearch: InternalOpenSearchServiceStart; pluginsInitialized?: boolean; } @@ -276,7 +276,7 @@ export class SavedObjectsService private clientFactoryProvider?: SavedObjectsClientFactoryProvider; private clientFactoryWrappers: WrappedClientFactoryWrapper[] = []; - private migrator$ = new Subject(); + private migrator$ = new Subject(); private typeRegistry = new SavedObjectTypeRegistry(); private started = false; @@ -309,7 +309,7 @@ export class SavedObjectsService return { status$: calculateStatus$( this.migrator$.pipe(switchMap((migrator) => migrator.getStatus$())), - setupDeps.elasticsearch.status$ + setupDeps.opensearch.status$ ), setClientFactoryProvider: (provider) => { if (this.started) { @@ -341,7 +341,7 @@ export class SavedObjectsService } public async start( - { elasticsearch, pluginsInitialized = true }: SavedObjectsStartDeps, + { opensearch, pluginsInitialized = true }: SavedObjectsStartDeps, migrationsRetryDelay?: number ): Promise { if (!this.setupDeps || !this.config) { @@ -350,16 +350,16 @@ export class SavedObjectsService this.logger.debug('Starting SavedObjects service'); - const kibanaConfig = await this.coreContext.configService - .atPath('kibana') + const opensearchDashboardsConfig = await this.coreContext.configService + .atPath('opensearchDashboard') .pipe(first()) .toPromise(); - const client = elasticsearch.client; + const client = opensearch.client; const migrator = this.createMigrator( - kibanaConfig, + opensearchDashboardsConfig, this.config.migration, - elasticsearch.client, + opensearch.client, migrationsRetryDelay ); @@ -372,7 +372,7 @@ export class SavedObjectsService * HTTP requests. * * However, our build system optimize step and some tests depend on the - * HTTP server running without an Elasticsearch server being available. + * HTTP server running without an OpenSearch server being available. * So, when the `migrations.skip` is true, we skip migrations altogether. * * We also cannot safely run migrations if plugins are not initialized since @@ -386,17 +386,17 @@ export class SavedObjectsService ); } else { this.logger.info( - 'Waiting until all Elasticsearch nodes are compatible with Kibana before starting saved objects migrations...' + 'Waiting until all OpenSearch nodes are compatible with OpenSearch Dashboards before starting saved objects migrations...' ); // TODO: Move to Status Service https://github.com/elastic/kibana/issues/41983 - this.setupDeps!.elasticsearch.esNodesCompatibility$.subscribe(({ isCompatible, message }) => { + this.setupDeps!.opensearch.opensearchNodesCompatibilityNodesCompatibility$.subscribe(({ isCompatible, message }) => { if (!isCompatible && message) { this.logger.error(message); } }); - await this.setupDeps!.elasticsearch.esNodesCompatibility$.pipe( + await this.setupDeps!.opensearch.opensearchNodesCompatibilityNodesCompatibility$.pipe( filter((nodes) => nodes.isCompatible), take(1) ).toPromise(); @@ -406,14 +406,14 @@ export class SavedObjectsService } const createRepository = ( - esClient: ElasticsearchClient, + opensearchClient: OpenSearchClient, includedHiddenTypes: string[] = [] ) => { return SavedObjectsRepository.createRepository( migrator, this.typeRegistry, - kibanaConfig.index, - esClient, + opensearchDashboardsConfig.index, + opensearchClient, includedHiddenTypes ); }; @@ -421,7 +421,7 @@ export class SavedObjectsService const repositoryFactory: SavedObjectsRepositoryFactory = { createInternalRepository: (includedHiddenTypes?: string[]) => createRepository(client.asInternalUser, includedHiddenTypes), - createScopedRepository: (req: KibanaRequest, includedHiddenTypes?: string[]) => + createScopedRepository: (req: OpenSearchDashboardsRequest, includedHiddenTypes?: string[]) => createRepository(client.asScoped(req).asCurrentUser, includedHiddenTypes), }; @@ -454,18 +454,18 @@ export class SavedObjectsService public async stop() {} private createMigrator( - kibanaConfig: KibanaConfigType, + opensearchDashboardsConfig: OpenSearchDashboardsConfigType, savedObjectsConfig: SavedObjectsMigrationConfigType, client: IClusterClient, migrationsRetryDelay?: number - ): IKibanaMigrator { - return new KibanaMigrator({ + ): IOpenSearchDashboardsMigrator { + return new OpenSearchDashboardsMigrator({ typeRegistry: this.typeRegistry, logger: this.logger, - kibanaVersion: this.coreContext.env.packageInfo.version, + opensearchDashboardsVersion: this.coreContext.env.packageInfo.version, savedObjectsConfig, - kibanaConfig, - client: createMigrationEsClient(client.asInternalUser, this.logger, migrationsRetryDelay), + opensearchDashboardsConfig, + client: createMigrationOpenSearchClient(client.asInternalUser, this.logger, migrationsRetryDelay), }); } } diff --git a/src/core/server/saved_objects/saved_objects_type_registry.mock.ts b/src/core/server/saved_objects/saved_objects_type_registry.mock.ts index 44490228490c..25de98c9d97c 100644 --- a/src/core/server/saved_objects/saved_objects_type_registry.mock.ts +++ b/src/core/server/saved_objects/saved_objects_type_registry.mock.ts @@ -39,8 +39,8 @@ const createRegistryMock = (): jest.Mocked< mock.getVisibleTypes.mockReturnValue([]); mock.getAllTypes.mockReturnValue([]); mock.getImportableAndExportableTypes.mockReturnValue([]); - mock.getIndex.mockReturnValue('.kibana-test'); - mock.getIndex.mockReturnValue('.kibana-test'); + mock.getIndex.mockReturnValue('.opensearch-dashboards-test'); + mock.getIndex.mockReturnValue('.opensearch-dashboards-test'); mock.isHidden.mockReturnValue(false); mock.isNamespaceAgnostic.mockImplementation((type: string) => type === 'global'); mock.isSingleNamespace.mockImplementation( diff --git a/src/core/server/saved_objects/saved_objects_type_registry.ts b/src/core/server/saved_objects/saved_objects_type_registry.ts index bb840e459bf2..cb27bd4ae9e6 100644 --- a/src/core/server/saved_objects/saved_objects_type_registry.ts +++ b/src/core/server/saved_objects/saved_objects_type_registry.ts @@ -17,7 +17,7 @@ * under the License. */ -import { deepFreeze } from '@kbn/std'; +import { deepFreeze } from '@osd/std'; import { SavedObjectsType } from './types'; /** diff --git a/src/core/server/saved_objects/serialization/index.ts b/src/core/server/saved_objects/serialization/index.ts index 812a0770ad98..b297a228d4ee 100644 --- a/src/core/server/saved_objects/serialization/index.ts +++ b/src/core/server/saved_objects/serialization/index.ts @@ -19,7 +19,7 @@ /* * This file contains the logic for transforming saved objects to / from - * the raw document format as stored in ElasticSearch. + * the raw document format as stored in OpenSearch. */ export { diff --git a/src/core/server/saved_objects/serialization/serializer.test.ts b/src/core/server/saved_objects/serialization/serializer.test.ts index e5f0e8abd3b7..d70f78fffee4 100644 --- a/src/core/server/saved_objects/serialization/serializer.test.ts +++ b/src/core/server/saved_objects/serialization/serializer.test.ts @@ -176,7 +176,7 @@ describe('#rawToSavedObject', () => { hello: {}, }, }) - ).toThrowErrorMatchingInlineSnapshot(`"_primary_term from elasticsearch must be an integer"`); + ).toThrowErrorMatchingInlineSnapshot(`"_primary_term from opensearch must be an integer"`); }); test(`if only _primary_term is throws`, () => { @@ -189,7 +189,7 @@ describe('#rawToSavedObject', () => { hello: {}, }, }) - ).toThrowErrorMatchingInlineSnapshot(`"_seq_no from elasticsearch must be an integer"`); + ).toThrowErrorMatchingInlineSnapshot(`"_seq_no from opensearch must be an integer"`); }); test('if specified it copies the _source.updated_at property to updated_at', () => { diff --git a/src/core/server/saved_objects/serialization/serializer.ts b/src/core/server/saved_objects/serialization/serializer.ts index 145dd286c1ca..1dc36dbabd74 100644 --- a/src/core/server/saved_objects/serialization/serializer.ts +++ b/src/core/server/saved_objects/serialization/serializer.ts @@ -42,7 +42,7 @@ export class SavedObjectsSerializer { /** * Determines whether or not the raw document can be converted to a saved object. * - * @param {SavedObjectsRawDoc} rawDoc - The raw ES document to be tested + * @param {SavedObjectsRawDoc} rawDoc - The raw OpenSearch document to be tested */ public isRawSavedObject(rawDoc: SavedObjectsRawDoc) { const { type, namespace } = rawDoc._source; @@ -56,9 +56,9 @@ export class SavedObjectsSerializer { } /** - * Converts a document from the format that is stored in elasticsearch to the saved object client format. + * Converts a document from the format that is stored in opensearch to the saved object client format. * - * @param {SavedObjectsRawDoc} doc - The raw ES document to be converted to saved object format. + * @param {SavedObjectsRawDoc} doc - The raw OpenSearch document to be converted to saved object format. */ public rawToSavedObject(doc: SavedObjectsRawDoc): SavedObjectSanitizedDoc { const { _id, _source, _seq_no, _primary_term } = doc; @@ -84,9 +84,9 @@ export class SavedObjectsSerializer { } /** - * Converts a document from the saved object client format to the format that is stored in elasticsearch. + * Converts a document from the saved object client format to the format that is stored in opensearch. * - * @param {SavedObjectSanitizedDoc} savedObj - The saved object to be converted to raw ES format. + * @param {SavedObjectSanitizedDoc} savedObj - The saved object to be converted to raw OpenSearch format. */ public savedObjectToRaw(savedObj: SavedObjectSanitizedDoc): SavedObjectsRawDoc { const { diff --git a/src/core/server/saved_objects/serialization/types.ts b/src/core/server/saved_objects/serialization/types.ts index 8b3eebceb2c5..69be7c15a9cb 100644 --- a/src/core/server/saved_objects/serialization/types.ts +++ b/src/core/server/saved_objects/serialization/types.ts @@ -65,7 +65,7 @@ interface Referencable { } /** - * Describes Saved Object documents from Kibana < 7.0.0 which don't have a + * Describes Saved Object documents from OpenSearch Dashboards < 7.0.0 which don't have a * `references` root property defined. This type should only be used in * migrations. * diff --git a/src/core/server/saved_objects/service/lib/decorate_es_error.test.ts b/src/core/server/saved_objects/service/lib/decorate_es_error.test.ts deleted file mode 100644 index 3358de1c1031..000000000000 --- a/src/core/server/saved_objects/service/lib/decorate_es_error.test.ts +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { errors as esErrors } from '@elastic/elasticsearch'; -import { elasticsearchClientMock } from '../../../elasticsearch/client/mocks'; -import { decorateEsError } from './decorate_es_error'; -import { SavedObjectsErrorHelpers } from './errors'; - -describe('savedObjectsClient/decorateEsError', () => { - it('always returns the same error it receives', () => { - const error = new esErrors.ResponseError(elasticsearchClientMock.createApiResponse()); - expect(decorateEsError(error)).toBe(error); - }); - - it('makes ConnectionError a SavedObjectsClient/EsUnavailable error', () => { - const error = new esErrors.ConnectionError( - 'reason', - elasticsearchClientMock.createApiResponse() - ); - expect(SavedObjectsErrorHelpers.isEsUnavailableError(error)).toBe(false); - expect(decorateEsError(error)).toBe(error); - expect(SavedObjectsErrorHelpers.isEsUnavailableError(error)).toBe(true); - }); - - it('makes ServiceUnavailable a SavedObjectsClient/EsUnavailable error', () => { - const error = new esErrors.ResponseError( - elasticsearchClientMock.createApiResponse({ statusCode: 503 }) - ); - expect(SavedObjectsErrorHelpers.isEsUnavailableError(error)).toBe(false); - expect(decorateEsError(error)).toBe(error); - expect(SavedObjectsErrorHelpers.isEsUnavailableError(error)).toBe(true); - }); - - it('makes NoLivingConnectionsError a SavedObjectsClient/EsUnavailable error', () => { - const error = new esErrors.NoLivingConnectionsError( - 'reason', - elasticsearchClientMock.createApiResponse() - ); - expect(SavedObjectsErrorHelpers.isEsUnavailableError(error)).toBe(false); - expect(decorateEsError(error)).toBe(error); - expect(SavedObjectsErrorHelpers.isEsUnavailableError(error)).toBe(true); - }); - - it('makes TimeoutError a SavedObjectsClient/EsUnavailable error', () => { - const error = new esErrors.TimeoutError('reason', elasticsearchClientMock.createApiResponse()); - expect(SavedObjectsErrorHelpers.isEsUnavailableError(error)).toBe(false); - expect(decorateEsError(error)).toBe(error); - expect(SavedObjectsErrorHelpers.isEsUnavailableError(error)).toBe(true); - }); - - it('makes Conflict a SavedObjectsClient/Conflict error', () => { - const error = new esErrors.ResponseError( - elasticsearchClientMock.createApiResponse({ statusCode: 409 }) - ); - expect(SavedObjectsErrorHelpers.isConflictError(error)).toBe(false); - expect(decorateEsError(error)).toBe(error); - expect(SavedObjectsErrorHelpers.isConflictError(error)).toBe(true); - }); - - it('makes TooManyRequests a SavedObjectsClient/tooManyRequests error', () => { - const error = new esErrors.ResponseError( - elasticsearchClientMock.createApiResponse({ statusCode: 429 }) - ); - expect(SavedObjectsErrorHelpers.isTooManyRequestsError(error)).toBe(false); - expect(decorateEsError(error)).toBe(error); - expect(SavedObjectsErrorHelpers.isTooManyRequestsError(error)).toBe(true); - }); - - it('makes NotAuthorized a SavedObjectsClient/NotAuthorized error', () => { - const error = new esErrors.ResponseError( - elasticsearchClientMock.createApiResponse({ statusCode: 401 }) - ); - expect(SavedObjectsErrorHelpers.isNotAuthorizedError(error)).toBe(false); - expect(decorateEsError(error)).toBe(error); - expect(SavedObjectsErrorHelpers.isNotAuthorizedError(error)).toBe(true); - }); - - it('makes Forbidden a SavedObjectsClient/Forbidden error', () => { - const error = new esErrors.ResponseError( - elasticsearchClientMock.createApiResponse({ statusCode: 403 }) - ); - expect(SavedObjectsErrorHelpers.isForbiddenError(error)).toBe(false); - expect(decorateEsError(error)).toBe(error); - expect(SavedObjectsErrorHelpers.isForbiddenError(error)).toBe(true); - }); - - it('makes RequestEntityTooLarge a SavedObjectsClient/RequestEntityTooLarge error', () => { - const error = new esErrors.ResponseError( - elasticsearchClientMock.createApiResponse({ statusCode: 413 }) - ); - expect(SavedObjectsErrorHelpers.isRequestEntityTooLargeError(error)).toBe(false); - expect(decorateEsError(error)).toBe(error); - expect(SavedObjectsErrorHelpers.isRequestEntityTooLargeError(error)).toBe(true); - }); - - it('discards NotFound errors and returns a generic NotFound error', () => { - const error = new esErrors.ResponseError( - elasticsearchClientMock.createApiResponse({ statusCode: 404 }) - ); - expect(SavedObjectsErrorHelpers.isNotFoundError(error)).toBe(false); - const genericError = decorateEsError(error); - expect(genericError).not.toBe(error); - expect(SavedObjectsErrorHelpers.isNotFoundError(error)).toBe(false); - expect(SavedObjectsErrorHelpers.isNotFoundError(genericError)).toBe(true); - }); - - it('makes BadRequest a SavedObjectsClient/BadRequest error', () => { - const error = new esErrors.ResponseError( - elasticsearchClientMock.createApiResponse({ statusCode: 400 }) - ); - expect(SavedObjectsErrorHelpers.isBadRequestError(error)).toBe(false); - expect(decorateEsError(error)).toBe(error); - expect(SavedObjectsErrorHelpers.isBadRequestError(error)).toBe(true); - }); - - describe('when es.BadRequest has a reason', () => { - it('makes a SavedObjectsClient/esCannotExecuteScriptError error when script context is disabled', () => { - const error = new esErrors.ResponseError( - elasticsearchClientMock.createApiResponse({ - statusCode: 400, - body: { - error: { - reason: 'cannot execute scripts using [update] context', - }, - }, - }) - ); - expect(SavedObjectsErrorHelpers.isEsCannotExecuteScriptError(error)).toBe(false); - expect(decorateEsError(error)).toBe(error); - expect(SavedObjectsErrorHelpers.isEsCannotExecuteScriptError(error)).toBe(true); - expect(SavedObjectsErrorHelpers.isBadRequestError(error)).toBe(false); - }); - - it('makes a SavedObjectsClient/esCannotExecuteScriptError error when inline scripts are disabled', () => { - const error = new esErrors.ResponseError( - elasticsearchClientMock.createApiResponse({ - statusCode: 400, - body: { - error: { - reason: 'cannot execute [inline] scripts', - }, - }, - }) - ); - expect(SavedObjectsErrorHelpers.isEsCannotExecuteScriptError(error)).toBe(false); - expect(decorateEsError(error)).toBe(error); - expect(SavedObjectsErrorHelpers.isEsCannotExecuteScriptError(error)).toBe(true); - expect(SavedObjectsErrorHelpers.isBadRequestError(error)).toBe(false); - }); - - it('makes a SavedObjectsClient/BadRequest error for any other reason', () => { - const error = new esErrors.ResponseError( - elasticsearchClientMock.createApiResponse({ statusCode: 400 }) - ); - expect(SavedObjectsErrorHelpers.isBadRequestError(error)).toBe(false); - expect(decorateEsError(error)).toBe(error); - expect(SavedObjectsErrorHelpers.isBadRequestError(error)).toBe(true); - }); - }); - - it('returns other errors as Boom errors', () => { - const error = new esErrors.ResponseError(elasticsearchClientMock.createApiResponse()); - expect(error).not.toHaveProperty('isBoom'); - expect(decorateEsError(error)).toBe(error); - expect(error).toHaveProperty('isBoom'); - }); -}); diff --git a/src/core/server/saved_objects/service/lib/decorate_opensearch_error.test.ts b/src/core/server/saved_objects/service/lib/decorate_opensearch_error.test.ts new file mode 100644 index 000000000000..e2dd9b7f7a8e --- /dev/null +++ b/src/core/server/saved_objects/service/lib/decorate_opensearch_error.test.ts @@ -0,0 +1,183 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { errors as opensearchErrors } from '@elastic/elasticsearch'; +import { opensearchClientMock } from '../../../opensearch/client/mocks'; +import { decorateOpenSearchError } from './decorate_opensearch_error'; +import { SavedObjectsErrorHelpers } from './errors'; + +describe('savedObjectsClient/decorateOpenSearchError', () => { + it('always returns the same error it receives', () => { + const error = new opensearchErrors.ResponseError(opensearchClientMock.createApiResponse()); + expect(decorateOpenSearchError(error)).toBe(error); + }); + + it('makes ConnectionError a SavedObjectsClient/OpenSearchUnavailable error', () => { + const error = new opensearchErrors.ConnectionError( + 'reason', + opensearchClientMock.createApiResponse() + ); + expect(SavedObjectsErrorHelpers.isOpenSearchUnavailableError(error)).toBe(false); + expect(decorateOpenSearchError(error)).toBe(error); + expect(SavedObjectsErrorHelpers.isOpenSearchUnavailableError(error)).toBe(true); + }); + + it('makes ServiceUnavailable a SavedObjectsClient/OpenSearchUnavailable error', () => { + const error = new opensearchErrors.ResponseError( + opensearchClientMock.createApiResponse({ statusCode: 503 }) + ); + expect(SavedObjectsErrorHelpers.isOpenSearchUnavailableError(error)).toBe(false); + expect(decorateOpenSearchError(error)).toBe(error); + expect(SavedObjectsErrorHelpers.isOpenSearchUnavailableError(error)).toBe(true); + }); + + it('makes NoLivingConnectionsError a SavedObjectsClient/OpenSearchUnavailable error', () => { + const error = new opensearchErrors.NoLivingConnectionsError( + 'reason', + opensearchClientMock.createApiResponse() + ); + expect(SavedObjectsErrorHelpers.isOpenSearchUnavailableError(error)).toBe(false); + expect(decorateOpenSearchError(error)).toBe(error); + expect(SavedObjectsErrorHelpers.isOpenSearchUnavailableError(error)).toBe(true); + }); + + it('makes TimeoutError a SavedObjectsClient/OpenSearchUnavailable error', () => { + const error = new opensearchErrors.TimeoutError('reason', opensearchClientMock.createApiResponse()); + expect(SavedObjectsErrorHelpers.isOpenSearchUnavailableError(error)).toBe(false); + expect(decorateOpenSearchError(error)).toBe(error); + expect(SavedObjectsErrorHelpers.isOpenSearchUnavailableError(error)).toBe(true); + }); + + it('makes Conflict a SavedObjectsClient/Conflict error', () => { + const error = new opensearchErrors.ResponseError( + opensearchClientMock.createApiResponse({ statusCode: 409 }) + ); + expect(SavedObjectsErrorHelpers.isConflictError(error)).toBe(false); + expect(decorateOpenSearchError(error)).toBe(error); + expect(SavedObjectsErrorHelpers.isConflictError(error)).toBe(true); + }); + + it('makes TooManyRequests a SavedObjectsClient/tooManyRequests error', () => { + const error = new opensearchErrors.ResponseError( + opensearchClientMock.createApiResponse({ statusCode: 429 }) + ); + expect(SavedObjectsErrorHelpers.isTooManyRequestsError(error)).toBe(false); + expect(decorateOpenSearchError(error)).toBe(error); + expect(SavedObjectsErrorHelpers.isTooManyRequestsError(error)).toBe(true); + }); + + it('makes NotAuthorized a SavedObjectsClient/NotAuthorized error', () => { + const error = new opensearchErrors.ResponseError( + opensearchClientMock.createApiResponse({ statusCode: 401 }) + ); + expect(SavedObjectsErrorHelpers.isNotAuthorizedError(error)).toBe(false); + expect(decorateOpenSearchError(error)).toBe(error); + expect(SavedObjectsErrorHelpers.isNotAuthorizedError(error)).toBe(true); + }); + + it('makes Forbidden a SavedObjectsClient/Forbidden error', () => { + const error = new opensearchErrors.ResponseError( + opensearchClientMock.createApiResponse({ statusCode: 403 }) + ); + expect(SavedObjectsErrorHelpers.isForbiddenError(error)).toBe(false); + expect(decorateOpenSearchError(error)).toBe(error); + expect(SavedObjectsErrorHelpers.isForbiddenError(error)).toBe(true); + }); + + it('makes RequestEntityTooLarge a SavedObjectsClient/RequestEntityTooLarge error', () => { + const error = new opensearchErrors.ResponseError( + opensearchClientMock.createApiResponse({ statusCode: 413 }) + ); + expect(SavedObjectsErrorHelpers.isRequestEntityTooLargeError(error)).toBe(false); + expect(decorateOpenSearchError(error)).toBe(error); + expect(SavedObjectsErrorHelpers.isRequestEntityTooLargeError(error)).toBe(true); + }); + + it('discards NotFound errors and returns a generic NotFound error', () => { + const error = new opensearchErrors.ResponseError( + opensearchClientMock.createApiResponse({ statusCode: 404 }) + ); + expect(SavedObjectsErrorHelpers.isNotFoundError(error)).toBe(false); + const genericError = decorateOpenSearchError(error); + expect(genericError).not.toBe(error); + expect(SavedObjectsErrorHelpers.isNotFoundError(error)).toBe(false); + expect(SavedObjectsErrorHelpers.isNotFoundError(genericError)).toBe(true); + }); + + it('makes BadRequest a SavedObjectsClient/BadRequest error', () => { + const error = new opensearchErrors.ResponseError( + opensearchClientMock.createApiResponse({ statusCode: 400 }) + ); + expect(SavedObjectsErrorHelpers.isBadRequestError(error)).toBe(false); + expect(decorateOpenSearchError(error)).toBe(error); + expect(SavedObjectsErrorHelpers.isBadRequestError(error)).toBe(true); + }); + + describe('when opensearch.BadRequest has a reason', () => { + it('makes a SavedObjectsClient/esCannotExecuteScriptError error when script context is disabled', () => { + const error = new opensearchErrors.ResponseError( + opensearchClientMock.createApiResponse({ + statusCode: 400, + body: { + error: { + reason: 'cannot execute scripts using [update] context', + }, + }, + }) + ); + expect(SavedObjectsErrorHelpers.isOpenSearchCannotExecuteScriptError(error)).toBe(false); + expect(decorateOpenSearchError(error)).toBe(error); + expect(SavedObjectsErrorHelpers.isOpenSearchCannotExecuteScriptError(error)).toBe(true); + expect(SavedObjectsErrorHelpers.isBadRequestError(error)).toBe(false); + }); + + it('makes a SavedObjectsClient/esCannotExecuteScriptError error when inline scripts are disabled', () => { + const error = new opensearchErrors.ResponseError( + opensearchClientMock.createApiResponse({ + statusCode: 400, + body: { + error: { + reason: 'cannot execute [inline] scripts', + }, + }, + }) + ); + expect(SavedObjectsErrorHelpers.isOpenSearchCannotExecuteScriptError(error)).toBe(false); + expect(decorateOpenSearchError(error)).toBe(error); + expect(SavedObjectsErrorHelpers.isOpenSearchCannotExecuteScriptError(error)).toBe(true); + expect(SavedObjectsErrorHelpers.isBadRequestError(error)).toBe(false); + }); + + it('makes a SavedObjectsClient/BadRequest error for any other reason', () => { + const error = new opensearchErrors.ResponseError( + opensearchClientMock.createApiResponse({ statusCode: 400 }) + ); + expect(SavedObjectsErrorHelpers.isBadRequestError(error)).toBe(false); + expect(decorateOpenSearchError(error)).toBe(error); + expect(SavedObjectsErrorHelpers.isBadRequestError(error)).toBe(true); + }); + }); + + it('returns other errors as Boom errors', () => { + const error = new opensearchErrors.ResponseError(opensearchClientMock.createApiResponse()); + expect(error).not.toHaveProperty('isBoom'); + expect(decorateOpenSearchError(error)).toBe(error); + expect(error).toHaveProperty('isBoom'); + }); +}); diff --git a/src/core/server/saved_objects/service/lib/decorate_es_error.ts b/src/core/server/saved_objects/service/lib/decorate_opensearch_error.ts similarity index 86% rename from src/core/server/saved_objects/service/lib/decorate_es_error.ts rename to src/core/server/saved_objects/service/lib/decorate_opensearch_error.ts index 592b268d8219..e8af524c5a4d 100644 --- a/src/core/server/saved_objects/service/lib/decorate_es_error.ts +++ b/src/core/server/saved_objects/service/lib/decorate_opensearch_error.ts @@ -17,7 +17,7 @@ * under the License. */ -import { errors as esErrors } from '@elastic/elasticsearch'; +import { errors as opensearchErrors } from '@elastic/elasticsearch'; import { get } from 'lodash'; const responseErrors = { @@ -30,19 +30,19 @@ const responseErrors = { isBadRequest: (statusCode: number) => statusCode === 400, isTooManyRequests: (statusCode: number) => statusCode === 429, }; -const { ConnectionError, NoLivingConnectionsError, TimeoutError } = esErrors; +const { ConnectionError, NoLivingConnectionsError, TimeoutError } = opensearchErrors; const SCRIPT_CONTEXT_DISABLED_REGEX = /(?:cannot execute scripts using \[)([a-z]*)(?:\] context)/; const INLINE_SCRIPTS_DISABLED_MESSAGE = 'cannot execute [inline] scripts'; import { SavedObjectsErrorHelpers } from './errors'; -type EsErrors = - | esErrors.ConnectionError - | esErrors.NoLivingConnectionsError - | esErrors.TimeoutError - | esErrors.ResponseError; +type OpenSearchErrors = + | opensearchErrors.ConnectionError + | opensearchErrors.NoLivingConnectionsError + | opensearchErrors.TimeoutError + | opensearchErrors.ResponseError; -export function decorateEsError(error: EsErrors) { +export function decorateOpenSearchError(error: OpenSearchErrors) { if (!(error instanceof Error)) { throw new Error('Expected an instance of Error'); } @@ -54,7 +54,7 @@ export function decorateEsError(error: EsErrors) { error instanceof TimeoutError || responseErrors.isServiceUnavailable(error.statusCode) ) { - return SavedObjectsErrorHelpers.decorateEsUnavailableError(error, reason); + return SavedObjectsErrorHelpers.decorateOpenSearchUnavailableError(error, reason); } if (responseErrors.isConflict(error.statusCode)) { @@ -86,7 +86,7 @@ export function decorateEsError(error: EsErrors) { SCRIPT_CONTEXT_DISABLED_REGEX.test(reason || '') || reason === INLINE_SCRIPTS_DISABLED_MESSAGE ) { - return SavedObjectsErrorHelpers.decorateEsCannotExecuteScriptError(error, reason); + return SavedObjectsErrorHelpers.decorateOpenSearchCannotExecuteScriptError(error, reason); } return SavedObjectsErrorHelpers.decorateBadRequestError(error, reason); } diff --git a/src/core/server/saved_objects/service/lib/errors.test.ts b/src/core/server/saved_objects/service/lib/errors.test.ts index 931d9f725e41..8f8163edb406 100644 --- a/src/core/server/saved_objects/service/lib/errors.test.ts +++ b/src/core/server/saved_objects/service/lib/errors.test.ts @@ -321,35 +321,35 @@ describe('savedObjectsClient/errorTypes', () => { }); }); - describe('EsCannotExecuteScript error', () => { - describe('decorateEsCannotExecuteScriptError', () => { + describe('OpenSearchCannotExecuteScript error', () => { + describe('decorateOpenSearchCannotExecuteScriptError', () => { it('returns original object', () => { const error = new Error(); - expect(SavedObjectsErrorHelpers.decorateEsCannotExecuteScriptError(error)).toBe(error); + expect(SavedObjectsErrorHelpers.decorateOpenSearchCannotExecuteScriptError(error)).toBe(error); }); - it('makes the error identifiable as a EsCannotExecuteScript error', () => { + it('makes the error identifiable as a OpenSearchCannotExecuteScript error', () => { const error = new Error(); - expect(SavedObjectsErrorHelpers.isEsCannotExecuteScriptError(error)).toBe(false); - SavedObjectsErrorHelpers.decorateEsCannotExecuteScriptError(error); - expect(SavedObjectsErrorHelpers.isEsCannotExecuteScriptError(error)).toBe(true); + expect(SavedObjectsErrorHelpers.isOpenSearchCannotExecuteScriptError(error)).toBe(false); + SavedObjectsErrorHelpers.decorateOpenSearchCannotExecuteScriptError(error); + expect(SavedObjectsErrorHelpers.isOpenSearchCannotExecuteScriptError(error)).toBe(true); }); it('adds boom properties', () => { - const error = SavedObjectsErrorHelpers.decorateEsCannotExecuteScriptError(new Error()); + const error = SavedObjectsErrorHelpers.decorateOpenSearchCannotExecuteScriptError(new Error()); expect(error).toHaveProperty('isBoom', true); }); describe('error.output', () => { it('defaults to message of error', () => { - const error = SavedObjectsErrorHelpers.decorateEsCannotExecuteScriptError( + const error = SavedObjectsErrorHelpers.decorateOpenSearchCannotExecuteScriptError( new Error('foobar') ); expect(error.output.payload).toHaveProperty('message', 'foobar'); }); it('prefixes message with passed reason', () => { - const error = SavedObjectsErrorHelpers.decorateEsCannotExecuteScriptError( + const error = SavedObjectsErrorHelpers.decorateOpenSearchCannotExecuteScriptError( new Error('foobar'), 'biz' ); @@ -357,7 +357,7 @@ describe('savedObjectsClient/errorTypes', () => { }); it('sets statusCode to 501', () => { - const error = SavedObjectsErrorHelpers.decorateEsCannotExecuteScriptError( + const error = SavedObjectsErrorHelpers.decorateOpenSearchCannotExecuteScriptError( new Error('foo') ); expect(error.output).toHaveProperty('statusCode', 400); @@ -365,40 +365,40 @@ describe('savedObjectsClient/errorTypes', () => { it('preserves boom properties of input', () => { const error = Boom.notFound(); - SavedObjectsErrorHelpers.decorateEsCannotExecuteScriptError(error); + SavedObjectsErrorHelpers.decorateOpenSearchCannotExecuteScriptError(error); expect(error.output).toHaveProperty('statusCode', 404); }); }); }); }); - describe('EsUnavailable error', () => { - describe('decorateEsUnavailableError', () => { + describe('OpenSearchUnavailable error', () => { + describe('decorateOpenSearchUnavailableError', () => { it('returns original object', () => { const error = new Error(); - expect(SavedObjectsErrorHelpers.decorateEsUnavailableError(error)).toBe(error); + expect(SavedObjectsErrorHelpers.decorateOpenSearchUnavailableError(error)).toBe(error); }); - it('makes the error identifiable as a EsUnavailable error', () => { + it('makes the error identifiable as a OpenSearchUnavailable error', () => { const error = new Error(); - expect(SavedObjectsErrorHelpers.isEsUnavailableError(error)).toBe(false); - SavedObjectsErrorHelpers.decorateEsUnavailableError(error); - expect(SavedObjectsErrorHelpers.isEsUnavailableError(error)).toBe(true); + expect(SavedObjectsErrorHelpers.isOpenSearchUnavailableError(error)).toBe(false); + SavedObjectsErrorHelpers.decorateOpenSearchUnavailableError(error); + expect(SavedObjectsErrorHelpers.isOpenSearchUnavailableError(error)).toBe(true); }); it('adds boom properties', () => { - const error = SavedObjectsErrorHelpers.decorateEsUnavailableError(new Error()); + const error = SavedObjectsErrorHelpers.decorateOpenSearchUnavailableError(new Error()); expect(error).toHaveProperty('isBoom', true); }); describe('error.output', () => { it('defaults to message of error', () => { - const error = SavedObjectsErrorHelpers.decorateEsUnavailableError(new Error('foobar')); + const error = SavedObjectsErrorHelpers.decorateOpenSearchUnavailableError(new Error('foobar')); expect(error.output.payload).toHaveProperty('message', 'foobar'); }); it('prefixes message with passed reason', () => { - const error = SavedObjectsErrorHelpers.decorateEsUnavailableError( + const error = SavedObjectsErrorHelpers.decorateOpenSearchUnavailableError( new Error('foobar'), 'biz' ); @@ -406,13 +406,13 @@ describe('savedObjectsClient/errorTypes', () => { }); it('sets statusCode to 503', () => { - const error = SavedObjectsErrorHelpers.decorateEsUnavailableError(new Error('foo')); + const error = SavedObjectsErrorHelpers.decorateOpenSearchUnavailableError(new Error('foo')); expect(error.output).toHaveProperty('statusCode', 503); }); it('preserves boom properties of input', () => { const error = Boom.notFound(); - SavedObjectsErrorHelpers.decorateEsUnavailableError(error); + SavedObjectsErrorHelpers.decorateOpenSearchUnavailableError(error); expect(error.output).toHaveProperty('statusCode', 404); }); }); diff --git a/src/core/server/saved_objects/service/lib/errors.ts b/src/core/server/saved_objects/service/lib/errors.ts index 6fd5bc9de0ec..12d39bd298b7 100644 --- a/src/core/server/saved_objects/service/lib/errors.ts +++ b/src/core/server/saved_objects/service/lib/errors.ts @@ -35,10 +35,10 @@ const CODE_NOT_FOUND = 'SavedObjectsClient/notFound'; const CODE_CONFLICT = 'SavedObjectsClient/conflict'; // 429 - Too Many Requests const CODE_TOO_MANY_REQUESTS = 'SavedObjectsClient/tooManyRequests'; -// 400 - Es Cannot Execute Script -const CODE_ES_CANNOT_EXECUTE_SCRIPT = 'SavedObjectsClient/esCannotExecuteScript'; -// 503 - Es Unavailable -const CODE_ES_UNAVAILABLE = 'SavedObjectsClient/esUnavailable'; +// 400 - OpenSearch Cannot Execute Script +const CODE_OPENSEARCH_CANNOT_EXECUTE_SCRIPT = 'SavedObjectsClient/esCannotExecuteScript'; +// 503 - OpenSearch Unavailable +const CODE_OPENSEARCH_UNAVAILABLE = 'SavedObjectsClient/esUnavailable'; // 500 - General Error const CODE_GENERAL_ERROR = 'SavedObjectsClient/generalError'; @@ -176,20 +176,20 @@ export class SavedObjectsErrorHelpers { return isSavedObjectsClientError(error) && error[code] === CODE_TOO_MANY_REQUESTS; } - public static decorateEsCannotExecuteScriptError(error: Error, reason?: string) { - return decorate(error, CODE_ES_CANNOT_EXECUTE_SCRIPT, 400, reason); + public static decorateOpenSearchCannotExecuteScriptError(error: Error, reason?: string) { + return decorate(error, CODE_OPENSEARCH_CANNOT_EXECUTE_SCRIPT, 400, reason); } - public static isEsCannotExecuteScriptError(error: Error | DecoratedError) { - return isSavedObjectsClientError(error) && error[code] === CODE_ES_CANNOT_EXECUTE_SCRIPT; + public static isOpenSearchCannotExecuteScriptError(error: Error | DecoratedError) { + return isSavedObjectsClientError(error) && error[code] === CODE_OPENSEARCH_CANNOT_EXECUTE_SCRIPT; } - public static decorateEsUnavailableError(error: Error, reason?: string) { - return decorate(error, CODE_ES_UNAVAILABLE, 503, reason); + public static decorateOpenSearchUnavailableError(error: Error, reason?: string) { + return decorate(error, CODE_OPENSEARCH_UNAVAILABLE, 503, reason); } - public static isEsUnavailableError(error: Error | DecoratedError) { - return isSavedObjectsClientError(error) && error[code] === CODE_ES_UNAVAILABLE; + public static isOpenSearchUnavailableError(error: Error | DecoratedError) { + return isSavedObjectsClientError(error) && error[code] === CODE_OPENSEARCH_UNAVAILABLE; } public static decorateGeneralError(error: Error, reason?: string) { diff --git a/src/core/server/saved_objects/service/lib/filter_utils.test.ts b/src/core/server/saved_objects/service/lib/filter_utils.test.ts index 0608035ce51a..da1c27c9e2c3 100644 --- a/src/core/server/saved_objects/service/lib/filter_utils.test.ts +++ b/src/core/server/saved_objects/service/lib/filter_utils.test.ts @@ -17,7 +17,7 @@ * under the License. */ // @ts-expect-error no ts -import { esKuery } from '../../es_query'; +import { opensearchKuery } from '../../opensearch_query'; import { validateFilterKueryNode, validateConvertFilterToKueryNode } from './filter_utils'; @@ -90,15 +90,15 @@ describe('Filter Utils', () => { expect( validateConvertFilterToKueryNode( ['foo'], - esKuery.nodeTypes.function.buildNode('is', `foo.attributes.title`, 'best', true), + opensearchKuery.nodeTypes.function.buildNode('is', `foo.attributes.title`, 'best', true), mockMappings ) - ).toEqual(esKuery.fromKueryExpression('foo.title: "best"')); + ).toEqual(opensearchKuery.fromKueryExpression('foo.title: "best"')); }); test('Validate a simple KQL expression filter', () => { expect( validateConvertFilterToKueryNode(['foo'], 'foo.attributes.title: "best"', mockMappings) - ).toEqual(esKuery.fromKueryExpression('foo.title: "best"')); + ).toEqual(opensearchKuery.fromKueryExpression('foo.title: "best"')); }); test('Assemble filter kuery node saved object attributes with one saved object type', () => { expect( @@ -108,7 +108,7 @@ describe('Filter Utils', () => { mockMappings ) ).toEqual( - esKuery.fromKueryExpression( + opensearchKuery.fromKueryExpression( '(type: foo and updatedAt: 5678654567) and foo.bytes > 1000 and foo.bytes < 8000 and foo.title: "best" and (foo.description: t* or foo.description :*)' ) ); @@ -122,7 +122,7 @@ describe('Filter Utils', () => { mockMappings ) ).toEqual( - esKuery.fromKueryExpression( + opensearchKuery.fromKueryExpression( '(type: foo and updatedAt: 5678654567) and foo.bytes > 1000 and foo.bytes < 8000 and foo.title: "best" and (foo.description: t* or foo.description :*)' ) ); @@ -136,7 +136,7 @@ describe('Filter Utils', () => { mockMappings ) ).toEqual( - esKuery.fromKueryExpression( + opensearchKuery.fromKueryExpression( '((type: bar and updatedAt: 5678654567) or (type: foo and updatedAt: 5678654567)) and foo.bytes > 1000 and foo.bytes < 8000 and foo.title: "best" and (foo.description: t* or bar.description :*)' ) ); @@ -149,7 +149,7 @@ describe('Filter Utils', () => { 'alert.attributes.actions:{ actionTypeId: ".server-log" }', mockMappings ) - ).toEqual(esKuery.fromKueryExpression('alert.actions:{ actionTypeId: ".server-log" }')); + ).toEqual(opensearchKuery.fromKueryExpression('alert.actions:{ actionTypeId: ".server-log" }')); }); test('Lets make sure that we are throwing an exception if we get an error', () => { @@ -174,7 +174,7 @@ describe('Filter Utils', () => { describe('#validateFilterKueryNode', () => { test('Validate filter query through KueryNode - happy path', () => { const validationObject = validateFilterKueryNode({ - astFilter: esKuery.fromKueryExpression( + astFilter: opensearchKuery.fromKueryExpression( 'foo.updatedAt: 5678654567 and foo.attributes.bytes > 1000 and foo.attributes.bytes < 8000 and foo.attributes.title: "best" and (foo.attributes.description: t* or foo.attributes.description :*)' ), types: ['foo'], @@ -229,7 +229,7 @@ describe('Filter Utils', () => { test('Validate nested filter query through KueryNode - happy path', () => { const validationObject = validateFilterKueryNode({ - astFilter: esKuery.fromKueryExpression( + astFilter: opensearchKuery.fromKueryExpression( 'alert.attributes.actions:{ actionTypeId: ".server-log" }' ), types: ['alert'], @@ -249,7 +249,7 @@ describe('Filter Utils', () => { test('Return Error if key is not wrapper by a saved object type', () => { const validationObject = validateFilterKueryNode({ - astFilter: esKuery.fromKueryExpression( + astFilter: opensearchKuery.fromKueryExpression( 'updatedAt: 5678654567 and foo.attributes.bytes > 1000 and foo.attributes.bytes < 8000 and foo.attributes.title: "best" and (foo.attributes.description: t* or foo.attributes.description :*)' ), types: ['foo'], @@ -304,7 +304,7 @@ describe('Filter Utils', () => { test('Return Error if key of a saved object type is not wrapped with attributes', () => { const validationObject = validateFilterKueryNode({ - astFilter: esKuery.fromKueryExpression( + astFilter: opensearchKuery.fromKueryExpression( 'foo.updatedAt: 5678654567 and foo.attributes.bytes > 1000 and foo.bytes < 8000 and foo.attributes.title: "best" and (foo.attributes.description: t* or foo.description :*)' ), types: ['foo'], @@ -361,7 +361,7 @@ describe('Filter Utils', () => { test('Return Error if filter is not using an allowed type', () => { const validationObject = validateFilterKueryNode({ - astFilter: esKuery.fromKueryExpression( + astFilter: opensearchKuery.fromKueryExpression( 'bar.updatedAt: 5678654567 and foo.attributes.bytes > 1000 and foo.attributes.bytes < 8000 and foo.attributes.title: "best" and (foo.attributes.description: t* or foo.attributes.description :*)' ), types: ['foo'], @@ -416,7 +416,7 @@ describe('Filter Utils', () => { test('Return Error if filter is using an non-existing key in the index patterns of the saved object type', () => { const validationObject = validateFilterKueryNode({ - astFilter: esKuery.fromKueryExpression( + astFilter: opensearchKuery.fromKueryExpression( 'foo.updatedAt33: 5678654567 and foo.attributes.bytes > 1000 and foo.attributes.bytes < 8000 and foo.attributes.header: "best" and (foo.attributes.description: t* or foo.attributes.description :*)' ), types: ['foo'], @@ -472,7 +472,7 @@ describe('Filter Utils', () => { test('Return Error if filter is using an non-existing key null key', () => { const validationObject = validateFilterKueryNode({ - astFilter: esKuery.fromKueryExpression('foo.attributes.description: hello AND bye'), + astFilter: opensearchKuery.fromKueryExpression('foo.attributes.description: hello AND bye'), types: ['foo'], indexMapping: mockMappings, }); diff --git a/src/core/server/saved_objects/service/lib/filter_utils.ts b/src/core/server/saved_objects/service/lib/filter_utils.ts index be36807f0d02..4eefce595559 100644 --- a/src/core/server/saved_objects/service/lib/filter_utils.ts +++ b/src/core/server/saved_objects/service/lib/filter_utils.ts @@ -22,7 +22,7 @@ import { get } from 'lodash'; import { SavedObjectsErrorHelpers } from './errors'; import { IndexMapping } from '../../mappings'; // @ts-expect-error no ts -import { esKuery } from '../../es_query'; +import { opensearchKuery } from '../../opensearch_query'; type KueryNode = any; const astFunctionType = ['is', 'range', 'nested']; @@ -34,7 +34,7 @@ export const validateConvertFilterToKueryNode = ( ): KueryNode | undefined => { if (filter && indexMapping) { const filterKueryNode = - typeof filter === 'string' ? esKuery.fromKueryExpression(filter) : filter; + typeof filter === 'string' ? opensearchKuery.fromKueryExpression(filter) : filter; const validationFilterKuery = validateFilterKueryNode({ astFilter: filterKueryNode, @@ -71,8 +71,8 @@ export const validateConvertFilterToKueryNode = ( set( filterKueryNode, path, - esKuery.nodeTypes.function.buildNode('and', [ - esKuery.nodeTypes.function.buildNode('is', 'type', itemType[0]), + opensearchKuery.nodeTypes.function.buildNode('and', [ + opensearchKuery.nodeTypes.function.buildNode('is', 'type', itemType[0]), existingKueryNode, ]) ); diff --git a/src/core/server/saved_objects/service/lib/included_fields.ts b/src/core/server/saved_objects/service/lib/included_fields.ts index 63d8f184ed2f..4a4ab7e6f879 100644 --- a/src/core/server/saved_objects/service/lib/included_fields.ts +++ b/src/core/server/saved_objects/service/lib/included_fields.ts @@ -21,7 +21,7 @@ function toArray(value: string | string[]): string[] { return typeof value === 'string' ? [value] : value; } /** - * Provides an array of paths for ES source filtering + * Provides an array of paths for OpenSearch source filtering */ export function includedFields(type: string | string[] = '*', fields?: string[] | string) { if (!fields || fields.length === 0) { diff --git a/src/core/server/saved_objects/service/lib/repository.test.js b/src/core/server/saved_objects/service/lib/repository.test.js index e93bdb34ecc7..76b8c2660e2f 100644 --- a/src/core/server/saved_objects/service/lib/repository.test.js +++ b/src/core/server/saved_objects/service/lib/repository.test.js @@ -25,9 +25,9 @@ import { SavedObjectsSerializer } from '../../serialization'; import { encodeHitVersion } from '../../version'; import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { DocumentMigrator } from '../../migrations/core/document_migrator'; -import { elasticsearchClientMock } from '../../../elasticsearch/client/mocks'; -import { esKuery } from '../../es_query'; -const { nodeTypes } = esKuery; +import { opensearchClientMock } from '../../../opensearch/client/mocks'; +import { opensearchKuery } from '../../opensearch_query'; +const { nodeTypes } = opensearchKuery; jest.mock('./search_dsl/search_dsl', () => ({ getSearchDsl: jest.fn() })); @@ -152,7 +152,7 @@ describe('SavedObjectsRepository', () => { const documentMigrator = new DocumentMigrator({ typeRegistry: registry, - kibanaVersion: '2.0.0', + opensearchDashboardsVersion: '2.0.0', log: {}, }); @@ -162,7 +162,7 @@ describe('SavedObjectsRepository', () => { ) => { const namespaceId = objectNamespace === 'default' ? undefined : objectNamespace ?? namespace; return { - // NOTE: Elasticsearch returns more fields (_index, _type) but the SavedObjectsRepository method ignores these + // NOTE: OpenSearch returns more fields (_index, _type) but the SavedObjectsRepository method ignores these found: true, _id: `${ registry.isSingleNamespace(type) && namespaceId ? `${namespaceId}:` : '' @@ -214,7 +214,7 @@ describe('SavedObjectsRepository', () => { }; beforeEach(() => { - client = elasticsearchClientMock.createElasticsearchClient(); + client = opensearchClientMock.createOpenSearchClient(); migrator = { migrateDocument: jest.fn().mockImplementation(documentMigrator.migrate), runMigrations: async () => ({ status: 'skipped' }), @@ -237,7 +237,7 @@ describe('SavedObjectsRepository', () => { const allowedTypes = [...new Set(allTypes.filter((type) => !registry.isHidden(type)))]; savedObjectsRepository = new SavedObjectsRepository({ - index: '.kibana-test', + index: '.opensearch-dashboards-test', mappings, client, migrator, @@ -274,14 +274,14 @@ describe('SavedObjectsRepository', () => { const mockResponse = getMockGetResponse({ type, id }); mockResponse._source.namespaces = [currentNs1, currentNs2]; client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(mockResponse) + opensearchClientMock.createSuccessTransportRequestPromise(mockResponse) ); }; const addToNamespacesSuccess = async (type, id, namespaces, options) => { mockGetResponse(type, id); client.update.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ _id: `${type}:${id}`, ...mockVersionProps, result: 'updated', @@ -294,7 +294,7 @@ describe('SavedObjectsRepository', () => { }; describe('client calls', () => { - it(`should use ES get action then update action`, async () => { + it(`should use OpenSearch get action then update action`, async () => { await addToNamespacesSuccess(type, id, [newNs1, newNs2]); }); @@ -370,17 +370,17 @@ describe('SavedObjectsRepository', () => { await test([]); }); - it(`throws when ES is unable to find the document during get`, async () => { + it(`throws when OpenSearch is unable to find the document during get`, async () => { client.get.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ found: false }) + opensearchClientMock.createSuccessTransportRequestPromise({ found: false }) ); await expectNotFoundError(type, id, [newNs1, newNs2]); expect(client.get).toHaveBeenCalledTimes(1); }); - it(`throws when ES is unable to find the index during get`, async () => { + it(`throws when OpenSearch is unable to find the index during get`, async () => { client.get.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + opensearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) ); await expectNotFoundError(type, id, [newNs1, newNs2]); expect(client.get).toHaveBeenCalledTimes(1); @@ -394,10 +394,10 @@ describe('SavedObjectsRepository', () => { expect(client.get).toHaveBeenCalledTimes(1); }); - it(`throws when ES is unable to find the document during update`, async () => { + it(`throws when OpenSearch is unable to find the document during update`, async () => { mockGetResponse(type, id); client.update.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + opensearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) ); await expectNotFoundError(type, id, [newNs1, newNs2]); expect(client.get).toHaveBeenCalledTimes(1); @@ -461,12 +461,12 @@ describe('SavedObjectsRepository', () => { if (multiNamespaceObjects?.length) { const response = getMockMgetResponse(multiNamespaceObjects, options?.namespace); client.mget.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); } const response = getMockBulkCreateResponse(objects, options?.namespace); client.bulk.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); const result = await savedObjectsRepository.bulkCreate(objects, options); expect(client.mget).toHaveBeenCalledTimes(multiNamespaceObjects?.length ? 1 : 0); @@ -517,12 +517,12 @@ describe('SavedObjectsRepository', () => { }); describe('client calls', () => { - it(`should use the ES bulk action by default`, async () => { + it(`should use the OpenSearch bulk action by default`, async () => { await bulkCreateSuccess([obj1, obj2]); expect(client.bulk).toHaveBeenCalledTimes(1); }); - it(`should use the ES mget action before bulk action for any types that are multi-namespace, when id is defined`, async () => { + it(`should use the OpenSearch mget action before bulk action for any types that are multi-namespace, when id is defined`, async () => { const objects = [obj1, { ...obj2, type: MULTI_NAMESPACE_TYPE }]; await bulkCreateSuccess(objects); expect(client.bulk).toHaveBeenCalledTimes(1); @@ -531,24 +531,24 @@ describe('SavedObjectsRepository', () => { expect(client.mget.mock.calls[0][0].body).toEqual({ docs }); }); - it(`should use the ES create method if ID is undefined and overwrite=true`, async () => { + it(`should use the OpenSearch create method if ID is undefined and overwrite=true`, async () => { const objects = [obj1, obj2].map((obj) => ({ ...obj, id: undefined })); await bulkCreateSuccess(objects, { overwrite: true }); expectClientCallArgsAction(objects, { method: 'create' }); }); - it(`should use the ES create method if ID is undefined and overwrite=false`, async () => { + it(`should use the OpenSearch create method if ID is undefined and overwrite=false`, async () => { const objects = [obj1, obj2].map((obj) => ({ ...obj, id: undefined })); await bulkCreateSuccess(objects); expectClientCallArgsAction(objects, { method: 'create' }); }); - it(`should use the ES index method if ID is defined and overwrite=true`, async () => { + it(`should use the OpenSearch index method if ID is defined and overwrite=true`, async () => { await bulkCreateSuccess([obj1, obj2], { overwrite: true }); expectClientCallArgsAction([obj1, obj2], { method: 'index' }); }); - it(`should use the ES index method with version if ID and version are defined and overwrite=true`, async () => { + it(`should use the OpenSearch index method with version if ID and version are defined and overwrite=true`, async () => { await bulkCreateSuccess( [ { @@ -569,12 +569,12 @@ describe('SavedObjectsRepository', () => { expectClientCallArgsAction([obj1WithSeq, obj2], { method: 'index' }); }); - it(`should use the ES create method if ID is defined and overwrite=false`, async () => { + it(`should use the OpenSearch create method if ID is defined and overwrite=false`, async () => { await bulkCreateSuccess([obj1, obj2]); expectClientCallArgsAction([obj1, obj2], { method: 'create' }); }); - it(`formats the ES request`, async () => { + it(`formats the OpenSearch request`, async () => { await bulkCreateSuccess([obj1, obj2]); const body = [...expectObjArgs(obj1), ...expectObjArgs(obj2)]; expect(client.bulk).toHaveBeenCalledWith( @@ -687,7 +687,7 @@ describe('SavedObjectsRepository', () => { it(`should use default index`, async () => { await bulkCreateSuccess([obj1, obj2]); - expectClientCallArgsAction([obj1, obj2], { method: 'create', _index: '.kibana-test' }); + expectClientCallArgsAction([obj1, obj2], { method: 'create', _index: '.opensearch-dashboards-test' }); }); it(`should use custom index`, async () => { @@ -726,22 +726,22 @@ describe('SavedObjectsRepository', () => { references: [{ name: 'ref_0', type: 'test', id: '2' }], }; - const bulkCreateError = async (obj, esError, expectedError) => { + const bulkCreateError = async (obj, opensearchError, expectedError) => { let response; - if (esError) { + if (opensearchError) { response = getMockBulkCreateResponse([obj1, obj, obj2]); - response.items[1].create = { error: esError }; + response.items[1].create = { error: opensearchError }; } else { response = getMockBulkCreateResponse([obj1, obj2]); } client.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); const objects = [obj1, obj, obj2]; const result = await savedObjectsRepository.bulkCreate(objects); expect(client.bulk).toHaveBeenCalled(); - const objCall = esError ? expectObjArgs(obj) : []; + const objCall = opensearchError ? expectObjArgs(obj) : []; const body = [...expectObjArgs(obj1), ...objCall, ...expectObjArgs(obj2)]; expect(client.bulk).toHaveBeenCalledWith( expect.objectContaining({ body }), @@ -811,11 +811,11 @@ describe('SavedObjectsRepository', () => { ], }; client.mget.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response1) + opensearchClientMock.createSuccessTransportRequestPromise(response1) ); const response2 = getMockBulkCreateResponse([obj1, obj2]); client.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response2) + opensearchClientMock.createSuccessTransportRequestPromise(response2) ); const options = { overwrite: true }; @@ -840,24 +840,24 @@ describe('SavedObjectsRepository', () => { }); it(`returns error when there is a version conflict (bulk)`, async () => { - const esError = { type: 'version_conflict_engine_exception' }; - await bulkCreateError(obj3, esError, expectErrorConflict(obj3)); + const opensearchError = { type: 'version_conflict_engine_exception' }; + await bulkCreateError(obj3, opensearchError, expectErrorConflict(obj3)); }); it(`returns error when document is missing`, async () => { - const esError = { type: 'document_missing_exception' }; - await bulkCreateError(obj3, esError, expectErrorNotFound(obj3)); + const opensearchError = { type: 'document_missing_exception' }; + await bulkCreateError(obj3, opensearchError, expectErrorNotFound(obj3)); }); it(`returns error reason for other errors`, async () => { - const esError = { reason: 'some_other_error' }; - await bulkCreateError(obj3, esError, expectErrorResult(obj3, { message: esError.reason })); + const opensearchError = { reason: 'some_other_error' }; + await bulkCreateError(obj3, opensearchError, expectErrorResult(obj3, { message: opensearchError.reason })); }); it(`returns error string for other errors if no reason is defined`, async () => { - const esError = { foo: 'some_other_error' }; - const expectedError = expectErrorResult(obj3, { message: JSON.stringify(esError) }); - await bulkCreateError(obj3, esError, expectedError); + const opensearchError = { foo: 'some_other_error' }; + const expectedError = expectErrorResult(obj3, { message: JSON.stringify(opensearchError) }); + await bulkCreateError(obj3, opensearchError, expectedError); }); }); @@ -919,7 +919,7 @@ describe('SavedObjectsRepository', () => { }); describe('returns', () => { - it(`formats the ES response`, async () => { + it(`formats the OpenSearch response`, async () => { const result = await bulkCreateSuccess([obj1, obj2]); expect(result).toEqual({ saved_objects: [obj1, obj2].map((x) => expectSuccessResult(x)), @@ -936,7 +936,7 @@ describe('SavedObjectsRepository', () => { const objects = [obj1, obj, obj2]; const response = getMockBulkCreateResponse([obj1, obj2]); client.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); const result = await savedObjectsRepository.bulkCreate(objects); expect(client.bulk).toHaveBeenCalledTimes(1); @@ -951,7 +951,7 @@ describe('SavedObjectsRepository', () => { const namespace = 'myspace'; const response = getMockBulkCreateResponse([obj1, obj2], namespace); client.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); // Bulk create one object with id unspecified, and one with id specified @@ -959,7 +959,7 @@ describe('SavedObjectsRepository', () => { namespace, }); - // Assert that both raw docs from the ES response are deserialized + // Assert that both raw docs from the OpenSearch response are deserialized expect(serializer.rawToSavedObject).toHaveBeenNthCalledWith(1, { ...response.items[0].create, _source: { @@ -1021,7 +1021,7 @@ describe('SavedObjectsRepository', () => { const bulkGetSuccess = async (objects, options) => { const response = getMockMgetResponse(objects, options?.namespace); client.mget.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); const result = await bulkGet(objects, options); expect(client.mget).toHaveBeenCalledTimes(1); @@ -1083,7 +1083,7 @@ describe('SavedObjectsRepository', () => { const bulkGetErrorInvalidType = async ([obj1, obj, obj2]) => { const response = getMockMgetResponse([obj1, obj2]); client.mget.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); const result = await bulkGet([obj1, obj, obj2]); expect(client.mget).toHaveBeenCalled(); @@ -1094,7 +1094,7 @@ describe('SavedObjectsRepository', () => { const bulkGetErrorNotFound = async ([obj1, obj, obj2], options, response) => { client.mget.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); const result = await bulkGet([obj1, obj, obj2], options); expect(client.mget).toHaveBeenCalled(); @@ -1159,10 +1159,10 @@ describe('SavedObjectsRepository', () => { expect(client.mget).not.toHaveBeenCalled(); }); - it(`formats the ES response`, async () => { + it(`formats the OpenSearch response`, async () => { const response = getMockMgetResponse([obj1, obj2]); client.mget.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); const result = await bulkGet([obj1, obj2]); expect(client.mget).toHaveBeenCalledTimes(1); @@ -1177,7 +1177,7 @@ describe('SavedObjectsRepository', () => { it(`handles a mix of successful gets and errors`, async () => { const response = getMockMgetResponse([obj1, obj2]); client.mget.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); const obj = { type: 'unknownType', id: 'three' }; const result = await bulkGet([obj1, obj, obj2]); @@ -1243,12 +1243,12 @@ describe('SavedObjectsRepository', () => { if (multiNamespaceObjects?.length) { const response = getMockMgetResponse(multiNamespaceObjects, options?.namespace); client.mget.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); } const response = getMockBulkUpdateResponse(objects, options?.namespace, includeOriginId); client.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); const result = await savedObjectsRepository.bulkUpdate(objects, options); expect(client.mget).toHaveBeenCalledTimes(multiNamespaceObjects?.length ? 1 : 0); @@ -1288,12 +1288,12 @@ describe('SavedObjectsRepository', () => { ]; describe('client calls', () => { - it(`should use the ES bulk action by default`, async () => { + it(`should use the OpenSearch bulk action by default`, async () => { await bulkUpdateSuccess([obj1, obj2]); expect(client.bulk).toHaveBeenCalled(); }); - it(`should use the ES mget action before bulk action for any types that are multi-namespace`, async () => { + it(`should use the OpenSearch mget action before bulk action for any types that are multi-namespace`, async () => { const objects = [obj1, { ...obj2, type: MULTI_NAMESPACE_TYPE }]; await bulkUpdateSuccess(objects); expect(client.bulk).toHaveBeenCalled(); @@ -1306,7 +1306,7 @@ describe('SavedObjectsRepository', () => { ); }); - it(`formats the ES request`, async () => { + it(`formats the OpenSearch request`, async () => { await bulkUpdateSuccess([obj1, obj2]); const body = [...expectObjArgs(obj1), ...expectObjArgs(obj2)]; expect(client.bulk).toHaveBeenCalledWith( @@ -1315,7 +1315,7 @@ describe('SavedObjectsRepository', () => { ); }); - it(`formats the ES request for any types that are multi-namespace`, async () => { + it(`formats the OpenSearch request for any types that are multi-namespace`, async () => { const _obj2 = { ...obj2, type: MULTI_NAMESPACE_TYPE }; await bulkUpdateSuccess([obj1, _obj2]); const body = [...expectObjArgs(obj1), ...expectObjArgs(_obj2)]; @@ -1325,7 +1325,7 @@ describe('SavedObjectsRepository', () => { ); }); - it(`doesnt call Elasticsearch if there are no valid objects to update`, async () => { + it(`doesnt call OpenSearch if there are no valid objects to update`, async () => { const objects = [obj1, obj2].map((x) => ({ ...x, type: 'unknownType' })); await savedObjectsRepository.bulkUpdate(objects); expect(client.bulk).toHaveBeenCalledTimes(0); @@ -1486,19 +1486,19 @@ describe('SavedObjectsRepository', () => { id: 'three', }; - const bulkUpdateError = async (obj, esError, expectedError) => { + const bulkUpdateError = async (obj, opensearchError, expectedError) => { const objects = [obj1, obj, obj2]; const mockResponse = getMockBulkUpdateResponse(objects); - if (esError) { - mockResponse.items[1].update = { error: esError }; + if (opensearchError) { + mockResponse.items[1].update = { error: opensearchError }; } client.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(mockResponse) + opensearchClientMock.createSuccessTransportRequestPromise(mockResponse) ); const result = await savedObjectsRepository.bulkUpdate(objects); expect(client.bulk).toHaveBeenCalled(); - const objCall = esError ? expectObjArgs(obj) : []; + const objCall = opensearchError ? expectObjArgs(obj) : []; const body = [...expectObjArgs(obj1), ...objCall, ...expectObjArgs(obj2)]; expect(client.bulk).toHaveBeenCalledWith( expect.objectContaining({ body }), @@ -1511,14 +1511,14 @@ describe('SavedObjectsRepository', () => { const bulkUpdateMultiError = async ([obj1, _obj, obj2], options, mgetResponse) => { client.mget.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(mgetResponse, { + opensearchClientMock.createSuccessTransportRequestPromise(mgetResponse, { statusCode: mgetResponse.statusCode, }) ); const bulkResponse = getMockBulkUpdateResponse([obj1, obj2], namespace); client.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(bulkResponse) + opensearchClientMock.createSuccessTransportRequestPromise(bulkResponse) ); const result = await savedObjectsRepository.bulkUpdate([obj1, _obj, obj2], options); @@ -1560,13 +1560,13 @@ describe('SavedObjectsRepository', () => { ); }); - it(`returns error when ES is unable to find the document (mget)`, async () => { + it(`returns error when OpenSearch is unable to find the document (mget)`, async () => { const _obj = { ...obj, type: MULTI_NAMESPACE_TYPE, found: false }; const mgetResponse = getMockMgetResponse([_obj]); await bulkUpdateMultiError([obj1, _obj, obj2], undefined, mgetResponse); }); - it(`returns error when ES is unable to find the index (mget)`, async () => { + it(`returns error when OpenSearch is unable to find the index (mget)`, async () => { const _obj = { ...obj, type: MULTI_NAMESPACE_TYPE }; const mgetResponse = { statusCode: 404 }; await bulkUpdateMultiError([obj1, _obj, obj2], { namespace }, mgetResponse); @@ -1579,24 +1579,24 @@ describe('SavedObjectsRepository', () => { }); it(`returns error when there is a version conflict (bulk)`, async () => { - const esError = { type: 'version_conflict_engine_exception' }; - await bulkUpdateError(obj, esError, expectErrorConflict(obj)); + const opensearchError = { type: 'version_conflict_engine_exception' }; + await bulkUpdateError(obj, opensearchError, expectErrorConflict(obj)); }); it(`returns error when document is missing (bulk)`, async () => { - const esError = { type: 'document_missing_exception' }; - await bulkUpdateError(obj, esError, expectErrorNotFound(obj)); + const opensearchError = { type: 'document_missing_exception' }; + await bulkUpdateError(obj, opensearchError, expectErrorNotFound(obj)); }); it(`returns error reason for other errors (bulk)`, async () => { - const esError = { reason: 'some_other_error' }; - await bulkUpdateError(obj, esError, expectErrorResult(obj, { message: esError.reason })); + const opensearchError = { reason: 'some_other_error' }; + await bulkUpdateError(obj, opensearchError, expectErrorResult(obj, { message: opensearchError.reason })); }); it(`returns error string for other errors if no reason is defined (bulk)`, async () => { - const esError = { foo: 'some_other_error' }; - const expectedError = expectErrorResult(obj, { message: JSON.stringify(esError) }); - await bulkUpdateError(obj, esError, expectedError); + const opensearchError = { foo: 'some_other_error' }; + const expectedError = expectErrorResult(obj, { message: JSON.stringify(opensearchError) }); + await bulkUpdateError(obj, opensearchError, expectedError); }); }); @@ -1612,7 +1612,7 @@ describe('SavedObjectsRepository', () => { ...mockTimestampFields, }); - it(`formats the ES response`, async () => { + it(`formats the OpenSearch response`, async () => { const response = await bulkUpdateSuccess([obj1, obj2]); expect(response).toEqual({ saved_objects: [obj1, obj2].map(expectSuccessResult), @@ -1635,7 +1635,7 @@ describe('SavedObjectsRepository', () => { const objects = [obj1, obj, obj2]; const mockResponse = getMockBulkUpdateResponse(objects); client.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(mockResponse) + opensearchClientMock.createSuccessTransportRequestPromise(mockResponse) ); const result = await savedObjectsRepository.bulkUpdate(objects); @@ -1687,7 +1687,7 @@ describe('SavedObjectsRepository', () => { const checkConflictsSuccess = async (objects, options) => { const response = getMockMgetResponse(objects, options?.namespace); client.mget.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); const result = await checkConflicts(objects, options); expect(client.mget).toHaveBeenCalledTimes(1); @@ -1771,7 +1771,7 @@ describe('SavedObjectsRepository', () => { ], }; client.mget.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); const result = await checkConflicts(objects); @@ -1802,7 +1802,7 @@ describe('SavedObjectsRepository', () => { describe('#create', () => { beforeEach(() => { client.create.mockImplementation((params) => - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ _id: params.id, ...mockVersionProps, }) @@ -1831,22 +1831,22 @@ describe('SavedObjectsRepository', () => { }; describe('client calls', () => { - it(`should use the ES create action if ID is undefined and overwrite=true`, async () => { + it(`should use the OpenSearch create action if ID is undefined and overwrite=true`, async () => { await createSuccess(type, attributes, { overwrite: true }); expect(client.create).toHaveBeenCalled(); }); - it(`should use the ES create action if ID is undefined and overwrite=false`, async () => { + it(`should use the OpenSearch create action if ID is undefined and overwrite=false`, async () => { await createSuccess(type, attributes); expect(client.create).toHaveBeenCalled(); }); - it(`should use the ES index action if ID is defined and overwrite=true`, async () => { + it(`should use the OpenSearch index action if ID is defined and overwrite=true`, async () => { await createSuccess(type, attributes, { id, overwrite: true }); expect(client.index).toHaveBeenCalled(); }); - it(`should use the ES index with version if ID and version are defined and overwrite=true`, async () => { + it(`should use the OpenSearch index with version if ID and version are defined and overwrite=true`, async () => { await createSuccess(type, attributes, { id, overwrite: true, version: mockVersion }); expect(client.index).toHaveBeenCalled(); @@ -1856,12 +1856,12 @@ describe('SavedObjectsRepository', () => { }); }); - it(`should use the ES create action if ID is defined and overwrite=false`, async () => { + it(`should use the OpenSearch create action if ID is defined and overwrite=false`, async () => { await createSuccess(type, attributes, { id }); expect(client.create).toHaveBeenCalled(); }); - it(`should use the ES get action then index action if type is multi-namespace, ID is defined, and overwrite=true`, async () => { + it(`should use the OpenSearch get action then index action if type is multi-namespace, ID is defined, and overwrite=true`, async () => { await createSuccess(MULTI_NAMESPACE_TYPE, attributes, { id, overwrite: true }); expect(client.get).toHaveBeenCalled(); expect(client.index).toHaveBeenCalled(); @@ -1926,7 +1926,7 @@ describe('SavedObjectsRepository', () => { it(`should use default index`, async () => { await createSuccess(type, attributes, { id }); expect(client.create).toHaveBeenCalledWith( - expect.objectContaining({ index: '.kibana-test' }), + expect.objectContaining({ index: '.opensearch-dashboards-test' }), expect.anything() ); }); @@ -2066,7 +2066,7 @@ describe('SavedObjectsRepository', () => { it(`throws when there is a conflict with an existing multi-namespace saved object (get)`, async () => { const response = getMockGetResponse({ type: MULTI_NAMESPACE_TYPE, id }, 'bar-namespace'); client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); await expect( savedObjectsRepository.create(MULTI_NAMESPACE_TYPE, attributes, { @@ -2138,7 +2138,7 @@ describe('SavedObjectsRepository', () => { }); describe('returns', () => { - it(`formats the ES response`, async () => { + it(`formats the OpenSearch response`, async () => { const result = await createSuccess(type, attributes, { id, namespace, @@ -2169,11 +2169,11 @@ describe('SavedObjectsRepository', () => { if (registry.isMultiNamespace(type)) { const mockGetResponse = getMockGetResponse({ type, id }, options?.namespace); client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(mockGetResponse) + opensearchClientMock.createSuccessTransportRequestPromise(mockGetResponse) ); } client.delete.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ result: 'deleted' }) + opensearchClientMock.createSuccessTransportRequestPromise({ result: 'deleted' }) ); const result = await savedObjectsRepository.delete(type, id, options); expect(client.get).toHaveBeenCalledTimes(registry.isMultiNamespace(type) ? 1 : 0); @@ -2181,13 +2181,13 @@ describe('SavedObjectsRepository', () => { }; describe('client calls', () => { - it(`should use the ES delete action when not using a multi-namespace type`, async () => { + it(`should use the OpenSearch delete action when not using a multi-namespace type`, async () => { await deleteSuccess(type, id); expect(client.get).not.toHaveBeenCalled(); expect(client.delete).toHaveBeenCalledTimes(1); }); - it(`should use ES get action then delete action when using a multi-namespace type`, async () => { + it(`should use OpenSearch get action then delete action when using a multi-namespace type`, async () => { await deleteSuccess(MULTI_NAMESPACE_TYPE, id); expect(client.get).toHaveBeenCalledTimes(1); expect(client.delete).toHaveBeenCalledTimes(1); @@ -2276,17 +2276,17 @@ describe('SavedObjectsRepository', () => { expect(client.delete).not.toHaveBeenCalled(); }); - it(`throws when ES is unable to find the document during get`, async () => { + it(`throws when OpenSearch is unable to find the document during get`, async () => { client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ found: false }) + opensearchClientMock.createSuccessTransportRequestPromise({ found: false }) ); await expectNotFoundError(MULTI_NAMESPACE_TYPE, id); expect(client.get).toHaveBeenCalledTimes(1); }); - it(`throws when ES is unable to find the index during get`, async () => { + it(`throws when OpenSearch is unable to find the index during get`, async () => { client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + opensearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) ); await expectNotFoundError(MULTI_NAMESPACE_TYPE, id); expect(client.get).toHaveBeenCalledTimes(1); @@ -2295,7 +2295,7 @@ describe('SavedObjectsRepository', () => { it(`throws when the type is multi-namespace and the document exists, but not in this namespace`, async () => { const response = getMockGetResponse({ type: MULTI_NAMESPACE_TYPE, id }, namespace); client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); await expectNotFoundError(MULTI_NAMESPACE_TYPE, id, { namespace: 'bar-namespace' }); expect(client.get).toHaveBeenCalledTimes(1); @@ -2305,7 +2305,7 @@ describe('SavedObjectsRepository', () => { const response = getMockGetResponse({ type: MULTI_NAMESPACE_TYPE, id, namespace }); response._source.namespaces = [namespace, 'bar-namespace']; client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); await expect( savedObjectsRepository.delete(MULTI_NAMESPACE_TYPE, id, { namespace }) @@ -2319,7 +2319,7 @@ describe('SavedObjectsRepository', () => { const response = getMockGetResponse({ type: MULTI_NAMESPACE_TYPE, id, namespace }); response._source.namespaces = ['*']; client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); await expect( savedObjectsRepository.delete(MULTI_NAMESPACE_TYPE, id, { namespace }) @@ -2329,17 +2329,17 @@ describe('SavedObjectsRepository', () => { expect(client.get).toHaveBeenCalledTimes(1); }); - it(`throws when ES is unable to find the document during delete`, async () => { + it(`throws when OpenSearch is unable to find the document during delete`, async () => { client.delete.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ result: 'not_found' }) + opensearchClientMock.createSuccessTransportRequestPromise({ result: 'not_found' }) ); await expectNotFoundError(type, id); expect(client.delete).toHaveBeenCalledTimes(1); }); - it(`throws when ES is unable to find the index during delete`, async () => { + it(`throws when OpenSearch is unable to find the index during delete`, async () => { client.delete.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ error: { type: 'index_not_found_exception' }, }) ); @@ -2347,14 +2347,14 @@ describe('SavedObjectsRepository', () => { expect(client.delete).toHaveBeenCalledTimes(1); }); - it(`throws when ES returns an unexpected response`, async () => { + it(`throws when OpenSearch returns an unexpected response`, async () => { client.delete.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ result: 'something unexpected', }) ); await expect(savedObjectsRepository.delete(type, id)).rejects.toThrowError( - 'Unexpected Elasticsearch DELETE response' + 'Unexpected OpenSearch DELETE response' ); expect(client.delete).toHaveBeenCalledTimes(1); }); @@ -2388,7 +2388,7 @@ describe('SavedObjectsRepository', () => { const deleteByNamespaceSuccess = async (namespace, options) => { client.updateByQuery.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(mockUpdateResults) + opensearchClientMock.createSuccessTransportRequestPromise(mockUpdateResults) ); const result = await savedObjectsRepository.deleteByNamespace(namespace, options); expect(getSearchDslNS.getSearchDsl).toHaveBeenCalledTimes(1); @@ -2397,7 +2397,7 @@ describe('SavedObjectsRepository', () => { }; describe('client calls', () => { - it(`should use the ES updateByQuery action`, async () => { + it(`should use the OpenSearch updateByQuery action`, async () => { await deleteByNamespaceSuccess(namespace); expect(client.updateByQuery).toHaveBeenCalledTimes(1); }); @@ -2405,7 +2405,7 @@ describe('SavedObjectsRepository', () => { it(`should use all indices for types that are not namespace-agnostic`, async () => { await deleteByNamespaceSuccess(namespace); expect(client.updateByQuery).toHaveBeenCalledWith( - expect.objectContaining({ index: ['.kibana-test', 'custom'] }), + expect.objectContaining({ index: ['.opensearch-dashboards-test', 'custom'] }), expect.anything() ); }); @@ -2453,7 +2453,7 @@ describe('SavedObjectsRepository', () => { total: 4, hits: [ { - _index: '.kibana', + _index: '.opensearch-dashboards', _id: `${namespace ? `${namespace}:` : ''}index-pattern:logstash-*`, _score: 1, ...mockVersionProps, @@ -2470,7 +2470,7 @@ describe('SavedObjectsRepository', () => { }, }, { - _index: '.kibana', + _index: '.opensearch-dashboards', _id: `${namespace ? `${namespace}:` : ''}config:6.0.0-alpha1`, _score: 2, ...mockVersionProps, @@ -2485,7 +2485,7 @@ describe('SavedObjectsRepository', () => { }, }, { - _index: '.kibana', + _index: '.opensearch-dashboards', _id: `${namespace ? `${namespace}:` : ''}index-pattern:stocks-*`, _score: 3, ...mockVersionProps, @@ -2501,7 +2501,7 @@ describe('SavedObjectsRepository', () => { }, }, { - _index: '.kibana', + _index: '.opensearch-dashboards', _id: `${NAMESPACE_AGNOSTIC_TYPE}:something`, _score: 4, ...mockVersionProps, @@ -2523,7 +2523,7 @@ describe('SavedObjectsRepository', () => { const findSuccess = async (options, namespace) => { client.search.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise( + opensearchClientMock.createSuccessTransportRequestPromise( generateSearchResults(namespace) ) ); @@ -2534,12 +2534,12 @@ describe('SavedObjectsRepository', () => { }; describe('client calls', () => { - it(`should use the ES search action`, async () => { + it(`should use the OpenSearch search action`, async () => { await findSuccess({ type }); expect(client.search).toHaveBeenCalledTimes(1); }); - it(`merges output of getSearchDsl into es request body`, async () => { + it(`merges output of getSearchDsl into opensearch request body`, async () => { const query = { query: 1, aggregations: 2 }; getSearchDslNS.getSearchDsl.mockReturnValue(query); await findSuccess({ type }); @@ -2692,10 +2692,10 @@ describe('SavedObjectsRepository', () => { }); describe('returns', () => { - it(`formats the ES response when there is no namespace`, async () => { + it(`formats the OpenSearch response when there is no namespace`, async () => { const noNamespaceSearchResults = generateSearchResults(); client.search.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(noNamespaceSearchResults) + opensearchClientMock.createSuccessTransportRequestPromise(noNamespaceSearchResults) ); const count = noNamespaceSearchResults.hits.hits.length; @@ -2719,10 +2719,10 @@ describe('SavedObjectsRepository', () => { }); }); - it(`formats the ES response when there is a namespace`, async () => { + it(`formats the OpenSearch response when there is a namespace`, async () => { const namespacedSearchResults = generateSearchResults(namespace); client.search.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(namespacedSearchResults) + opensearchClientMock.createSuccessTransportRequestPromise(namespacedSearchResults) ); const count = namespacedSearchResults.hits.hits.length; @@ -2952,7 +2952,7 @@ describe('SavedObjectsRepository', () => { options?.namespace ); client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); const result = await savedObjectsRepository.get(type, id, options); expect(client.get).toHaveBeenCalledTimes(1); @@ -2960,7 +2960,7 @@ describe('SavedObjectsRepository', () => { }; describe('client calls', () => { - it(`should use the ES get action`, async () => { + it(`should use the OpenSearch get action`, async () => { await getSuccess(type, id); expect(client.get).toHaveBeenCalledTimes(1); }); @@ -3038,17 +3038,17 @@ describe('SavedObjectsRepository', () => { expect(client.get).not.toHaveBeenCalled(); }); - it(`throws when ES is unable to find the document during get`, async () => { + it(`throws when OpenSearch is unable to find the document during get`, async () => { client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ found: false }) + opensearchClientMock.createSuccessTransportRequestPromise({ found: false }) ); await expectNotFoundError(type, id); expect(client.get).toHaveBeenCalledTimes(1); }); - it(`throws when ES is unable to find the index during get`, async () => { + it(`throws when OpenSearch is unable to find the index during get`, async () => { client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + opensearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) ); await expectNotFoundError(type, id); expect(client.get).toHaveBeenCalledTimes(1); @@ -3057,7 +3057,7 @@ describe('SavedObjectsRepository', () => { it(`throws when type is multi-namespace and the document exists, but not in this namespace`, async () => { const response = getMockGetResponse({ type: MULTI_NAMESPACE_TYPE, id }, namespace); client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); await expectNotFoundError(MULTI_NAMESPACE_TYPE, id, { namespace: 'bar-namespace' }); expect(client.get).toHaveBeenCalledTimes(1); @@ -3065,7 +3065,7 @@ describe('SavedObjectsRepository', () => { }); describe('returns', () => { - it(`formats the ES response`, async () => { + it(`formats the OpenSearch response`, async () => { const result = await getSuccess(type, id); expect(result).toEqual({ id, @@ -3113,14 +3113,14 @@ describe('SavedObjectsRepository', () => { if (isMultiNamespace) { const response = getMockGetResponse({ type, id }, options?.namespace); client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); } client.update.mockImplementation((params) => - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ _id: params.id, ...mockVersionProps, - _index: '.kibana', + _index: '.opensearch-dashboards', get: { found: true, _source: { @@ -3141,12 +3141,12 @@ describe('SavedObjectsRepository', () => { }; describe('client calls', () => { - it(`should use the ES update action if type is not multi-namespace`, async () => { + it(`should use the OpenSearch update action if type is not multi-namespace`, async () => { await incrementCounterSuccess(type, id, field, { namespace }); expect(client.update).toHaveBeenCalledTimes(1); }); - it(`should use the ES get action then update action if type is multi-namespace, ID is defined, and overwrite=true`, async () => { + it(`should use the OpenSearch get action then update action if type is multi-namespace, ID is defined, and overwrite=true`, async () => { await incrementCounterSuccess(MULTI_NAMESPACE_TYPE, id, field, { namespace }); expect(client.get).toHaveBeenCalledTimes(1); expect(client.update).toHaveBeenCalledTimes(1); @@ -3268,7 +3268,7 @@ describe('SavedObjectsRepository', () => { it(`throws when there is a conflict with an existing multi-namespace saved object (get)`, async () => { const response = getMockGetResponse({ type: MULTI_NAMESPACE_TYPE, id }, 'bar-namespace'); client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); await expect( savedObjectsRepository.incrementCounter(MULTI_NAMESPACE_TYPE, id, field, { namespace }) @@ -3295,12 +3295,12 @@ describe('SavedObjectsRepository', () => { }); describe('returns', () => { - it(`formats the ES response`, async () => { + it(`formats the OpenSearch response`, async () => { client.update.mockImplementation((params) => - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ _id: params.id, ...mockVersionProps, - _index: '.kibana', + _index: '.opensearch-dashboards', get: { found: true, _source: { @@ -3352,7 +3352,7 @@ describe('SavedObjectsRepository', () => { const mockResponse = getMockGetResponse({ type, id }); mockResponse._source.namespaces = namespaces; client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(mockResponse) + opensearchClientMock.createSuccessTransportRequestPromise(mockResponse) ); }; @@ -3365,14 +3365,14 @@ describe('SavedObjectsRepository', () => { ) => { mockGetResponse(type, id, currentNamespaces); client.delete.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ _id: `${type}:${id}`, ...mockVersionProps, result: 'deleted', }) ); client.update.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ _id: `${type}:${id}`, ...mockVersionProps, result: 'updated', @@ -3395,7 +3395,7 @@ describe('SavedObjectsRepository', () => { await test([namespace1, namespace2]); }; - it(`should use ES get action then delete action if the object has no namespaces remaining`, async () => { + it(`should use OpenSearch get action then delete action if the object has no namespaces remaining`, async () => { const expectFn = () => { expect(client.delete).toHaveBeenCalledTimes(1); expect(client.get).toHaveBeenCalledTimes(1); @@ -3403,7 +3403,7 @@ describe('SavedObjectsRepository', () => { await deleteFromNamespacesSuccessDelete(expectFn); }); - it(`formats the ES requests`, async () => { + it(`formats the OpenSearch requests`, async () => { const expectFn = () => { expect(client.delete).toHaveBeenCalledWith( expect.objectContaining({ @@ -3441,7 +3441,7 @@ describe('SavedObjectsRepository', () => { it(`should use default index`, async () => { const expectFn = () => expect(client.delete).toHaveBeenCalledWith( - expect.objectContaining({ index: '.kibana-test' }), + expect.objectContaining({ index: '.opensearch-dashboards-test' }), expect.anything() ); await deleteFromNamespacesSuccessDelete(expectFn); @@ -3470,7 +3470,7 @@ describe('SavedObjectsRepository', () => { await test([namespace2, namespace3]); }; - it(`should use ES get action then update action if the object has one or more namespaces remaining`, async () => { + it(`should use OpenSearch get action then update action if the object has one or more namespaces remaining`, async () => { const expectFn = () => { expect(client.update).toHaveBeenCalledTimes(1); expect(client.get).toHaveBeenCalledTimes(1); @@ -3478,7 +3478,7 @@ describe('SavedObjectsRepository', () => { await deleteFromNamespacesSuccessUpdate(expectFn); }); - it(`formats the ES requests`, async () => { + it(`formats the OpenSearch requests`, async () => { let ctr = 0; const expectFn = () => { expect(client.update).toHaveBeenCalledWith( @@ -3518,7 +3518,7 @@ describe('SavedObjectsRepository', () => { it(`should use default index`, async () => { const expectFn = () => expect(client.update).toHaveBeenCalledWith( - expect.objectContaining({ index: '.kibana-test' }), + expect.objectContaining({ index: '.opensearch-dashboards-test' }), expect.anything() ); await deleteFromNamespacesSuccessUpdate(expectFn); @@ -3580,17 +3580,17 @@ describe('SavedObjectsRepository', () => { await test([]); }); - it(`throws when ES is unable to find the document during get`, async () => { + it(`throws when OpenSearch is unable to find the document during get`, async () => { client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ found: false }) + opensearchClientMock.createSuccessTransportRequestPromise({ found: false }) ); await expectNotFoundError(type, id, [namespace1, namespace2]); expect(client.get).toHaveBeenCalledTimes(1); }); - it(`throws when ES is unable to find the index during get`, async () => { + it(`throws when OpenSearch is unable to find the index during get`, async () => { client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + opensearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) ); await expectNotFoundError(type, id, [namespace1, namespace2]); expect(client.get).toHaveBeenCalledTimes(1); @@ -3602,20 +3602,20 @@ describe('SavedObjectsRepository', () => { expect(client.get).toHaveBeenCalledTimes(1); }); - it(`throws when ES is unable to find the document during delete`, async () => { + it(`throws when OpenSearch is unable to find the document during delete`, async () => { mockGetResponse(type, id, [namespace1]); client.delete.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ result: 'not_found' }) + opensearchClientMock.createSuccessTransportRequestPromise({ result: 'not_found' }) ); await expectNotFoundError(type, id, [namespace1]); expect(client.get).toHaveBeenCalledTimes(1); expect(client.delete).toHaveBeenCalledTimes(1); }); - it(`throws when ES is unable to find the index during delete`, async () => { + it(`throws when OpenSearch is unable to find the index during delete`, async () => { mockGetResponse(type, id, [namespace1]); client.delete.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ error: { type: 'index_not_found_exception' }, }) ); @@ -3624,24 +3624,24 @@ describe('SavedObjectsRepository', () => { expect(client.delete).toHaveBeenCalledTimes(1); }); - it(`throws when ES returns an unexpected response`, async () => { + it(`throws when OpenSearch returns an unexpected response`, async () => { mockGetResponse(type, id, [namespace1]); client.delete.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ result: 'something unexpected', }) ); await expect( savedObjectsRepository.deleteFromNamespaces(type, id, [namespace1]) - ).rejects.toThrowError('Unexpected Elasticsearch DELETE response'); + ).rejects.toThrowError('Unexpected OpenSearch DELETE response'); expect(client.get).toHaveBeenCalledTimes(1); expect(client.delete).toHaveBeenCalledTimes(1); }); - it(`throws when ES is unable to find the document during update`, async () => { + it(`throws when OpenSearch is unable to find the document during update`, async () => { mockGetResponse(type, id, [namespace1, namespace2]); client.update.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + opensearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) ); await expectNotFoundError(type, id, [namespace1]); expect(client.get).toHaveBeenCalledTimes(1); @@ -3703,11 +3703,11 @@ describe('SavedObjectsRepository', () => { if (registry.isMultiNamespace(type)) { const mockGetResponse = getMockGetResponse({ type, id }, options?.namespace); client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(mockGetResponse) + opensearchClientMock.createSuccessTransportRequestPromise(mockGetResponse) ); } client.update.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + opensearchClientMock.createSuccessTransportRequestPromise({ _id: `${type}:${id}`, ...mockVersionProps, result: 'updated', @@ -3730,13 +3730,13 @@ describe('SavedObjectsRepository', () => { }; describe('client calls', () => { - it(`should use the ES get action then update action when type is multi-namespace`, async () => { + it(`should use the OpenSearch get action then update action when type is multi-namespace`, async () => { await updateSuccess(MULTI_NAMESPACE_TYPE, id, attributes); expect(client.get).toHaveBeenCalledTimes(1); expect(client.update).toHaveBeenCalledTimes(1); }); - it(`should use the ES update action when type is not multi-namespace`, async () => { + it(`should use the OpenSearch update action when type is not multi-namespace`, async () => { await updateSuccess(type, id, attributes); expect(client.update).toHaveBeenCalledTimes(1); }); @@ -3899,17 +3899,17 @@ describe('SavedObjectsRepository', () => { expect(client.update).not.toHaveBeenCalled(); }); - it(`throws when ES is unable to find the document during get`, async () => { + it(`throws when OpenSearch is unable to find the document during get`, async () => { client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ found: false }) + opensearchClientMock.createSuccessTransportRequestPromise({ found: false }) ); await expectNotFoundError(MULTI_NAMESPACE_TYPE, id); expect(client.get).toHaveBeenCalledTimes(1); }); - it(`throws when ES is unable to find the index during get`, async () => { + it(`throws when OpenSearch is unable to find the index during get`, async () => { client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + opensearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) ); await expectNotFoundError(MULTI_NAMESPACE_TYPE, id); expect(client.get).toHaveBeenCalledTimes(1); @@ -3918,15 +3918,15 @@ describe('SavedObjectsRepository', () => { it(`throws when type is multi-namespace and the document exists, but not in this namespace`, async () => { const response = getMockGetResponse({ type: MULTI_NAMESPACE_TYPE, id }, namespace); client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) + opensearchClientMock.createSuccessTransportRequestPromise(response) ); await expectNotFoundError(MULTI_NAMESPACE_TYPE, id, { namespace: 'bar-namespace' }); expect(client.get).toHaveBeenCalledTimes(1); }); - it(`throws when ES is unable to find the document during update`, async () => { + it(`throws when OpenSearch is unable to find the document during update`, async () => { client.update.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + opensearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) ); await expectNotFoundError(type, id); expect(client.update).toHaveBeenCalledTimes(1); diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts index 39aacd6b05b7..f7cf50d60980 100644 --- a/src/core/server/saved_objects/service/lib/repository.ts +++ b/src/core/server/saved_objects/service/lib/repository.ts @@ -20,18 +20,18 @@ import { omit } from 'lodash'; import uuid from 'uuid'; import { - ElasticsearchClient, + OpenSearchClient, DeleteDocumentResponse, GetResponse, SearchResponse, -} from '../../../elasticsearch/'; +} from '../../../opensearch/'; import { getRootPropertiesObjects, IndexMapping } from '../../mappings'; -import { createRepositoryEsClient, RepositoryEsClient } from './repository_es_client'; +import { createRepositoryOpenSearchClient, RepositoryOpenSearchClient } from './repository_opensearch_client'; import { getSearchDsl } from './search_dsl'; import { includedFields } from './included_fields'; import { SavedObjectsErrorHelpers, DecoratedError } from './errors'; import { decodeRequestVersion, encodeVersion, encodeHitVersion } from '../../version'; -import { IKibanaMigrator } from '../../migrations'; +import { IOpenSearchDashboardsMigrator } from '../../migrations'; import { SavedObjectsSerializer, SavedObjectSanitizedDoc, @@ -88,10 +88,10 @@ const isRight = (either: Either): either is Right => either.tag === 'Right'; export interface SavedObjectsRepositoryOptions { index: string; mappings: IndexMapping; - client: ElasticsearchClient; + client: OpenSearchClient; typeRegistry: SavedObjectTypeRegistry; serializer: SavedObjectsSerializer; - migrator: IKibanaMigrator; + migrator: IOpenSearchDashboardsMigrator; allowedTypes: string[]; } @@ -100,7 +100,7 @@ export interface SavedObjectsRepositoryOptions { */ export interface SavedObjectsIncrementCounterOptions extends SavedObjectsBaseOptions { migrationVersion?: SavedObjectsMigrationVersion; - /** The Elasticsearch Refresh setting for this operation */ + /** The OpenSearch Refresh setting for this operation */ refresh?: MutatingOperationRefreshSetting; } @@ -109,7 +109,7 @@ export interface SavedObjectsIncrementCounterOptions extends SavedObjectsBaseOpt * @public */ export interface SavedObjectsDeleteByNamespaceOptions extends SavedObjectsBaseOptions { - /** The Elasticsearch supports only boolean flag for this operation */ + /** The OpenSearch supports only boolean flag for this operation */ refresh?: boolean; } @@ -126,12 +126,12 @@ export type ISavedObjectsRepository = Pick value.esRequestIndex !== undefined) + .filter(({ value }) => value.opensearchRequestIndex !== undefined) .map(({ value: { object: { type, id } } }) => ({ _id: this._serializer.generateRawId(namespace, type, id), _index: this.getIndexForType(type), @@ -387,13 +387,13 @@ export class SavedObjectsRepository { let savedObjectNamespaces; let versionProperties; const { - esRequestIndex, + opensearchRequestIndex, object: { initialNamespaces, version, ...object }, method, } = expectedBulkGetResult.value; - if (esRequestIndex !== undefined) { + if (opensearchRequestIndex !== undefined) { const indexFound = bulkGetResponse?.statusCode !== 404; - const actualResult = indexFound ? bulkGetResponse?.body.docs[esRequestIndex] : undefined; + const actualResult = indexFound ? bulkGetResponse?.body.docs[opensearchRequestIndex] : undefined; const docFound = indexFound && actualResult.found === true; if (docFound && !this.rawDocExistsInNamespace(actualResult, namespace)) { const { id, type } = object; @@ -422,7 +422,7 @@ export class SavedObjectsRepository { } const expectedResult = { - esRequestIndex: bulkRequestIndexCounter++, + opensearchRequestIndex: bulkRequestIndexCounter++, requestedId: object.id, rawMigratedDoc: this._serializer.savedObjectToRaw( this._migrator.migrateDocument({ @@ -466,9 +466,9 @@ export class SavedObjectsRepository { return expectedResult.error as any; } - const { requestedId, rawMigratedDoc, esRequestIndex } = expectedResult.value; + const { requestedId, rawMigratedDoc, opensearchRequestIndex } = expectedResult.value; const { error, ...rawResponse } = Object.values( - bulkResponse?.body.items[esRequestIndex] + bulkResponse?.body.items[opensearchRequestIndex] )[0] as any; if (error) { @@ -524,7 +524,7 @@ export class SavedObjectsRepository { value: { type, id, - esRequestIndex: bulkGetRequestIndexCounter++, + opensearchRequestIndex: bulkGetRequestIndexCounter++, }, }; }); @@ -552,8 +552,8 @@ export class SavedObjectsRepository { return; } - const { type, id, esRequestIndex } = expectedResult.value; - const doc = bulkGetResponse?.body.docs[esRequestIndex]; + const { type, id, opensearchRequestIndex } = expectedResult.value; + const doc = bulkGetResponse?.body.docs[opensearchRequestIndex]; if (doc.found) { errors.push({ id, @@ -627,7 +627,7 @@ export class SavedObjectsRepository { } throw new Error( - `Unexpected Elasticsearch DELETE response: ${JSON.stringify({ + `Unexpected OpenSearch DELETE response: ${JSON.stringify({ type, id, response: { body, statusCode }, @@ -689,7 +689,7 @@ export class SavedObjectsRepository { * @property {(string|Array)} [options.type] * @property {string} [options.search] * @property {string} [options.defaultSearchOperator] - * @property {Array} [options.searchFields] - see Elasticsearch Simple Query String + * @property {Array} [options.searchFields] - see OpenSearch Simple Query String * Query field argument for more information * @property {integer} [options.page=1] * @property {integer} [options.perPage=20] @@ -770,7 +770,7 @@ export class SavedObjectsRepository { } } - const esOptions = { + const opensearchOptions = { index: this.getIndicesForTypes(allowedTypes), size: perPage, from: perPage * (page - 1), @@ -795,7 +795,7 @@ export class SavedObjectsRepository { }, }; - const { body, statusCode } = await this.client.search>(esOptions, { + const { body, statusCode } = await this.client.search>(opensearchOptions, { ignore: [404], }); if (statusCode === 404) { @@ -867,7 +867,7 @@ export class SavedObjectsRepository { type, id, fields, - esRequestIndex: bulkGetRequestIndexCounter++, + opensearchRequestIndex: bulkGetRequestIndexCounter++, }, }; }); @@ -896,8 +896,8 @@ export class SavedObjectsRepository { return expectedResult.error as any; } - const { type, id, esRequestIndex } = expectedResult.value; - const doc = bulkGetResponse?.body.docs[esRequestIndex]; + const { type, id, opensearchRequestIndex } = expectedResult.value; + const doc = bulkGetResponse?.body.docs[opensearchRequestIndex]; if (!doc.found || !this.rawDocExistsInNamespace(doc, namespace)) { return ({ @@ -1099,7 +1099,7 @@ export class SavedObjectsRepository { const preflightResult = await this.preflightCheckIncludesNamespace(type, id, namespace); const existingNamespaces = getSavedObjectNamespaces(undefined, preflightResult); // there should never be a case where a multi-namespace object does not have any existing namespaces - // however, it is a possibility if someone manually modifies the document in Elasticsearch + // however, it is a possibility if someone manually modifies the document in OpenSearch const time = this._getCurrentTime(); const doc = { @@ -1221,7 +1221,7 @@ export class SavedObjectsRepository { } throw new Error( - `Unexpected Elasticsearch DELETE response: ${JSON.stringify({ + `Unexpected OpenSearch DELETE response: ${JSON.stringify({ type, id, response: { body, statusCode }, @@ -1293,7 +1293,7 @@ export class SavedObjectsRepository { version, documentToSave, objectNamespace, - ...(requiresNamespacesCheck && { esRequestIndex: bulkGetRequestIndexCounter++ }), + ...(requiresNamespacesCheck && { opensearchRequestIndex: bulkGetRequestIndexCounter++ }), }, }; }); @@ -1307,7 +1307,7 @@ export class SavedObjectsRepository { const bulkGetDocs = expectedBulkGetResults .filter(isRight) - .filter(({ value }) => value.esRequestIndex !== undefined) + .filter(({ value }) => value.opensearchRequestIndex !== undefined) .map(({ value: { type, id, objectNamespace } }) => ({ _id: this._serializer.generateRawId(getNamespaceId(objectNamespace), type, id), _index: this.getIndexForType(type), @@ -1335,7 +1335,7 @@ export class SavedObjectsRepository { } const { - esRequestIndex, + opensearchRequestIndex, id, type, version, @@ -1345,9 +1345,9 @@ export class SavedObjectsRepository { let namespaces; let versionProperties; - if (esRequestIndex !== undefined) { + if (opensearchRequestIndex !== undefined) { const indexFound = bulkGetResponse?.statusCode !== 404; - const actualResult = indexFound ? bulkGetResponse?.body.docs[esRequestIndex] : undefined; + const actualResult = indexFound ? bulkGetResponse?.body.docs[opensearchRequestIndex] : undefined; const docFound = indexFound && actualResult.found === true; if ( !docFound || @@ -1378,7 +1378,7 @@ export class SavedObjectsRepository { type, id, namespaces, - esRequestIndex: bulkUpdateRequestIndexCounter++, + opensearchRequestIndex: bulkUpdateRequestIndexCounter++, documentToSave: expectedBulkGetResult.value.documentToSave, }; @@ -1412,8 +1412,8 @@ export class SavedObjectsRepository { return expectedResult.error as any; } - const { type, id, namespaces, documentToSave, esRequestIndex } = expectedResult.value; - const response = bulkUpdateResponse?.body.items[esRequestIndex]; + const { type, id, namespaces, documentToSave, opensearchRequestIndex } = expectedResult.value; + const response = bulkUpdateResponse?.body.items[opensearchRequestIndex]; // When a bulk update operation is completed, any fields specified in `_sourceIncludes` will be found in the "get" value of the // returned object. We need to retrieve the `originId` if it exists so we can return it to the consumer. const { error, _seq_no: seqNo, _primary_term: primaryTerm, get } = Object.values( @@ -1576,7 +1576,7 @@ export class SavedObjectsRepository { * we rely on the guarantees of the document ID format. If the document is a multi-namespace type, this checks to ensure that the * document's `namespaces` value includes the string representation of the given namespace. * - * WARNING: This should only be used for documents that were retrieved from Elasticsearch. Otherwise, the guarantees of the document ID + * WARNING: This should only be used for documents that were retrieved from OpenSearch. Otherwise, the guarantees of the document ID * format mentioned above do not apply. */ private rawDocExistsInNamespace(raw: SavedObjectsRawDoc, namespace?: string) { @@ -1604,7 +1604,7 @@ export class SavedObjectsRepository { * @param namespace The target namespace. * @returns Array of namespaces that this saved object currently includes, or (if the object does not exist yet) the namespaces that a * newly-created object will include. Value may be undefined if an existing saved object has no namespaces attribute; this should not - * happen in normal operations, but it is possible if the Elasticsearch document is manually modified. + * happen in normal operations, but it is possible if the OpenSearch document is manually modified. * @throws Will throw an error if the saved object exists and it does not include the target namespace. */ private async preflightGetNamespaces(type: string, id: string, namespace?: string) { @@ -1640,7 +1640,7 @@ export class SavedObjectsRepository { * @param type The type of the saved object. * @param id The ID of the saved object. * @param namespace The target namespace. - * @returns Raw document from Elasticsearch. + * @returns Raw document from OpenSearch. * @throws Will throw an error if the saved object is not found, or if it doesn't include the target namespace. */ private async preflightCheckIncludesNamespace(type: string, id: string, namespace?: string) { @@ -1680,7 +1680,7 @@ function getBulkOperationError(error: { type: string; reason?: string }, type: s } /** - * Returns an object with the expected version properties. This facilitates Elasticsearch's Optimistic Concurrency Control. + * Returns an object with the expected version properties. This facilitates OpenSearch's Optimistic Concurrency Control. * * @param version Optional version specified by the consumer. * @param document Optional existing document that was obtained in a preflight operation. @@ -1700,7 +1700,7 @@ function getExpectedVersionProperties(version?: string, document?: SavedObjectsR /** * Returns a string array of namespaces for a given saved object. If the saved object is undefined, the result is an array that contains the * current namespace. Value may be undefined if an existing saved object has no namespaces attribute; this should not happen in normal - * operations, but it is possible if the Elasticsearch document is manually modified. + * operations, but it is possible if the OpenSearch document is manually modified. * * @param namespace The current namespace. * @param document Optional existing saved object that was obtained in a preflight operation. diff --git a/src/core/server/saved_objects/service/lib/repository_create_repository.test.ts b/src/core/server/saved_objects/service/lib/repository_create_repository.test.ts index ea881805e1ae..55015f6360fb 100644 --- a/src/core/server/saved_objects/service/lib/repository_create_repository.test.ts +++ b/src/core/server/saved_objects/service/lib/repository_create_repository.test.ts @@ -17,8 +17,8 @@ * under the License. */ import { SavedObjectsRepository } from './repository'; -import { mockKibanaMigrator } from '../../migrations/kibana/kibana_migrator.mock'; -import { KibanaMigrator } from '../../migrations'; +import { mockOpenSearchDashboardsMigrator } from '../../migrations/opensearch-dashboards/opensearch_dashboards_migrator.mock'; +import { OpenSearchDashboardsMigrator } from '../../migrations'; import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; jest.mock('./repository'); @@ -65,7 +65,7 @@ describe('SavedObjectsRepository#createRepository', () => { migrations: {}, }); - const migrator = mockKibanaMigrator.create({ types: typeRegistry.getAllTypes() }); + const migrator = mockOpenSearchDashboardsMigrator.create({ types: typeRegistry.getAllTypes() }); const RepositoryConstructor = (SavedObjectsRepository as unknown) as jest.Mock< SavedObjectsRepository >; @@ -77,9 +77,9 @@ describe('SavedObjectsRepository#createRepository', () => { it('should not allow a repository with an undefined type', () => { try { originalRepository.createRepository( - (migrator as unknown) as KibanaMigrator, + (migrator as unknown) as OpenSearchDashboardsMigrator, typeRegistry, - '.kibana-test', + '.opensearch-dashboards-test', callAdminCluster, ['unMappedType1', 'unmappedType2'] ); @@ -92,9 +92,9 @@ describe('SavedObjectsRepository#createRepository', () => { it('should create a repository without hidden types', () => { const repository = originalRepository.createRepository( - (migrator as unknown) as KibanaMigrator, + (migrator as unknown) as OpenSearchDashboardsMigrator, typeRegistry, - '.kibana-test', + '.opensearch-dashboards-test', callAdminCluster, [], SavedObjectsRepository @@ -110,9 +110,9 @@ describe('SavedObjectsRepository#createRepository', () => { it('should create a repository with a unique list of hidden types', () => { const repository = originalRepository.createRepository( - (migrator as unknown) as KibanaMigrator, + (migrator as unknown) as OpenSearchDashboardsMigrator, typeRegistry, - '.kibana-test', + '.opensearch-dashboards-test', callAdminCluster, ['hiddenType', 'hiddenType', 'hiddenType'], SavedObjectsRepository diff --git a/src/core/server/saved_objects/service/lib/repository_es_client.test.mock.ts b/src/core/server/saved_objects/service/lib/repository_opensearch_client.test.mock.ts similarity index 92% rename from src/core/server/saved_objects/service/lib/repository_es_client.test.mock.ts rename to src/core/server/saved_objects/service/lib/repository_opensearch_client.test.mock.ts index 3dcf82dae5e4..79bf3175fce7 100644 --- a/src/core/server/saved_objects/service/lib/repository_es_client.test.mock.ts +++ b/src/core/server/saved_objects/service/lib/repository_opensearch_client.test.mock.ts @@ -17,6 +17,6 @@ * under the License. */ export const retryCallClusterMock = jest.fn((fn) => fn()); -jest.doMock('../../../elasticsearch/client/retry_call_cluster', () => ({ +jest.doMock('../../../opensearch/client/retry_call_cluster', () => ({ retryCallCluster: retryCallClusterMock, })); diff --git a/src/core/server/saved_objects/service/lib/repository_es_client.test.ts b/src/core/server/saved_objects/service/lib/repository_opensearch_client.test.ts similarity index 72% rename from src/core/server/saved_objects/service/lib/repository_es_client.test.ts rename to src/core/server/saved_objects/service/lib/repository_opensearch_client.test.ts index 61df94fb6bfe..05c040ea8f24 100644 --- a/src/core/server/saved_objects/service/lib/repository_es_client.test.ts +++ b/src/core/server/saved_objects/service/lib/repository_opensearch_client.test.ts @@ -16,23 +16,23 @@ * specific language governing permissions and limitations * under the License. */ -import { retryCallClusterMock } from './repository_es_client.test.mock'; +import { retryCallClusterMock } from './repository_opensearch_client.test.mock'; -import { createRepositoryEsClient, RepositoryEsClient } from './repository_es_client'; -import { elasticsearchClientMock } from '../../../elasticsearch/client/mocks'; +import { createRepositoryOpenSearchClient, RepositoryOpenSearchClient } from './repository_opensearch_client'; +import { opensearchClientMock } from '../../../opensearch/client/mocks'; import { SavedObjectsErrorHelpers } from './errors'; -describe('RepositoryEsClient', () => { - let client: ReturnType; - let repositoryClient: RepositoryEsClient; +describe('RepositoryOpenSearchClient', () => { + let client: ReturnType; + let repositoryClient: RepositoryOpenSearchClient; beforeEach(() => { - client = elasticsearchClientMock.createElasticsearchClient(); - repositoryClient = createRepositoryEsClient(client); + client = opensearchClientMock.createOpenSearchClient(); + repositoryClient = createRepositoryOpenSearchClient(client); retryCallClusterMock.mockClear(); }); - it('delegates call to ES client method', async () => { + it('delegates call to OpenSearch client method', async () => { expect(repositoryClient.bulk).toStrictEqual(expect.any(Function)); await repositoryClient.bulk({ body: [] }); expect(client.bulk).toHaveBeenCalledTimes(1); @@ -52,7 +52,7 @@ describe('RepositoryEsClient', () => { ); }); - it('transform elasticsearch errors into saved objects errors', async () => { + it('transform opensearch errors into saved objects errors', async () => { expect.assertions(1); client.bulk = jest.fn().mockRejectedValue(new Error('reason')); try { diff --git a/src/core/server/saved_objects/service/lib/repository_es_client.ts b/src/core/server/saved_objects/service/lib/repository_opensearch_client.ts similarity index 67% rename from src/core/server/saved_objects/service/lib/repository_es_client.ts rename to src/core/server/saved_objects/service/lib/repository_opensearch_client.ts index 0a759669b1af..852c683cb13f 100644 --- a/src/core/server/saved_objects/service/lib/repository_es_client.ts +++ b/src/core/server/saved_objects/service/lib/repository_opensearch_client.ts @@ -16,11 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -import type { TransportRequestOptions } from '@elastic/elasticsearch/lib/Transport'; +import type { TransportRequestOptions } from '@elastic/opensearch/lib/Transport'; -import { ElasticsearchClient } from '../../../elasticsearch/'; -import { retryCallCluster } from '../../../elasticsearch/client/retry_call_cluster'; -import { decorateEsError } from './decorate_es_error'; +import { OpenSearchClient } from '../../../opensearch/'; +import { retryCallCluster } from '../../../opensearch/client/retry_call_cluster'; +import { decorateOpenSearchError } from './decorate_opensearch_error'; const methods = [ 'bulk', @@ -36,10 +36,10 @@ const methods = [ type MethodName = typeof methods[number]; -export type RepositoryEsClient = Pick; +export type RepositoryOpenSearchClient = Pick; -export function createRepositoryEsClient(client: ElasticsearchClient): RepositoryEsClient { - return methods.reduce((acc: RepositoryEsClient, key: MethodName) => { +export function createRepositoryOpenSearchClient(client: OpenSearchClient): RepositoryOpenSearchClient { + return methods.reduce((acc: RepositoryOpenSearchClient, key: MethodName) => { Object.defineProperty(acc, key, { value: async (params?: unknown, options?: TransportRequestOptions) => { try { @@ -47,10 +47,10 @@ export function createRepositoryEsClient(client: ElasticsearchClient): Repositor (client[key] as Function)(params, { maxRetries: 0, ...options }) ); } catch (e) { - throw decorateEsError(e); + throw decorateOpenSearchError(e); } }, }); return acc; - }, {} as RepositoryEsClient); + }, {} as RepositoryOpenSearchClient); } diff --git a/src/core/server/saved_objects/service/lib/repository_opensearch_client.ts2 b/src/core/server/saved_objects/service/lib/repository_opensearch_client.ts2 new file mode 100644 index 000000000000..852c683cb13f --- /dev/null +++ b/src/core/server/saved_objects/service/lib/repository_opensearch_client.ts2 @@ -0,0 +1,56 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import type { TransportRequestOptions } from '@elastic/opensearch/lib/Transport'; + +import { OpenSearchClient } from '../../../opensearch/'; +import { retryCallCluster } from '../../../opensearch/client/retry_call_cluster'; +import { decorateOpenSearchError } from './decorate_opensearch_error'; + +const methods = [ + 'bulk', + 'create', + 'delete', + 'get', + 'index', + 'mget', + 'search', + 'update', + 'updateByQuery', +] as const; + +type MethodName = typeof methods[number]; + +export type RepositoryOpenSearchClient = Pick; + +export function createRepositoryOpenSearchClient(client: OpenSearchClient): RepositoryOpenSearchClient { + return methods.reduce((acc: RepositoryOpenSearchClient, key: MethodName) => { + Object.defineProperty(acc, key, { + value: async (params?: unknown, options?: TransportRequestOptions) => { + try { + return await retryCallCluster(() => + (client[key] as Function)(params, { maxRetries: 0, ...options }) + ); + } catch (e) { + throw decorateOpenSearchError(e); + } + }, + }); + return acc; + }, {} as RepositoryOpenSearchClient); +} diff --git a/src/core/server/saved_objects/service/lib/scoped_client_provider.ts b/src/core/server/saved_objects/service/lib/scoped_client_provider.ts index ab80f37e6652..fdc2f869d8bb 100644 --- a/src/core/server/saved_objects/service/lib/scoped_client_provider.ts +++ b/src/core/server/saved_objects/service/lib/scoped_client_provider.ts @@ -20,7 +20,7 @@ import { PriorityCollection } from './priority_collection'; import { SavedObjectsClientContract } from '../../types'; import { SavedObjectsRepositoryFactory } from '../../saved_objects_service'; import { ISavedObjectTypeRegistry } from '../../saved_objects_type_registry'; -import { KibanaRequest } from '../../../http'; +import { OpenSearchDashboardsRequest } from '../../../http'; /** * Options passed to each SavedObjectsClientWrapperFactory to aid in creating the wrapper instance. @@ -29,7 +29,7 @@ import { KibanaRequest } from '../../../http'; export interface SavedObjectsClientWrapperOptions { client: SavedObjectsClientContract; typeRegistry: ISavedObjectTypeRegistry; - request: KibanaRequest; + request: OpenSearchDashboardsRequest; } /** @@ -48,7 +48,7 @@ export type SavedObjectsClientFactory = ({ request, includedHiddenTypes, }: { - request: KibanaRequest; + request: OpenSearchDashboardsRequest; includedHiddenTypes?: string[]; }) => SavedObjectsClientContract; @@ -123,7 +123,7 @@ export class SavedObjectsClientProvider { } getClient( - request: KibanaRequest, + request: OpenSearchDashboardsRequest, { includedHiddenTypes, excludedWrappers = [] }: SavedObjectsClientProviderOptions = {} ): SavedObjectsClientContract { const client = this._clientFactory({ diff --git a/src/core/server/saved_objects/service/lib/search_dsl/query_params.test.ts b/src/core/server/saved_objects/service/lib/search_dsl/query_params.test.ts index 0ebb884e87fc..ff0913664e29 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/query_params.test.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/query_params.test.ts @@ -18,7 +18,7 @@ */ // @ts-expect-error no ts -import { esKuery } from '../../../es_query'; +import { opensearchKuery } from '../../../opensearch_query'; type KueryNode = any; import { SavedObjectTypeRegistry } from '../../../saved_objects_type_registry'; @@ -148,7 +148,7 @@ describe('#getQueryParams', () => { it('includes the specified Kuery clause', () => { const test = (kueryNode: KueryNode) => { const result = getQueryParams({ registry, kueryNode }); - const expected = esKuery.toElasticsearchQuery(kueryNode); + const expected = opensearchKuery.toOpenSearchQuery(kueryNode); expect(result.query.bool.filter).toHaveLength(2); expectResult(result, expected); }; diff --git a/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts b/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts index 183c0684cf5f..359fa7eac20c 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts @@ -17,7 +17,7 @@ * under the License. */ // @ts-expect-error no ts -import { esKuery } from '../../../es_query'; +import { opensearchKuery } from '../../../opensearch_query'; type KueryNode = any; import { ISavedObjectTypeRegistry } from '../../../saved_objects_type_registry'; @@ -196,7 +196,7 @@ export function getQueryParams({ const bool: any = { filter: [ - ...(kueryNode != null ? [esKuery.toElasticsearchQuery(kueryNode)] : []), + ...(kueryNode != null ? [opensearchKuery.toOpenSearchQuery(kueryNode)] : []), { bool: { must: hasReference ? [getClauseForReference(hasReference)] : undefined, diff --git a/src/core/server/saved_objects/service/saved_objects_client.ts b/src/core/server/saved_objects/service/saved_objects_client.ts index 6782998d1bf1..c046a2a53dd6 100644 --- a/src/core/server/saved_objects/service/saved_objects_client.ts +++ b/src/core/server/saved_objects/service/saved_objects_client.ts @@ -46,7 +46,7 @@ export interface SavedObjectsCreateOptions extends SavedObjectsBaseOptions { /** {@inheritDoc SavedObjectsMigrationVersion} */ migrationVersion?: SavedObjectsMigrationVersion; references?: SavedObjectReference[]; - /** The Elasticsearch Refresh setting for this operation */ + /** The OpenSearch Refresh setting for this operation */ refresh?: MutatingOperationRefreshSetting; /** Optional ID of the original saved object, if this object's `id` was regenerated */ originId?: string; @@ -117,7 +117,7 @@ export interface SavedObjectsBulkResponse { */ export interface SavedObjectsFindResult extends SavedObject { /** - * The Elasticsearch `_score` of this result. + * The OpenSearch `_score` of this result. */ score: number; } @@ -167,7 +167,7 @@ export interface SavedObjectsUpdateOptions extends SavedObjectsBaseOptions { version?: string; /** {@inheritdoc SavedObjectReference} */ references?: SavedObjectReference[]; - /** The Elasticsearch Refresh setting for this operation */ + /** The OpenSearch Refresh setting for this operation */ refresh?: MutatingOperationRefreshSetting; } @@ -178,7 +178,7 @@ export interface SavedObjectsUpdateOptions extends SavedObjectsBaseOptions { export interface SavedObjectsAddToNamespacesOptions extends SavedObjectsBaseOptions { /** An opaque version number which changes on each successful write operation. Can be used for implementing optimistic concurrency control. */ version?: string; - /** The Elasticsearch Refresh setting for this operation */ + /** The OpenSearch Refresh setting for this operation */ refresh?: MutatingOperationRefreshSetting; } @@ -196,7 +196,7 @@ export interface SavedObjectsAddToNamespacesResponse { * @public */ export interface SavedObjectsDeleteFromNamespacesOptions extends SavedObjectsBaseOptions { - /** The Elasticsearch Refresh setting for this operation */ + /** The OpenSearch Refresh setting for this operation */ refresh?: MutatingOperationRefreshSetting; } @@ -214,7 +214,7 @@ export interface SavedObjectsDeleteFromNamespacesResponse { * @public */ export interface SavedObjectsBulkUpdateOptions extends SavedObjectsBaseOptions { - /** The Elasticsearch Refresh setting for this operation */ + /** The OpenSearch Refresh setting for this operation */ refresh?: MutatingOperationRefreshSetting; } @@ -223,7 +223,7 @@ export interface SavedObjectsBulkUpdateOptions extends SavedObjectsBaseOptions { * @public */ export interface SavedObjectsDeleteOptions extends SavedObjectsBaseOptions { - /** The Elasticsearch Refresh setting for this operation */ + /** The OpenSearch Refresh setting for this operation */ refresh?: MutatingOperationRefreshSetting; /** Force deletion of an object that exists in multiple namespaces */ force?: boolean; diff --git a/src/core/server/saved_objects/status.test.ts b/src/core/server/saved_objects/status.test.ts index 8efea1e2c00c..d4ef84adf027 100644 --- a/src/core/server/saved_objects/status.test.ts +++ b/src/core/server/saved_objects/status.test.ts @@ -23,7 +23,7 @@ import { calculateStatus$ } from './status'; import { take } from 'rxjs/operators'; describe('calculateStatus$', () => { - const expectUnavailableDueToEs = (status$: Observable) => + const expectUnavailableDueToOpenSearch = (status$: Observable) => expect(status$.pipe(take(1)).toPromise()).resolves.toEqual({ level: ServiceStatusLevels.unavailable, summary: `SavedObjects service is not available without a healthy Elasticearch connection`, @@ -35,53 +35,53 @@ describe('calculateStatus$', () => { summary: `SavedObjects service is waiting to start migrations`, }); - describe('when elasticsearch is unavailable', () => { - const esStatus$ = of({ + describe('when opensearch is unavailable', () => { + const openSearchStatus$ = of({ level: ServiceStatusLevels.unavailable, summary: 'xxx', }); it('is unavailable before migrations have ran', async () => { - await expectUnavailableDueToEs(calculateStatus$(of(), esStatus$)); + await expectUnavailableDueToOpenSearch(calculateStatus$(of(), openSearchStatus$)); }); it('is unavailable after migrations have ran', async () => { - await expectUnavailableDueToEs( - calculateStatus$(of({ status: 'completed', result: [] }), esStatus$) + await expectUnavailableDueToOpenSearch( + calculateStatus$(of({ status: 'completed', result: [] }), openSearchStatus$) ); }); }); - describe('when elasticsearch is critical', () => { - const esStatus$ = of({ + describe('when opensearch is critical', () => { + const openSearchStatus$ = of({ level: ServiceStatusLevels.critical, summary: 'xxx', }); it('is unavailable before migrations have ran', async () => { - await expectUnavailableDueToEs(calculateStatus$(of(), esStatus$)); + await expectUnavailableDueToOpenSearch(calculateStatus$(of(), openSearchStatus$)); }); it('is unavailable after migrations have ran', async () => { - await expectUnavailableDueToEs( + await expectUnavailableDueToOpenSearch( calculateStatus$( of({ status: 'completed', result: [{ status: 'migrated' } as any] }), - esStatus$ + openSearchStatus$ ) ); }); }); - describe('when elasticsearch is available', () => { - const esStatus$ = of({ + describe('when opensearch is available', () => { + const openSearchStatus$ = of({ level: ServiceStatusLevels.available, summary: 'Available', }); it('is unavailable before migrations have ran', async () => { - await expectUnavailableDueToMigrations(calculateStatus$(of(), esStatus$)); + await expectUnavailableDueToMigrations(calculateStatus$(of(), openSearchStatus$)); }); it('is unavailable while migrations are running', async () => { await expect( - calculateStatus$(of({ status: 'running' }), esStatus$) + calculateStatus$(of({ status: 'running' }), openSearchStatus$) .pipe(take(2)) .toPromise() ).resolves.toEqual({ @@ -93,7 +93,7 @@ describe('calculateStatus$', () => { await expect( calculateStatus$( of({ status: 'completed', result: [{ status: 'skipped' }, { status: 'patched' }] }), - esStatus$ + openSearchStatus$ ) .pipe(take(2)) .toPromise() @@ -111,23 +111,23 @@ describe('calculateStatus$', () => { }); }); - describe('when elasticsearch is degraded', () => { - const esStatus$ = of({ level: ServiceStatusLevels.degraded, summary: 'xxx' }); + describe('when opensearch is degraded', () => { + const openSearchStatus$ = of({ level: ServiceStatusLevels.degraded, summary: 'xxx' }); it('is unavailable before migrations have ran', async () => { - await expectUnavailableDueToMigrations(calculateStatus$(of(), esStatus$)); + await expectUnavailableDueToMigrations(calculateStatus$(of(), openSearchStatus$)); }); it('is degraded after migrations have ran', async () => { await expect( calculateStatus$( of([{ status: 'skipped' }]), - esStatus$ + openSearchStatus$ ) .pipe(take(2)) .toPromise() ).resolves.toEqual({ level: ServiceStatusLevels.degraded, - summary: 'SavedObjects service is degraded due to Elasticsearch: [xxx]', + summary: 'SavedObjects service is degraded due to OpenSearch: [xxx]', }); }); }); diff --git a/src/core/server/saved_objects/status.ts b/src/core/server/saved_objects/status.ts index 1823fbe95b8b..50b4a48f40fb 100644 --- a/src/core/server/saved_objects/status.ts +++ b/src/core/server/saved_objects/status.ts @@ -21,11 +21,11 @@ import { Observable, combineLatest } from 'rxjs'; import { startWith, map } from 'rxjs/operators'; import { ServiceStatus, ServiceStatusLevels } from '../status'; import { SavedObjectStatusMeta } from './types'; -import { KibanaMigratorStatus } from './migrations/kibana'; +import { OpenSearchDashboardsMigratorStatus } from './migrations/kibana'; export const calculateStatus$ = ( - rawMigratorStatus$: Observable, - elasticsearchStatus$: Observable + rawMigratorStatus$: Observable, + opensearchStatus$: Observable ): Observable> => { const migratorStatus$: Observable> = rawMigratorStatus$.pipe( map((migrationStatus) => { @@ -62,19 +62,19 @@ export const calculateStatus$ = ( }) ); - return combineLatest([elasticsearchStatus$, migratorStatus$]).pipe( - map(([esStatus, migratorStatus]) => { - if (esStatus.level >= ServiceStatusLevels.unavailable) { + return combineLatest([opensearchStatus$, migratorStatus$]).pipe( + map(([openSearchStatus, migratorStatus]) => { + if (openSearchStatus.level >= ServiceStatusLevels.unavailable) { return { level: ServiceStatusLevels.unavailable, summary: `SavedObjects service is not available without a healthy Elasticearch connection`, }; } else if (migratorStatus.level === ServiceStatusLevels.unavailable) { return migratorStatus; - } else if (esStatus.level === ServiceStatusLevels.degraded) { + } else if (openSearchStatus.level === ServiceStatusLevels.degraded) { return { - level: esStatus.level, - summary: `SavedObjects service is degraded due to Elasticsearch: [${esStatus.summary}]`, + level: openSearchStatus.level, + summary: `SavedObjects service is degraded due to OpenSearch: [${openSearchStatus.summary}]`, }; } else { return migratorStatus; diff --git a/src/core/server/saved_objects/types.ts b/src/core/server/saved_objects/types.ts index 01128e4f8cf5..6268f352adbb 100644 --- a/src/core/server/saved_objects/types.ts +++ b/src/core/server/saved_objects/types.ts @@ -76,9 +76,9 @@ export interface SavedObjectsFindOptions { * SavedObjects.find({type: 'dashboard', fields: ['attributes.name', 'attributes.location']}) */ fields?: string[]; - /** Search documents using the Elasticsearch Simple Query String syntax. See Elasticsearch Simple Query String `query` argument for more information */ + /** Search documents using the OpenSearch Simple Query String syntax. See OpenSearch Simple Query String `query` argument for more information */ search?: string; - /** The fields to perform the parsed query against. See Elasticsearch Simple Query String `fields` argument for more information */ + /** The fields to perform the parsed query against. See OpenSearch Simple Query String `fields` argument for more information */ searchFields?: string[]; /** * The fields to perform the parsed query against. Unlike the `searchFields` argument, these are expected to be root fields and will not @@ -92,12 +92,12 @@ export interface SavedObjectsFindOptions { /** * This map defines each type to search for, and the namespace(s) to search for the type in; this is only intended to be used by a saved * object client wrapper. - * If this is defined, it supersedes the `type` and `namespaces` fields when building the Elasticsearch query. + * If this is defined, it supersedes the `type` and `namespaces` fields when building the OpenSearch query. * Any types that are not included in this map will be excluded entirely. * If a type is included but its value is undefined, the operation will search for that type in the Default namespace. */ typeToNamespacesMap?: Map; - /** An optional ES preference value to be used for the query **/ + /** An optional OpenSearch preference value to be used for the query **/ preference?: string; } @@ -111,14 +111,14 @@ export interface SavedObjectsBaseOptions { } /** - * Elasticsearch Refresh setting for mutating operation + * OpenSearch Refresh setting for mutating operation * @public */ export type MutatingOperationRefreshSetting = boolean | 'wait_for'; /** - * Saved Objects is Kibana's data persisentence mechanism allowing plugins to - * use Elasticsearch for storing plugin state. + * Saved Objects is OpenSearchDashboards's data persisentence mechanism allowing plugins to + * use OpenSearch for storing plugin state. * * ## SavedObjectsClient errors * @@ -137,7 +137,7 @@ export type MutatingOperationRefreshSetting = boolean | 'wait_for'; * responses from the `SavedObjectsClient`. * * Type 2 errors are decorated versions of the source error, so if - * the elasticsearch client threw an error it will be decorated based + * the opensearch client threw an error it will be decorated based * on its type. That means that rather than looking for `error.body.error.type` or * doing substring checks on `error.body.error.reason`, just use the helpers to * understand the meaning of the error: @@ -159,7 +159,7 @@ export type MutatingOperationRefreshSetting = boolean | 'wait_for'; * * From the perspective of application code and APIs the SavedObjectsClient is * a black box that persists objects. One of the internal details that users have - * no control over is that we use an elasticsearch index for persistance and that + * no control over is that we use an opensearch index for persistance and that * index might be missing. * * At the time of writing we are in the process of transitioning away from the diff --git a/src/core/server/saved_objects/version/decode_version.ts b/src/core/server/saved_objects/version/decode_version.ts index 73e8ca963979..a7fbb5a4748f 100644 --- a/src/core/server/saved_objects/version/decode_version.ts +++ b/src/core/server/saved_objects/version/decode_version.ts @@ -22,7 +22,7 @@ import { decodeBase64 } from './base64'; /** * Decode the "opaque" version string to the sequence params we - * can use to activate optimistic concurrency in Elasticsearch + * can use to activate optimistic concurrency in OpenSearch */ export function decodeVersion(version?: string) { try { diff --git a/src/core/server/saved_objects/version/encode_version.test.ts b/src/core/server/saved_objects/version/encode_version.test.ts index 9f9d9140f939..4e2abc232dda 100644 --- a/src/core/server/saved_objects/version/encode_version.test.ts +++ b/src/core/server/saved_objects/version/encode_version.test.ts @@ -22,37 +22,37 @@ import { encodeVersion } from './encode_version'; describe('encodeVersion', () => { it('throws if primaryTerm is not an integer', () => { expect(() => encodeVersion(1, undefined as any)).toThrowErrorMatchingInlineSnapshot( - `"_primary_term from elasticsearch must be an integer"` + `"_primary_term from opensearch must be an integer"` ); expect(() => encodeVersion(1, null as any)).toThrowErrorMatchingInlineSnapshot( - `"_primary_term from elasticsearch must be an integer"` + `"_primary_term from opensearch must be an integer"` ); expect(() => encodeVersion(1, {} as any)).toThrowErrorMatchingInlineSnapshot( - `"_primary_term from elasticsearch must be an integer"` + `"_primary_term from opensearch must be an integer"` ); expect(() => encodeVersion(1, [] as any)).toThrowErrorMatchingInlineSnapshot( - `"_primary_term from elasticsearch must be an integer"` + `"_primary_term from opensearch must be an integer"` ); expect(() => encodeVersion(1, 2.5 as any)).toThrowErrorMatchingInlineSnapshot( - `"_primary_term from elasticsearch must be an integer"` + `"_primary_term from opensearch must be an integer"` ); }); it('throws if seqNo is not an integer', () => { expect(() => encodeVersion(undefined as any, 1)).toThrowErrorMatchingInlineSnapshot( - `"_seq_no from elasticsearch must be an integer"` + `"_seq_no from opensearch must be an integer"` ); expect(() => encodeVersion(null as any, 1)).toThrowErrorMatchingInlineSnapshot( - `"_seq_no from elasticsearch must be an integer"` + `"_seq_no from opensearch must be an integer"` ); expect(() => encodeVersion({} as any, 1)).toThrowErrorMatchingInlineSnapshot( - `"_seq_no from elasticsearch must be an integer"` + `"_seq_no from opensearch must be an integer"` ); expect(() => encodeVersion([] as any, 1)).toThrowErrorMatchingInlineSnapshot( - `"_seq_no from elasticsearch must be an integer"` + `"_seq_no from opensearch must be an integer"` ); expect(() => encodeVersion(2.5 as any, 1)).toThrowErrorMatchingInlineSnapshot( - `"_seq_no from elasticsearch must be an integer"` + `"_seq_no from opensearch must be an integer"` ); }); diff --git a/src/core/server/saved_objects/version/encode_version.ts b/src/core/server/saved_objects/version/encode_version.ts index 9b0fcdfbab50..5207fa928543 100644 --- a/src/core/server/saved_objects/version/encode_version.ts +++ b/src/core/server/saved_objects/version/encode_version.ts @@ -26,11 +26,11 @@ import { encodeBase64 } from './base64'; */ export function encodeVersion(seqNo: number, primaryTerm: number) { if (!Number.isInteger(primaryTerm)) { - throw new TypeError('_primary_term from elasticsearch must be an integer'); + throw new TypeError('_primary_term from opensearch must be an integer'); } if (!Number.isInteger(seqNo)) { - throw new TypeError('_seq_no from elasticsearch must be an integer'); + throw new TypeError('_seq_no from opensearch must be an integer'); } return encodeBase64(JSON.stringify([seqNo, primaryTerm]));