From 44c18b4d3f0cfb110c06f0a0903c047fbd7a1cc0 Mon Sep 17 00:00:00 2001 From: Jussi Hallila Date: Tue, 10 Jan 2023 13:40:38 +0100 Subject: [PATCH 1/4] Expose optional persistenceContext on TechInsights construction This enables integrators to provide their own database implementations for fact handling if something more suitable than Postgres/SQlite is needed. Signed-off-by: Jussi Hallila --- .changeset/rude-pumas-draw.md | 5 +++ plugins/tech-insights-backend/api-report.md | 41 +++++++++++++++++++ plugins/tech-insights-backend/src/index.ts | 1 + .../persistence/TechInsightsDatabase.ts | 5 +++ .../src/service/techInsightsContextBuilder.ts | 14 +++++-- 5 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 .changeset/rude-pumas-draw.md diff --git a/.changeset/rude-pumas-draw.md b/.changeset/rude-pumas-draw.md new file mode 100644 index 0000000000..df3592ece8 --- /dev/null +++ b/.changeset/rude-pumas-draw.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-tech-insights-backend': patch +--- + +Expose optional persistenceContext on TechInsights construction to enable integrators to provide their own database implementations for fact handling. diff --git a/plugins/tech-insights-backend/api-report.md b/plugins/tech-insights-backend/api-report.md index 8dc8efbb24..faca4a615c 100644 --- a/plugins/tech-insights-backend/api-report.md +++ b/plugins/tech-insights-backend/api-report.md @@ -5,6 +5,7 @@ ```ts import { CheckResult } from '@backstage/plugin-tech-insights-common'; import { Config } from '@backstage/config'; +import { DateTime } from 'luxon'; import { Duration } from 'luxon'; import express from 'express'; import { FactChecker } from '@backstage/plugin-tech-insights-node'; @@ -13,12 +14,16 @@ import { FactLifecycle } from '@backstage/plugin-tech-insights-node'; import { FactRetriever } from '@backstage/plugin-tech-insights-node'; import { FactRetrieverRegistration } from '@backstage/plugin-tech-insights-node'; import { FactSchema } from '@backstage/plugin-tech-insights-node'; +import { FactSchemaDefinition } from '@backstage/plugin-tech-insights-node'; +import { FlatTechInsightFact } from '@backstage/plugin-tech-insights-node'; import { HumanDuration } from '@backstage/types'; +import { Knex } from 'knex'; import { Logger } from 'winston'; import { PluginDatabaseManager } from '@backstage/backend-common'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; import { TechInsightCheck } from '@backstage/plugin-tech-insights-node'; +import { TechInsightFact } from '@backstage/plugin-tech-insights-node'; import { TechInsightsStore } from '@backstage/plugin-tech-insights-node'; import { TokenManager } from '@backstage/backend-common'; @@ -106,6 +111,41 @@ export type TechInsightsContext< factRetrieverEngine: FactRetrieverEngine; }; +// @public +export class TechInsightsDatabase implements TechInsightsStore { + constructor(db: Knex, logger: Logger); + // (undocumented) + getFactsBetweenTimestampsByIds( + ids: string[], + entityTriplet: string, + startDateTime: DateTime, + endDateTime: DateTime, + ): Promise<{ + [factId: string]: FlatTechInsightFact[]; + }>; + // (undocumented) + getLatestFactsByIds( + ids: string[], + entityTriplet: string, + ): Promise<{ + [factId: string]: FlatTechInsightFact; + }>; + // (undocumented) + getLatestSchemas(ids?: string[]): Promise; + // (undocumented) + insertFacts({ + id, + facts, + lifecycle, + }: { + id: string; + facts: TechInsightFact[]; + lifecycle?: FactLifecycle; + }): Promise; + // (undocumented) + insertFactSchema(schemaDefinition: FactSchemaDefinition): Promise; +} + // @public (undocumented) export interface TechInsightsOptions< CheckType extends TechInsightCheck, @@ -122,6 +162,7 @@ export interface TechInsightsOptions< factRetrievers?: FactRetrieverRegistration[]; // (undocumented) logger: Logger; + persistenceContext?: PersistenceContext; // (undocumented) scheduler: PluginTaskScheduler; // (undocumented) diff --git a/plugins/tech-insights-backend/src/index.ts b/plugins/tech-insights-backend/src/index.ts index 28a922cd67..8106517a3f 100644 --- a/plugins/tech-insights-backend/src/index.ts +++ b/plugins/tech-insights-backend/src/index.ts @@ -23,6 +23,7 @@ export type { TechInsightsContext, } from './service/techInsightsContextBuilder'; export type { FactRetrieverEngine } from './service/fact/FactRetrieverEngine'; +export type { TechInsightsDatabase } from './service/persistence/TechInsightsDatabase'; export type { PersistenceContext } from './service/persistence/persistenceContext'; export { createFactRetrieverRegistration } from './service/fact/createFactRetriever'; export type { FactRetrieverRegistry } from './service/fact/FactRetrieverRegistry'; diff --git a/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.ts b/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.ts index c6751e864a..65db088431 100644 --- a/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.ts +++ b/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.ts @@ -46,6 +46,11 @@ type RawDbFactSchemaRow = { entityFilter?: string; }; +/** + * Default TechInsightsDatabase implementation. + * + * @public + */ export class TechInsightsDatabase implements TechInsightsStore { private readonly CHUNK_SIZE = 50; diff --git a/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.ts b/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.ts index f85d99b2a8..20693d0a7d 100644 --- a/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.ts +++ b/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.ts @@ -74,6 +74,12 @@ export interface TechInsightsOptions< */ factRetrieverRegistry?: FactRetrieverRegistry; + /** + * Optional persistenceContext implementation that replaces the default one. + * This can be used to replace underlying database with a more suitable implementation if needed + */ + persistenceContext?: PersistenceContext; + logger: Logger; config: Config; discovery: PluginEndpointDiscovery; @@ -139,9 +145,11 @@ export const buildTechInsightsContext = async < const factRetrieverRegistry = buildFactRetrieverRegistry(); - const persistenceContext = await initializePersistenceContext(database, { - logger, - }); + const persistenceContext = + options.persistenceContext ?? + (await initializePersistenceContext(database, { + logger, + })); const factRetrieverEngine = await DefaultFactRetrieverEngine.create({ scheduler, From 4e7bd0a1b1ce05d470fbf9d5b2c433e6419d5264 Mon Sep 17 00:00:00 2001 From: Jussi Hallila Date: Tue, 10 Jan 2023 13:46:27 +0100 Subject: [PATCH 2/4] Fix english language Signed-off-by: Jussi Hallila --- .changeset/rude-pumas-draw.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/rude-pumas-draw.md b/.changeset/rude-pumas-draw.md index df3592ece8..e36d1dd997 100644 --- a/.changeset/rude-pumas-draw.md +++ b/.changeset/rude-pumas-draw.md @@ -2,4 +2,4 @@ '@backstage/plugin-tech-insights-backend': patch --- -Expose optional persistenceContext on TechInsights construction to enable integrators to provide their own database implementations for fact handling. +Expose optional `persistenceContext` on `TechInsights` construction to enable integrators to provide their own database implementations for fact handling. From d5e43e4a09ac67c5b5a64ec8a12c1cf2dbf1ebb4 Mon Sep 17 00:00:00 2001 From: Jussi Hallila Date: Wed, 11 Jan 2023 11:52:05 +0100 Subject: [PATCH 3/4] Make default repository impl protected Expose a construction function instead. Signed-off-by: Jussi Hallila --- plugins/tech-insights-backend/api-report.md | 51 ++++--------------- plugins/tech-insights-backend/src/index.ts | 7 ++- .../persistence/TechInsightsDatabase.ts | 2 +- .../service/persistence/persistenceContext.ts | 7 ++- 4 files changed, 23 insertions(+), 44 deletions(-) diff --git a/plugins/tech-insights-backend/api-report.md b/plugins/tech-insights-backend/api-report.md index faca4a615c..7d1d7583ae 100644 --- a/plugins/tech-insights-backend/api-report.md +++ b/plugins/tech-insights-backend/api-report.md @@ -5,7 +5,6 @@ ```ts import { CheckResult } from '@backstage/plugin-tech-insights-common'; import { Config } from '@backstage/config'; -import { DateTime } from 'luxon'; import { Duration } from 'luxon'; import express from 'express'; import { FactChecker } from '@backstage/plugin-tech-insights-node'; @@ -14,16 +13,12 @@ import { FactLifecycle } from '@backstage/plugin-tech-insights-node'; import { FactRetriever } from '@backstage/plugin-tech-insights-node'; import { FactRetrieverRegistration } from '@backstage/plugin-tech-insights-node'; import { FactSchema } from '@backstage/plugin-tech-insights-node'; -import { FactSchemaDefinition } from '@backstage/plugin-tech-insights-node'; -import { FlatTechInsightFact } from '@backstage/plugin-tech-insights-node'; import { HumanDuration } from '@backstage/types'; -import { Knex } from 'knex'; import { Logger } from 'winston'; import { PluginDatabaseManager } from '@backstage/backend-common'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; import { TechInsightCheck } from '@backstage/plugin-tech-insights-node'; -import { TechInsightFact } from '@backstage/plugin-tech-insights-node'; import { TechInsightsStore } from '@backstage/plugin-tech-insights-node'; import { TokenManager } from '@backstage/backend-common'; @@ -35,6 +30,11 @@ export const buildTechInsightsContext: < options: TechInsightsOptions, ) => Promise>; +// @public +export type CreateDatabaseOptions = { + logger: Logger; +}; + // @public export function createFactRetrieverRegistration( options: FactRetrieverRegistrationOptions, @@ -82,6 +82,12 @@ export interface FactRetrieverRegistry { register(registration: FactRetrieverRegistration): Promise; } +// @public +export const initializePersistenceContext: ( + database: PluginDatabaseManager, + options?: CreateDatabaseOptions, +) => Promise; + // @public export type PersistenceContext = { techInsightsStore: TechInsightsStore; @@ -111,41 +117,6 @@ export type TechInsightsContext< factRetrieverEngine: FactRetrieverEngine; }; -// @public -export class TechInsightsDatabase implements TechInsightsStore { - constructor(db: Knex, logger: Logger); - // (undocumented) - getFactsBetweenTimestampsByIds( - ids: string[], - entityTriplet: string, - startDateTime: DateTime, - endDateTime: DateTime, - ): Promise<{ - [factId: string]: FlatTechInsightFact[]; - }>; - // (undocumented) - getLatestFactsByIds( - ids: string[], - entityTriplet: string, - ): Promise<{ - [factId: string]: FlatTechInsightFact; - }>; - // (undocumented) - getLatestSchemas(ids?: string[]): Promise; - // (undocumented) - insertFacts({ - id, - facts, - lifecycle, - }: { - id: string; - facts: TechInsightFact[]; - lifecycle?: FactLifecycle; - }): Promise; - // (undocumented) - insertFactSchema(schemaDefinition: FactSchemaDefinition): Promise; -} - // @public (undocumented) export interface TechInsightsOptions< CheckType extends TechInsightCheck, diff --git a/plugins/tech-insights-backend/src/index.ts b/plugins/tech-insights-backend/src/index.ts index 8106517a3f..2071acd263 100644 --- a/plugins/tech-insights-backend/src/index.ts +++ b/plugins/tech-insights-backend/src/index.ts @@ -18,13 +18,16 @@ export * from './service/router'; export type { RouterOptions } from './service/router'; export { buildTechInsightsContext } from './service/techInsightsContextBuilder'; +export { initializePersistenceContext } from './service/persistence/persistenceContext'; export type { TechInsightsOptions, TechInsightsContext, } from './service/techInsightsContextBuilder'; export type { FactRetrieverEngine } from './service/fact/FactRetrieverEngine'; -export type { TechInsightsDatabase } from './service/persistence/TechInsightsDatabase'; -export type { PersistenceContext } from './service/persistence/persistenceContext'; +export type { + PersistenceContext, + CreateDatabaseOptions, +} from './service/persistence/persistenceContext'; export { createFactRetrieverRegistration } from './service/fact/createFactRetriever'; export type { FactRetrieverRegistry } from './service/fact/FactRetrieverRegistry'; export type { FactRetrieverRegistrationOptions } from './service/fact/createFactRetriever'; diff --git a/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.ts b/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.ts index 65db088431..0b14f80843 100644 --- a/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.ts +++ b/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.ts @@ -49,7 +49,7 @@ type RawDbFactSchemaRow = { /** * Default TechInsightsDatabase implementation. * - * @public + * @internal */ export class TechInsightsDatabase implements TechInsightsStore { private readonly CHUNK_SIZE = 50; diff --git a/plugins/tech-insights-backend/src/service/persistence/persistenceContext.ts b/plugins/tech-insights-backend/src/service/persistence/persistenceContext.ts index 575ee67bdf..87efcd8a3d 100644 --- a/plugins/tech-insights-backend/src/service/persistence/persistenceContext.ts +++ b/plugins/tech-insights-backend/src/service/persistence/persistenceContext.ts @@ -36,6 +36,11 @@ export type PersistenceContext = { techInsightsStore: TechInsightsStore; }; +/** + * A Container for persistence context initialization options + * + * @public + */ export type CreateDatabaseOptions = { logger: Logger; }; @@ -45,7 +50,7 @@ const defaultOptions: CreateDatabaseOptions = { }; /** - * A factory method to construct persistence context for running implementation. + * A factory function to construct persistence context for running implementation. * * @public */ From 9a6263105669a0439c05b80347283ddd3f7db66d Mon Sep 17 00:00:00 2001 From: Jussi Hallila Date: Wed, 11 Jan 2023 16:21:37 +0100 Subject: [PATCH 4/4] Change name of the type of passed in option object. Signed-off-by: Jussi Hallila --- plugins/tech-insights-backend/api-report.md | 12 ++++++------ plugins/tech-insights-backend/src/index.ts | 2 +- .../src/service/persistence/persistenceContext.ts | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/tech-insights-backend/api-report.md b/plugins/tech-insights-backend/api-report.md index 7d1d7583ae..a757f0d67c 100644 --- a/plugins/tech-insights-backend/api-report.md +++ b/plugins/tech-insights-backend/api-report.md @@ -30,11 +30,6 @@ export const buildTechInsightsContext: < options: TechInsightsOptions, ) => Promise>; -// @public -export type CreateDatabaseOptions = { - logger: Logger; -}; - // @public export function createFactRetrieverRegistration( options: FactRetrieverRegistrationOptions, @@ -85,7 +80,7 @@ export interface FactRetrieverRegistry { // @public export const initializePersistenceContext: ( database: PluginDatabaseManager, - options?: CreateDatabaseOptions, + options?: PersistenceContextOptions, ) => Promise; // @public @@ -93,6 +88,11 @@ export type PersistenceContext = { techInsightsStore: TechInsightsStore; }; +// @public +export type PersistenceContextOptions = { + logger: Logger; +}; + // @public export interface RouterOptions< CheckType extends TechInsightCheck, diff --git a/plugins/tech-insights-backend/src/index.ts b/plugins/tech-insights-backend/src/index.ts index 2071acd263..e9e037cce1 100644 --- a/plugins/tech-insights-backend/src/index.ts +++ b/plugins/tech-insights-backend/src/index.ts @@ -26,7 +26,7 @@ export type { export type { FactRetrieverEngine } from './service/fact/FactRetrieverEngine'; export type { PersistenceContext, - CreateDatabaseOptions, + PersistenceContextOptions, } from './service/persistence/persistenceContext'; export { createFactRetrieverRegistration } from './service/fact/createFactRetriever'; export type { FactRetrieverRegistry } from './service/fact/FactRetrieverRegistry'; diff --git a/plugins/tech-insights-backend/src/service/persistence/persistenceContext.ts b/plugins/tech-insights-backend/src/service/persistence/persistenceContext.ts index 87efcd8a3d..07badb038c 100644 --- a/plugins/tech-insights-backend/src/service/persistence/persistenceContext.ts +++ b/plugins/tech-insights-backend/src/service/persistence/persistenceContext.ts @@ -41,11 +41,11 @@ export type PersistenceContext = { * * @public */ -export type CreateDatabaseOptions = { +export type PersistenceContextOptions = { logger: Logger; }; -const defaultOptions: CreateDatabaseOptions = { +const defaultOptions: PersistenceContextOptions = { logger: getVoidLogger(), }; @@ -56,7 +56,7 @@ const defaultOptions: CreateDatabaseOptions = { */ export const initializePersistenceContext = async ( database: PluginDatabaseManager, - options: CreateDatabaseOptions = defaultOptions, + options: PersistenceContextOptions = defaultOptions, ): Promise => { const client = await database.getClient();