feat(search): create search services and extension points

Signed-off-by: Camila Belo <camilaibs@gmail.com>
This commit is contained in:
Camila Belo
2023-03-01 21:14:18 +01:00
parent 49fe8c2000
commit b49c312875
6 changed files with 129 additions and 9 deletions
+1
View File
@@ -24,6 +24,7 @@
},
"dependencies": {
"@backstage/backend-common": "workspace:^",
"@backstage/backend-plugin-api": "workspace:^",
"@backstage/backend-tasks": "workspace:^",
"@backstage/config": "workspace:^",
"@backstage/errors": "workspace:^",
@@ -14,7 +14,6 @@
* limitations under the License.
*/
import { createServiceRef } from '@backstage/backend-plugin-api';
import {
DocumentDecoratorFactory,
DocumentTypeInfo,
@@ -24,20 +23,16 @@ import { Transform, pipeline } from 'stream';
import { Logger } from 'winston';
import { Scheduler } from './Scheduler';
import {
IndexBuilderService,
IndexBuilderOptions,
RegisterCollatorParameters,
RegisterDecoratorParameters,
} from './types';
export const searchIndexBuilderRef = createServiceRef<IndexBuilderService>({
id: 'search.index-node',
});
/**
* Used for adding collators, decorators and compile them into tasks which are added to a scheduler returned to the caller.
* @public
*/
export class IndexBuilder implements IndexBuilderService {
export class IndexBuilder {
private collators: Record<string, RegisterCollatorParameters>;
private decorators: Record<string, DocumentDecoratorFactory[]>;
private documentTypes: Record<string, DocumentTypeInfo>;
@@ -0,0 +1,31 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed 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 { createExtensionPoint } from '@backstage/backend-plugin-api';
import {
SearchEngineRegistryExtensionPoint,
SearchIndexRegistryExtensionPoint,
} from './types';
export const searchEngineRegistryExtensionPoint =
createExtensionPoint<SearchEngineRegistryExtensionPoint>({
id: 'search.engine.registry',
});
export const searchIndexRegistryExtensionPoint =
createExtensionPoint<SearchIndexRegistryExtensionPoint>({
id: 'search.index.registry',
});
+7 -1
View File
@@ -20,7 +20,7 @@
* @packageDocumentation
*/
export { IndexBuilder, searchIndexBuilderRef } from './IndexBuilder';
export { IndexBuilder } from './IndexBuilder';
export { Scheduler } from './Scheduler';
export * from './collators';
export { LunrSearchEngine } from './engines';
@@ -33,9 +33,15 @@ export type {
IndexBuilderOptions,
RegisterCollatorParameters,
RegisterDecoratorParameters,
SearchIndexRegistryExtensionPoint,
SearchEngineRegistryExtensionPoint,
} from './types';
export * from './errors';
export * from './indexing';
export * from './test-utils';
export type { ScheduleTaskParameters } from './Scheduler';
// TODO: export as alfa subpath
export * from './services';
export * from './extensions';
@@ -0,0 +1,87 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed 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 { Logger } from 'winston';
import {
createServiceRef,
createServiceFactory,
coreServices,
} from '@backstage/backend-plugin-api';
import { DocumentTypeInfo } from '@backstage/plugin-search-common';
import { IndexBuilder } from './IndexBuilder';
import { Scheduler } from './Scheduler';
import {
IndexBuilderServiceBuildOptions,
SearchIndexBuilderService,
} from './types';
import { loggerToWinstonLogger } from '@backstage/backend-common';
type DefaultSearchIndexBuilderServiceOptions = {
logger: Logger;
};
class DefaultSearchIndexBuilderService implements SearchIndexBuilderService {
private logger: Logger;
private indexBuilder: IndexBuilder | null = null;
private constructor(options: DefaultSearchIndexBuilderServiceOptions) {
this.logger = options.logger;
}
static fromConfig(options: DefaultSearchIndexBuilderServiceOptions) {
return new DefaultSearchIndexBuilderService(options);
}
build(
options: IndexBuilderServiceBuildOptions,
): Promise<{ scheduler: Scheduler }> {
this.indexBuilder = new IndexBuilder({
logger: this.logger,
searchEngine: options.searchEngine,
});
options.collators.forEach(collator =>
this.indexBuilder?.addCollator(collator),
);
options.decorators.forEach(decorator =>
this.indexBuilder?.addDecorator(decorator),
);
return this.indexBuilder?.build();
}
getDocumentTypes(): Record<string, DocumentTypeInfo> {
return this.indexBuilder?.getDocumentTypes() ?? {};
}
}
export const searchIndexBuilderService =
createServiceRef<SearchIndexBuilderService>({
id: 'search.index.builder',
defaultFactory: async service =>
createServiceFactory({
service,
deps: {
logger: coreServices.logger,
},
factory({ logger }) {
return DefaultSearchIndexBuilderService.fromConfig({
logger: loggerToWinstonLogger(logger),
});
},
}),
});
+2 -2
View File
@@ -65,7 +65,7 @@ export type IndexBuilderServiceBuildOptions = {
collators: RegisterCollatorParameters[];
decorators: RegisterDecoratorParameters[];
};
export interface IndexBuilderService {
export interface SearchIndexBuilderService {
build(options: IndexBuilderServiceBuildOptions): Promise<{
scheduler: Scheduler;
}>;
@@ -81,5 +81,5 @@ export interface SearchIndexRegistryExtensionPoint {
export interface SearchEngineRegistryExtensionPoint {
setSearchEngine(searchEngine: SearchEngine): void;
getSearchEngine(): SearchEngine;
getSearchEngine(): SearchEngine | null;
}