Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[dot-kibana-split] Adapt usages of core.savedObjects.getKibanaIndex to use the correct index #155155

Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ export function createPluginSetupContext<TPlugin, TPluginDependencies>(
setSpacesExtension: deps.savedObjects.setSpacesExtension,
registerType: deps.savedObjects.registerType,
getKibanaIndex: deps.savedObjects.getKibanaIndex,
getDefaultIndex: deps.savedObjects.getDefaultIndex,
getAllIndices: deps.savedObjects.getAllIndices,
},
status: {
core$: deps.status.core$,
Expand Down Expand Up @@ -313,6 +315,10 @@ export function createPluginStartContext<TPlugin, TPluginDependencies>(
createExporter: deps.savedObjects.createExporter,
createImporter: deps.savedObjects.createImporter,
getTypeRegistry: deps.savedObjects.getTypeRegistry,
getDefaultIndex: deps.savedObjects.getDefaultIndex,
getIndexForType: deps.savedObjects.getIndexForType,
getIndicesForTypes: deps.savedObjects.getIndicesForTypes,
getAllIndices: deps.savedObjects.getAllIndices,
},
metrics: {
collectionInterval: deps.metrics.collectionInterval,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ import {
import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-base-server-internal';
import type { DeprecationRegistryProvider } from '@kbn/core-deprecations-server';
import type { NodeInfo } from '@kbn/core-node-server';
import { MAIN_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server';
import { MAIN_SAVED_OBJECT_INDEX, SavedObjectsIndexPatterns } from '@kbn/core-saved-objects-server';
import { registerRoutes } from './routes';
import { calculateStatus$ } from './status';
import { registerCoreObjectTypes } from './object_types';
Expand Down Expand Up @@ -198,6 +198,8 @@ export class SavedObjectsService
},
getTypeRegistry: () => this.typeRegistry,
getKibanaIndex: () => MAIN_SAVED_OBJECT_INDEX,
getDefaultIndex: () => MAIN_SAVED_OBJECT_INDEX,
getAllIndices: () => [...SavedObjectsIndexPatterns],
};
}

Expand Down Expand Up @@ -340,6 +342,21 @@ export class SavedObjectsService
importSizeLimit: options?.importSizeLimit ?? this.config!.maxImportExportSize,
}),
getTypeRegistry: () => this.typeRegistry,
getDefaultIndex: () => MAIN_SAVED_OBJECT_INDEX,
getIndexForType: (type: string) => {
const definition = this.typeRegistry.getType(type);
return definition?.indexPattern ?? MAIN_SAVED_OBJECT_INDEX;
},
getIndicesForTypes: (types: string[]) => {
const indices = new Set<string>();
types.forEach((type) => {
const definition = this.typeRegistry.getType(type);
const index = definition?.indexPattern ?? MAIN_SAVED_OBJECT_INDEX;
indices.add(index);
});
return [...indices];
},
getAllIndices: () => [...SavedObjectsIndexPatterns],
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ const createStartContractMock = (typeRegistry?: jest.Mocked<ISavedObjectTypeRegi
createExporter: jest.fn(),
createImporter: jest.fn(),
getTypeRegistry: jest.fn(),
getDefaultIndex: jest.fn(),
getIndexForType: jest.fn(),
getIndicesForTypes: jest.fn(),
getAllIndices: jest.fn(),
};

startContrat.getScopedClient.mockReturnValue(savedObjectsClientMock.create());
Expand All @@ -50,6 +54,10 @@ const createStartContractMock = (typeRegistry?: jest.Mocked<ISavedObjectTypeRegi
startContrat.getTypeRegistry.mockReturnValue(typeRegistry ?? typeRegistryMock.create());
startContrat.createExporter.mockReturnValue(savedObjectsExporterMock.create());
startContrat.createImporter.mockReturnValue(savedObjectsImporterMock.create());
startContrat.getDefaultIndex.mockReturnValue(MAIN_SAVED_OBJECT_INDEX);
startContrat.getIndexForType.mockReturnValue(MAIN_SAVED_OBJECT_INDEX);
startContrat.getIndicesForTypes.mockReturnValue([MAIN_SAVED_OBJECT_INDEX]);
startContrat.getAllIndices.mockReturnValue([MAIN_SAVED_OBJECT_INDEX]);

return startContrat;
};
Expand All @@ -69,9 +77,13 @@ const createSetupContractMock = () => {
setSpacesExtension: jest.fn(),
registerType: jest.fn(),
getKibanaIndex: jest.fn(),
getDefaultIndex: jest.fn(),
getAllIndices: jest.fn(),
};

setupContract.getKibanaIndex.mockReturnValue(MAIN_SAVED_OBJECT_INDEX);
setupContract.getDefaultIndex.mockReturnValue(MAIN_SAVED_OBJECT_INDEX);
setupContract.getAllIndices.mockReturnValue([MAIN_SAVED_OBJECT_INDEX]);

return setupContract;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,22 @@ export interface SavedObjectsServiceSetup {

/**
* Returns the default index used for saved objects.
*
* @deprecated use {@link SavedObjectsServiceSetup.getDefaultIndex} instead.
*/
getKibanaIndex: () => string;

/**
* Returns the default index used for saved objects.
*/
getDefaultIndex: () => string;

/**
* Returns all (aliases to) kibana system indices used for saved object storage.
*
* @deprecated use the `start` contract counterpart.
*/
getAllIndices: () => string[];
}

/**
Expand Down Expand Up @@ -209,4 +223,25 @@ export interface SavedObjectsServiceStart {
* {@link SavedObjectsType | saved object types}
*/
getTypeRegistry: () => ISavedObjectTypeRegistry;
/**
* Returns the (alias to the) index that the specified saved object type is stored in.
*
* @param type The SO type to retrieve the index/alias for.
*/
getIndexForType: (type: string) => string;
/**
* Returns the (alias to the) index that the specified saved object type is stored in.
*
* @remark if multiple types are living in the same index, duplicates will be removed.
* @param types The SO types to retrieve the index/alias for.
*/
getIndicesForTypes: (types: string[]) => string[];
Comment on lines +219 to +231
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TSDoc was added fairly quickly, please tell me if we want to rephrase stuff in here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT plurals here would be nice:

 /**
  * Returns the (aliases to the) indices that the specified saved object types are stored in.
  *
  * @remark an index that matches multiple types will only be returned once, aka duplicates will be removed.
  * @param types The SO types to retrieve the indices/aliases for.
  */

/**
* Returns the default index used for saved objects.
*/
getDefaultIndex: () => string;
/**
* Returns all (aliases to) kibana system indices used for saved object storage.
*/
getAllIndices: () => string[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,14 @@ export function dashboardTaskRunner(logger: Logger, core: CoreSetup, embeddable:
return dashboardData;
};

const kibanaIndex = core.savedObjects.getKibanaIndex();
const dashboardIndex = await core
.getStartServices()
.then(([coreStart]) => coreStart.savedObjects.getIndexForType('dashboard'));
const pageSize = 50;

const searchParams = {
size: pageSize,
index: kibanaIndex,
index: dashboardIndex,
ignore_unavailable: true,
filter_path: ['hits.hits', '_scroll_id'],
body: { query: { bool: { filter: { term: { type: 'dashboard' } } } } },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ export class KqlTelemetryService implements Plugin<void> {

if (usageCollection) {
try {
makeKQLUsageCollector(usageCollection, savedObjects.getKibanaIndex());
const getIndexForType = (type: string) =>
getStartServices().then(([coreStart]) => coreStart.savedObjects.getIndexForType(type));
makeKQLUsageCollector(usageCollection, getIndexForType);
} catch (e) {
this.initializerContext.logger
.get('kql-telemetry')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ function setupMockCallCluster(
describe('makeKQLUsageCollector', () => {
describe('fetch method', () => {
beforeEach(() => {
fetch = fetchProvider('.kibana');
fetch = fetchProvider(() => Promise.resolve('.kibana'));
});

it('should return opt in data from the .kibana/kql-telemetry doc', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ export interface Usage {
defaultQueryLanguage: string;
}

export function fetchProvider(index: string) {
export function fetchProvider(getIndexForType: (type: string) => Promise<string>) {
return async ({ esClient }: CollectorFetchContext): Promise<Usage> => {
const [response, config] = await Promise.all([
esClient.get(
{
index,
index: await getIndexForType('kql-telemetry'),
id: 'kql-telemetry:kql-telemetry',
},
{ ignore: [404] }
),
esClient.search(
{
index,
index: await getIndexForType('config'),
body: { query: { term: { type: 'config' } } },
},
{ ignore: [404] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
describe('makeKQLUsageCollector', () => {
let usageCollectionMock: jest.Mocked<UsageCollectionSetup>;

const getIndexForType = () => Promise.resolve('.kibana');

beforeEach(() => {
usageCollectionMock = {
makeUsageCollector: jest.fn(),
Expand All @@ -20,12 +22,12 @@ describe('makeKQLUsageCollector', () => {
});

it('should call registerCollector', () => {
makeKQLUsageCollector(usageCollectionMock as UsageCollectionSetup, '.kibana');
makeKQLUsageCollector(usageCollectionMock as UsageCollectionSetup, getIndexForType);
expect(usageCollectionMock.registerCollector).toHaveBeenCalledTimes(1);
});

it('should call makeUsageCollector with type = kql', () => {
makeKQLUsageCollector(usageCollectionMock as UsageCollectionSetup, '.kibana');
makeKQLUsageCollector(usageCollectionMock as UsageCollectionSetup, getIndexForType);
expect(usageCollectionMock.makeUsageCollector).toHaveBeenCalledTimes(1);
expect(usageCollectionMock.makeUsageCollector.mock.calls[0][0].type).toBe('kql');
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
import { fetchProvider, Usage } from './fetch';

export function makeKQLUsageCollector(usageCollection: UsageCollectionSetup, kibanaIndex: string) {
export function makeKQLUsageCollector(
usageCollection: UsageCollectionSetup,
getIndexForType: (type: string) => Promise<string>
) {
const kqlUsageCollector = usageCollection.makeUsageCollector<Usage>({
type: 'kql',
fetch: fetchProvider(kibanaIndex),
fetch: fetchProvider(getIndexForType),
isReady: () => true,
schema: {
optInCount: { type: 'long' },
Expand Down
5 changes: 3 additions & 2 deletions src/plugins/data/server/search/collectors/search/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ interface SearchTelemetry {
'search-telemetry': CollectedUsage;
}

export function fetchProvider(kibanaIndex: string) {
export function fetchProvider(getIndexForType: (type: string) => Promise<string>) {
return async ({ esClient }: CollectorFetchContext): Promise<ReportedUsage> => {
const searchIndex = await getIndexForType('search-telemetry');
const esResponse = await esClient.search<SearchTelemetry>(
{
index: kibanaIndex,
index: searchIndex,
body: {
query: { term: { type: { value: 'search-telemetry' } } },
},
Expand Down
7 changes: 5 additions & 2 deletions src/plugins/data/server/search/collectors/search/register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@ export interface ReportedUsage {
averageDuration: number | null;
}

export function registerUsageCollector(usageCollection: UsageCollectionSetup, kibanaIndex: string) {
export function registerUsageCollector(
usageCollection: UsageCollectionSetup,
getIndexForType: (type: string) => Promise<string>
) {
try {
const collector = usageCollection.makeUsageCollector<ReportedUsage>({
type: 'search',
isReady: () => true,
fetch: fetchProvider(kibanaIndex),
fetch: fetchProvider(getIndexForType),
schema: {
successCount: { type: 'long' },
errorCount: { type: 'long' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ describe('fetchProvider', () => {

beforeEach(async () => {
const kibanaIndex = '123';
const getIndexForType = () => Promise.resolve(kibanaIndex);
mockLogger = {
warn: jest.fn(),
debug: jest.fn(),
} as any;
esClient = elasticsearchServiceMock.createElasticsearchClient();
fetchFn = fetchProvider(kibanaIndex, mockLogger);
fetchFn = fetchProvider(getIndexForType, mockLogger);
});

test('returns when ES returns no results', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ interface SessionPersistedTermsBucket {
doc_count: number;
}

export function fetchProvider(kibanaIndex: string, logger: Logger) {
export function fetchProvider(getIndexForType: (type: string) => Promise<string>, logger: Logger) {
return async ({ esClient }: CollectorFetchContext): Promise<ReportedUsage> => {
try {
const searchSessionIndex = await getIndexForType(SEARCH_SESSION_TYPE);
const esResponse = await esClient.search<unknown>({
index: kibanaIndex,
index: searchSessionIndex,
body: {
size: 0,
aggs: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ export interface ReportedUsage {

export function registerUsageCollector(
usageCollection: UsageCollectionSetup,
kibanaIndex: string,
getIndexForType: (type: string) => Promise<string>,
logger: Logger
) {
try {
const collector = usageCollection.makeUsageCollector<ReportedUsage>({
type: 'search-session',
isReady: () => true,
fetch: fetchProvider(kibanaIndex, logger),
fetch: fetchProvider(getIndexForType, logger),
schema: {
transientCount: { type: 'long' },
persistedCount: { type: 'long' },
Expand Down
10 changes: 4 additions & 6 deletions src/plugins/data/server/search/search_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,12 +213,10 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {

core.savedObjects.registerType(searchTelemetry);
if (usageCollection) {
registerSearchUsageCollector(usageCollection, core.savedObjects.getKibanaIndex());
registerSearchSessionUsageCollector(
usageCollection,
core.savedObjects.getKibanaIndex(),
this.logger
);
const getIndexForType = (type: string) =>
core.getStartServices().then(([coreStart]) => coreStart.savedObjects.getIndexForType(type));
registerSearchUsageCollector(usageCollection, getIndexForType);
registerSearchSessionUsageCollector(usageCollection, getIndexForType, this.logger);
}

expressions.registerFunction(getEsaggs({ getStartServices: core.getStartServices }));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { registerSampleDatasetWithIntegration } from './lib/register_with_integr

export class SampleDataRegistry {
constructor(private readonly initContext: PluginInitializerContext) {}

private readonly sampleDatasets: SampleDatasetSchema[] = [];
private readonly appLinksMap = new Map<string, AppLinkData[]>();

Expand Down Expand Up @@ -68,8 +69,9 @@ export class SampleDataRegistry {
isDevMode?: boolean
) {
if (usageCollections) {
const kibanaIndex = core.savedObjects.getKibanaIndex();
makeSampleDataUsageCollector(usageCollections, kibanaIndex);
const getIndexForType = (type: string) =>
core.getStartServices().then(([coreStart]) => coreStart.savedObjects.getIndexForType(type));
makeSampleDataUsageCollector(usageCollections, getIndexForType);
}
const usageTracker = usage(
core.getStartServices().then(([coreStart]) => coreStart.savedObjects),
Expand Down Expand Up @@ -176,6 +178,7 @@ export class SampleDataRegistry {
return {};
}
}

/** @public */
export type SampleDataRegistrySetup = ReturnType<SampleDataRegistry['setup']>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import { fetchProvider, TelemetryResponse } from './collector_fetch';

export function makeSampleDataUsageCollector(
usageCollection: UsageCollectionSetup,
kibanaIndex: string
getIndexForType: (type: string) => Promise<string>
) {
const collector = usageCollection.makeUsageCollector<TelemetryResponse>({
type: 'sample-data',
fetch: fetchProvider(kibanaIndex),
fetch: fetchProvider(getIndexForType),
isReady: () => true,
schema: {
installed: { type: 'array', items: { type: 'keyword' } },
Expand Down
Loading