chore: added some more mock defintions and refactoring the TaskManager.forPlugin

Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
blam
2023-01-03 17:02:35 +01:00
parent bdd4b973e8
commit beed5864d0
7 changed files with 151 additions and 17 deletions
@@ -17,6 +17,7 @@
import {
coreServices,
createServiceFactory,
loggerToWinstonLogger,
} from '@backstage/backend-plugin-api';
import { TaskScheduler } from '@backstage/backend-tasks';
@@ -26,11 +27,16 @@ export const schedulerFactory = createServiceFactory({
deps: {
config: coreServices.config,
plugin: coreServices.pluginMetadata,
databaseManager: coreServices.database,
logger: coreServices.logger,
},
async factory({ config }) {
const taskScheduler = TaskScheduler.fromConfig(config);
return async ({ plugin }) => {
return taskScheduler.forPlugin(plugin.getId());
return async ({ plugin, databaseManager, logger }) => {
return taskScheduler.forPlugin(plugin.getId(), {
databaseManager,
logger: loggerToWinstonLogger(logger),
});
};
},
});
@@ -14,7 +14,11 @@
* limitations under the License.
*/
import { DatabaseManager, getRootLogger } from '@backstage/backend-common';
import {
DatabaseManager,
getRootLogger,
PluginDatabaseManager,
} from '@backstage/backend-common';
import { Config } from '@backstage/config';
import { once } from 'lodash';
import { Duration } from 'luxon';
@@ -56,9 +60,15 @@ export class TaskScheduler {
* @param pluginId - The unique ID of the plugin, for example "catalog"
* @returns A {@link PluginTaskScheduler} instance
*/
forPlugin(pluginId: string): PluginTaskScheduler {
forPlugin(
pluginId: string,
options?: { databaseManager?: PluginDatabaseManager; logger?: Logger },
): PluginTaskScheduler {
const databaseManager =
options?.databaseManager ?? this.databaseManager.forPlugin(pluginId);
const logger = options?.logger ?? this.logger.child({ plugin: pluginId });
const databaseFactory = once(async () => {
const databaseManager = this.databaseManager.forPlugin(pluginId);
const knex = await databaseManager.getClient();
if (!databaseManager.migrations?.skip) {
@@ -68,16 +78,13 @@ export class TaskScheduler {
const janitor = new PluginTaskSchedulerJanitor({
knex,
waitBetweenRuns: Duration.fromObject({ minutes: 1 }),
logger: this.logger,
logger,
});
janitor.start();
return knex;
});
return new PluginTaskSchedulerImpl(
databaseFactory,
this.logger.child({ plugin: pluginId }),
);
return new PluginTaskSchedulerImpl(databaseFactory, logger);
}
}
@@ -14,3 +14,6 @@
* limitations under the License.
*/
export { mockTokenManagerFactory } from './mockTokenManagerService';
export { mockConfigFactory } from './mockConfigService';
export { mockDatabaseFactory } from './mockDatabaseService';
export { mockDiscoveryFactory } from './mockDiscoveryService';
@@ -0,0 +1,30 @@
/*
* Copyright 2022 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 {
coreServices,
createServiceFactory,
} from '@backstage/backend-plugin-api';
import { AppConfig, ConfigReader } from '@backstage/config';
/** @public */
export const mockConfigFactory = createServiceFactory({
service: coreServices.config,
deps: {},
async factory(_, options?: { config?: AppConfig }) {
return new ConfigReader(options?.config);
},
});
@@ -0,0 +1,46 @@
/*
* Copyright 2022 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 { DatabaseManager } from '@backstage/backend-common';
import {
coreServices,
createServiceFactory,
} from '@backstage/backend-plugin-api';
import { ConfigReader } from '@backstage/config';
/** @public */
export const mockDatabaseFactory = createServiceFactory({
service: coreServices.database,
deps: {
config: coreServices.config,
plugin: coreServices.pluginMetadata,
},
async factory({ config }) {
const databaseManager = config.getOptional('backend.database')
? DatabaseManager.fromConfig(config)
: DatabaseManager.fromConfig(
new ConfigReader({
backend: {
database: { client: 'better-sqlite', connection: ':memory:' },
},
}),
);
return async ({ plugin }) => {
return databaseManager.forPlugin(plugin.getId());
};
},
});
@@ -0,0 +1,40 @@
/*
* 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 { SingleHostDiscovery } from '@backstage/backend-common';
import {
coreServices,
createServiceFactory,
} from '@backstage/backend-plugin-api';
import { ConfigReader } from '@backstage/config';
/** @public */
export const mockDiscoveryFactory = createServiceFactory({
service: coreServices.discovery,
deps: {},
async factory() {
// todo(blam): we want to grab the port from the httpRouter when that's available here
// to provide a better way to create our mockDiscoveryService.
const discovery = SingleHostDiscovery.fromConfig(
new ConfigReader({
backend: { baseUrl: 'http://localhost:7000', listen: '0.0.0.0:7000' },
}),
);
return async () => {
return discovery;
};
},
});
@@ -21,10 +21,7 @@ import {
rootLifecycleFactory,
loggerFactory,
rootLoggerFactory,
configFactory,
discoveryFactory,
cacheFactory,
databaseFactory,
permissionsFactory,
schedulerFactory,
urlReaderFactory,
@@ -38,7 +35,12 @@ import {
ExtensionPoint,
} from '@backstage/backend-plugin-api';
import { mockTokenManagerFactory } from '../implementations';
import {
mockConfigFactory,
mockDatabaseFactory,
mockTokenManagerFactory,
mockDiscoveryFactory,
} from '../implementations';
/** @alpha */
export interface TestBackendOptions<
@@ -66,9 +68,9 @@ export interface TestBackendOptions<
const defaultServiceFactories = [
cacheFactory(),
configFactory(),
databaseFactory(),
discoveryFactory(),
mockConfigFactory(),
mockDatabaseFactory(),
mockDiscoveryFactory(),
lifecycleFactory(),
loggerFactory(),
permissionsFactory(),