refactor(techdocs-backend): deprecate create router and router options

Signed-off-by: Camila Belo <camilaibs@gmail.com>
This commit is contained in:
Camila Belo
2024-08-25 10:48:11 +02:00
parent 997998e0e0
commit 5b679ac14c
15 changed files with 70 additions and 65 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-techdocs-backend': patch
---
The `createRouter` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system.
+8 -8
View File
@@ -8,6 +8,7 @@ import { CatalogApi } from '@backstage/catalog-client';
import { CatalogClient } from '@backstage/catalog-client';
import { Config } from '@backstage/config';
import { DefaultTechDocsCollatorFactory as DefaultTechDocsCollatorFactory_2 } from '@backstage/plugin-search-backend-module-techdocs';
import { DiscoveryService } from '@backstage/backend-plugin-api';
import { DocsBuildStrategy as DocsBuildStrategy_2 } from '@backstage/plugin-techdocs-node';
import { Entity } from '@backstage/catalog-model';
import express from 'express';
@@ -16,8 +17,7 @@ import { HttpAuthService } from '@backstage/backend-plugin-api';
import { Knex } from 'knex';
import { Logger } from 'winston';
import { Permission } from '@backstage/plugin-permission-common';
import { PluginCacheManager } from '@backstage/backend-common';
import { PluginEndpointDiscovery } from '@backstage/backend-common';
import { PluginCacheManager } from '@backstage/backend-defaults/cache';
import { PreparerBuilder } from '@backstage/plugin-techdocs-node';
import { PublisherBase } from '@backstage/plugin-techdocs-node';
import type { TechDocsCollatorFactoryOptions as TechDocsCollatorFactoryOptions_2 } from '@backstage/plugin-search-backend-module-techdocs';
@@ -25,7 +25,7 @@ import { TechDocsDocument as TechDocsDocument_2 } from '@backstage/plugin-techdo
import { TokenManager } from '@backstage/backend-common';
import * as winston from 'winston';
// @public
// @public @deprecated
export function createRouter(options: RouterOptions): Promise<express.Router>;
// @public @deprecated
@@ -60,7 +60,7 @@ export type OutOfTheBoxDeploymentOptions = {
generators: GeneratorBuilder;
publisher: PublisherBase;
logger: winston.Logger;
discovery: PluginEndpointDiscovery;
discovery: DiscoveryService;
database?: Knex;
config: Config;
cache: PluginCacheManager;
@@ -71,11 +71,11 @@ export type OutOfTheBoxDeploymentOptions = {
auth?: AuthService;
};
// @public
// @public @deprecated
export type RecommendedDeploymentOptions = {
publisher: PublisherBase;
logger: winston.Logger;
discovery: PluginEndpointDiscovery;
discovery: DiscoveryService;
config: Config;
cache: PluginCacheManager;
docsBuildStrategy?: DocsBuildStrategy_2;
@@ -85,7 +85,7 @@ export type RecommendedDeploymentOptions = {
auth?: AuthService;
};
// @public
// @public @deprecated
export type RouterOptions =
| RecommendedDeploymentOptions
| OutOfTheBoxDeploymentOptions;
@@ -100,7 +100,7 @@ export type TechDocsCollatorFactoryOptions = TechDocsCollatorFactoryOptions_2;
// @public
export type TechDocsCollatorOptions = {
discovery: PluginEndpointDiscovery;
discovery: DiscoveryService;
logger: Logger;
tokenManager: TokenManager;
locationTemplate?: string;
+1
View File
@@ -59,6 +59,7 @@
},
"dependencies": {
"@backstage/backend-common": "workspace:^",
"@backstage/backend-defaults": "workspace:^",
"@backstage/backend-plugin-api": "workspace:^",
"@backstage/catalog-client": "workspace:^",
"@backstage/catalog-model": "workspace:^",
+4 -4
View File
@@ -14,10 +14,10 @@
* limitations under the License.
*/
import { CacheClient, loggerToWinstonLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { CacheInvalidationError, TechDocsCache } from './TechDocsCache';
import { mockServices } from '@backstage/backend-test-utils';
import { CacheService } from '@backstage/backend-plugin-api';
const cached = (str: string): string => {
return Buffer.from(str).toString('base64');
@@ -25,7 +25,7 @@ const cached = (str: string): string => {
describe('TechDocsCache', () => {
let CacheUnderTest: TechDocsCache;
let MockClient: jest.Mocked<CacheClient>;
let MockClient: jest.Mocked<CacheService>;
beforeEach(() => {
MockClient = {
@@ -36,7 +36,7 @@ describe('TechDocsCache', () => {
};
CacheUnderTest = TechDocsCache.fromConfig(new ConfigReader({}), {
cache: MockClient,
logger: loggerToWinstonLogger(mockServices.logger.mock()),
logger: mockServices.logger.mock(),
});
});
@@ -83,7 +83,7 @@ describe('TechDocsCache', () => {
}),
{
cache: MockClient,
logger: loggerToWinstonLogger(mockServices.logger.mock()),
logger: mockServices.logger.mock(),
},
);
+7 -8
View File
@@ -13,16 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CacheClient } from '@backstage/backend-common';
import { assertError, CustomErrorBase } from '@backstage/errors';
import { Config } from '@backstage/config';
import { Logger } from 'winston';
import { CacheService, LoggerService } from '@backstage/backend-plugin-api';
export class CacheInvalidationError extends CustomErrorBase {}
export class TechDocsCache {
protected readonly cache: CacheClient;
protected readonly logger: Logger;
protected readonly cache: CacheService;
protected readonly logger: LoggerService;
protected readonly readTimeout: number;
private constructor({
@@ -30,8 +29,8 @@ export class TechDocsCache {
logger,
readTimeout,
}: {
cache: CacheClient;
logger: Logger;
cache: CacheService;
logger: LoggerService;
readTimeout: number;
}) {
this.cache = cache;
@@ -41,7 +40,7 @@ export class TechDocsCache {
static fromConfig(
config: Config,
{ cache, logger }: { cache: CacheClient; logger: Logger },
{ cache, logger }: { cache: CacheService; logger: LoggerService },
) {
const timeout = config.getOptionalNumber('techdocs.cache.readTimeout');
const readTimeout = timeout === undefined ? 1000 : timeout;
@@ -67,7 +66,7 @@ export class TechDocsCache {
} catch (e) {
assertError(e);
this.logger.warn(`Error getting cache entry ${path}: ${e.message}`);
this.logger.debug(e.stack);
this.logger.debug(e.message, e);
return undefined;
}
}
+1 -2
View File
@@ -14,7 +14,6 @@
* limitations under the License.
*/
import { loggerToWinstonLogger } from '@backstage/backend-common';
import express from 'express';
import request from 'supertest';
import { createCacheMiddleware } from './cacheMiddleware';
@@ -58,7 +57,7 @@ describe('createCacheMiddleware', () => {
invalidateMultiple: jest.fn().mockResolvedValue(undefined),
} as unknown as jest.Mocked<TechDocsCache>;
const router = await createCacheMiddleware({
logger: loggerToWinstonLogger(mockServices.logger.mock()),
logger: mockServices.logger.mock(),
cache,
});
app = express().use(router);
+2 -2
View File
@@ -15,12 +15,12 @@
*/
import { Router } from 'express';
import router from 'express-promise-router';
import { Logger } from 'winston';
import { TechDocsCache } from './TechDocsCache';
import { LoggerService } from '@backstage/backend-plugin-api';
type CacheMiddlewareOptions = {
cache: TechDocsCache;
logger: Logger;
logger: LoggerService;
};
type ErrorCallback = (err?: Error) => void;
@@ -14,11 +14,7 @@
* limitations under the License.
*/
import {
PluginEndpointDiscovery,
TokenManager,
loggerToWinstonLogger,
} from '@backstage/backend-common';
import { TokenManager, loggerToWinstonLogger } from '@backstage/backend-common';
import { Entity } from '@backstage/catalog-model';
import { DefaultTechDocsCollator } from './DefaultTechDocsCollator';
import {
@@ -29,6 +25,7 @@ import { setupServer } from 'msw/node';
import { rest } from 'msw';
import { ConfigReader } from '@backstage/config';
import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common';
import { DiscoveryService } from '@backstage/backend-plugin-api';
const logger = loggerToWinstonLogger(mockServices.logger.mock());
@@ -83,7 +80,7 @@ describe('TechDocs Collator', () => {
registerMswTestHooks(worker);
describe('DefaultTechDocsCollator with legacyPathCasing configuration', () => {
let mockDiscoveryApi: jest.Mocked<PluginEndpointDiscovery>;
let mockDiscoveryApi: jest.Mocked<DiscoveryService>;
let mockTokenManager: jest.Mocked<TokenManager>;
let collator: DefaultTechDocsCollator;
@@ -147,7 +144,7 @@ describe('TechDocs Collator', () => {
});
describe('DefaultTechDocsCollator', () => {
let mockDiscoveryApi: jest.Mocked<PluginEndpointDiscovery>;
let mockDiscoveryApi: jest.Mocked<DiscoveryService>;
let mockTokenManager: jest.Mocked<TokenManager>;
let collator: DefaultTechDocsCollator;
@@ -14,10 +14,7 @@
* limitations under the License.
*/
import {
PluginEndpointDiscovery,
TokenManager,
} from '@backstage/backend-common';
import { TokenManager } from '@backstage/backend-common';
import {
Entity,
parseEntityRef,
@@ -38,6 +35,7 @@ import {
} from '@backstage/catalog-client';
import { TechDocsDocument } from '@backstage/plugin-techdocs-node';
import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common';
import { DiscoveryService } from '@backstage/backend-plugin-api';
interface MkSearchIndexDoc {
title: string;
@@ -51,7 +49,7 @@ interface MkSearchIndexDoc {
* @public
*/
export type TechDocsCollatorOptions = {
discovery: PluginEndpointDiscovery;
discovery: DiscoveryService;
logger: Logger;
tokenManager: TokenManager;
locationTemplate?: string;
@@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CacheService } from '@backstage/backend-plugin-api';
import { CachedEntityLoader } from './CachedEntityLoader';
import { CatalogClient } from '@backstage/catalog-client';
import { CacheClient } from '@backstage/backend-common';
import { CompoundEntityRef } from '@backstage/catalog-model';
describe('CachedEntityLoader', () => {
@@ -23,7 +23,7 @@ describe('CachedEntityLoader', () => {
getEntityByRef: jest.fn(),
} as any;
const cache: jest.Mocked<CacheClient> = {
const cache: jest.Mocked<CacheService> = {
get: jest.fn(),
set: jest.fn(),
} as any;
@@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CacheService } from '@backstage/backend-plugin-api';
import { CatalogClient } from '@backstage/catalog-client';
import { CacheClient } from '@backstage/backend-common';
import {
Entity,
CompoundEntityRef,
@@ -23,12 +23,12 @@ import {
export type CachedEntityLoaderOptions = {
catalog: CatalogClient;
cache: CacheClient;
cache: CacheService;
};
export class CachedEntityLoader {
private readonly catalog: CatalogClient;
private readonly cache: CacheClient;
private readonly cache: CacheService;
private readonly readTimeout = 1000;
constructor({ catalog, cache }: CachedEntityLoaderOptions) {
@@ -14,10 +14,7 @@
* limitations under the License.
*/
import {
loggerToWinstonLogger,
PluginEndpointDiscovery,
} from '@backstage/backend-common';
import { loggerToWinstonLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
import {
@@ -31,6 +28,7 @@ import { TechDocsCache } from '../cache';
import { DocsBuilder, shouldCheckForUpdate } from '../DocsBuilder';
import { DocsSynchronizer, DocsSynchronizerSyncOpts } from './DocsSynchronizer';
import { mockServices } from '@backstage/backend-test-utils';
import { DiscoveryService } from '@backstage/backend-plugin-api';
jest.mock('../DocsBuilder');
jest.useFakeTimers();
@@ -66,7 +64,7 @@ describe('DocsSynchronizer', () => {
hasDocsBeenGenerated: jest.fn(),
publish: jest.fn(),
};
const discovery: jest.Mocked<PluginEndpointDiscovery> = {
const discovery: jest.Mocked<DiscoveryService> = {
getBaseUrl: jest.fn(),
getExternalBaseUrl: jest.fn(),
};
@@ -14,7 +14,6 @@
* limitations under the License.
*/
import { PluginEndpointDiscovery } from '@backstage/backend-common';
import {
DEFAULT_NAMESPACE,
Entity,
@@ -38,6 +37,7 @@ import {
DocsBuilder,
shouldCheckForUpdate,
} from '../DocsBuilder';
import { DiscoveryService } from '@backstage/backend-plugin-api';
export type DocsSynchronizerSyncOpts = {
log: (message: string) => void;
@@ -189,7 +189,7 @@ export class DocsSynchronizer {
entity,
}: {
responseHandler: DocsSynchronizerSyncOpts;
discovery: PluginEndpointDiscovery;
discovery: DiscoveryService;
token: string | undefined;
entity: Entity;
}) {
@@ -14,12 +14,7 @@
* limitations under the License.
*/
import {
errorHandler,
loggerToWinstonLogger,
PluginCacheManager,
PluginEndpointDiscovery,
} from '@backstage/backend-common';
import { loggerToWinstonLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import {
DocsBuildStrategy,
@@ -34,6 +29,9 @@ import { CachedEntityLoader } from './CachedEntityLoader';
import { createEventStream, createRouter, RouterOptions } from './router';
import { TechDocsCache } from '../cache';
import { mockServices } from '@backstage/backend-test-utils';
import { DiscoveryService } from '@backstage/backend-plugin-api';
import { PluginCacheManager } from '@backstage/backend-defaults/cache';
import { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';
jest.mock('@backstage/catalog-client');
jest.mock('@backstage/config');
@@ -76,7 +74,11 @@ const getMockHttpResponseFor = (content: string): Buffer => {
const createApp = async (options: RouterOptions) => {
const app = express();
app.use(await createRouter(options));
app.use(errorHandler());
const errorHandler = MiddlewareFactory.create({
config: mockServices.rootConfig(),
logger: mockServices.rootLogger(),
}).error();
app.use(errorHandler);
return app;
};
@@ -112,7 +114,7 @@ describe('createRouter', () => {
hasDocsBeenGenerated: jest.fn(),
publish: jest.fn(),
};
const discovery: jest.Mocked<PluginEndpointDiscovery> = {
const discovery: jest.Mocked<DiscoveryService> = {
getBaseUrl: jest.fn(),
getExternalBaseUrl: jest.fn(),
};
+15 -9
View File
@@ -13,11 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
PluginEndpointDiscovery,
PluginCacheManager,
createLegacyAuthAdapters,
} from '@backstage/backend-common';
import { createLegacyAuthAdapters } from '@backstage/backend-common';
import { CatalogClient } from '@backstage/catalog-client';
import { stringifyEntityRef } from '@backstage/catalog-model';
import { Config } from '@backstage/config';
@@ -38,20 +34,26 @@ import { createCacheMiddleware, TechDocsCache } from '../cache';
import { CachedEntityLoader } from './CachedEntityLoader';
import { DefaultDocsBuildStrategy } from './DefaultDocsBuildStrategy';
import * as winston from 'winston';
import { AuthService, HttpAuthService } from '@backstage/backend-plugin-api';
import {
AuthService,
DiscoveryService,
HttpAuthService,
} from '@backstage/backend-plugin-api';
import { PluginCacheManager } from '@backstage/backend-defaults/cache';
/**
* Required dependencies for running TechDocs in the "out-of-the-box"
* deployment configuration (prepare/generate/publish all in the Backend).
*
* @public
*
*/
export type OutOfTheBoxDeploymentOptions = {
preparers: PreparerBuilder;
generators: GeneratorBuilder;
publisher: PublisherBase;
logger: winston.Logger;
discovery: PluginEndpointDiscovery;
discovery: DiscoveryService;
database?: Knex; // TODO: Make database required when we're implementing database stuff.
config: Config;
cache: PluginCacheManager;
@@ -67,11 +69,12 @@ export type OutOfTheBoxDeploymentOptions = {
* configuration (prepare/generate handled externally in CI/CD).
*
* @public
* @deprecated This type is only exported for legacy reasons and will be removed in the future.
*/
export type RecommendedDeploymentOptions = {
publisher: PublisherBase;
logger: winston.Logger;
discovery: PluginEndpointDiscovery;
discovery: DiscoveryService;
config: Config;
cache: PluginCacheManager;
docsBuildStrategy?: DocsBuildStrategy;
@@ -85,6 +88,7 @@ export type RecommendedDeploymentOptions = {
* One of the two deployment configurations must be provided.
*
* @public
* @deprecated This type is only exported for legacy reasons and will be removed in the future.
*/
export type RouterOptions =
| RecommendedDeploymentOptions
@@ -94,7 +98,7 @@ export type RouterOptions =
* Typeguard to help createRouter() understand when we are in a "recommended"
* deployment vs. when we are in an out-of-the-box deployment configuration.
*
* * @public
* @public
*/
function isOutOfTheBoxOption(
opt: RouterOptions,
@@ -106,6 +110,8 @@ function isOutOfTheBoxOption(
* Creates a techdocs router.
*
* @public
*@deprecated This function is only exported for legacy reasons and will be removed in the future.
* Please {@link https://backstage.io/docs/backend-system/building-backends/migrating | migrate } to use the new backend system and follow these {@link https://backstage.io/docs/features/techdocs/getting-started#new-backend-system | instructions } to install the user settings backend plugin.
*/
export async function createRouter(
options: RouterOptions,