Techdocs: support HumanDuration for cache config
Signed-off-by: Gabriel Dugny <gabriel.dugny@believe.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-backend': minor
|
||||
---
|
||||
|
||||
Techdocs: support HumanDuration for cache TTL and timeout configuration
|
||||
Vendored
+6
-4
@@ -14,6 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { HumanDuration } from '@backstage/types';
|
||||
|
||||
export interface Config {
|
||||
/**
|
||||
* Configuration options for the techdocs-backend plugin
|
||||
@@ -277,7 +279,7 @@ export interface Config {
|
||||
*/
|
||||
cache?: {
|
||||
/**
|
||||
* The cache time-to-live for TechDocs sites (in milliseconds). Set this
|
||||
* The cache time-to-live for TechDocs sites, in milliseconds for a number or a human duration. Set this
|
||||
* to a non-zero value to cache TechDocs sites and assets as they are
|
||||
* read from storage.
|
||||
*
|
||||
@@ -285,16 +287,16 @@ export interface Config {
|
||||
* and to pass a PluginCacheManager instance to TechDocs Backend's
|
||||
* createRouter method in your backend.
|
||||
*/
|
||||
ttl: number;
|
||||
ttl: number | HumanDuration | string;
|
||||
|
||||
/**
|
||||
* The time (in milliseconds) that the TechDocs backend will wait for
|
||||
* The time (in milliseconds for a number or a human duration) that the TechDocs backend will wait for
|
||||
* a cache service to respond before continuing on as though the cached
|
||||
* object was not found (e.g. when the cache sercice is unavailable).
|
||||
*
|
||||
* Defaults to 1000 milliseconds.
|
||||
*/
|
||||
readTimeout?: number;
|
||||
readTimeout?: number | HumanDuration | string;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
"@backstage/plugin-search-backend-module-techdocs": "workspace:^",
|
||||
"@backstage/plugin-techdocs-common": "workspace:^",
|
||||
"@backstage/plugin-techdocs-node": "workspace:^",
|
||||
"@backstage/types": "workspace:^",
|
||||
"express": "^4.17.1",
|
||||
"express-promise-router": "^4.1.0",
|
||||
"fs-extra": "^11.2.0",
|
||||
|
||||
+16
-3
@@ -14,8 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { assertError, CustomErrorBase } from '@backstage/errors';
|
||||
import { Config } from '@backstage/config';
|
||||
import { Config, readDurationFromConfig } from '@backstage/config';
|
||||
import { CacheService, LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { durationToMilliseconds } from '@backstage/types';
|
||||
|
||||
export class CacheInvalidationError extends CustomErrorBase {}
|
||||
|
||||
@@ -42,8 +43,20 @@ export class TechDocsCache {
|
||||
config: Config,
|
||||
{ cache, logger }: { cache: CacheService; logger: LoggerService },
|
||||
) {
|
||||
const timeout = config.getOptionalNumber('techdocs.cache.readTimeout');
|
||||
const readTimeout = timeout === undefined ? 1000 : timeout;
|
||||
let readTimeout: number;
|
||||
if (config.has('techdocs.cache.readTimeout')) {
|
||||
if (typeof config.get('techdocs.cache.readTimeout') === 'number') {
|
||||
readTimeout = config.getNumber('techdocs.cache.readTimeout');
|
||||
} else {
|
||||
readTimeout = durationToMilliseconds(
|
||||
readDurationFromConfig(config, {
|
||||
key: 'techdocs.cache.readTimeout',
|
||||
}),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
readTimeout = 1000;
|
||||
}
|
||||
return new TechDocsCache({ cache, logger, readTimeout });
|
||||
}
|
||||
|
||||
|
||||
@@ -30,14 +30,10 @@ import { TechDocsCache } from '../cache';
|
||||
import { mockErrorHandler, mockServices } from '@backstage/backend-test-utils';
|
||||
|
||||
jest.mock('@backstage/catalog-client');
|
||||
jest.mock('@backstage/config');
|
||||
jest.mock('./CachedEntityLoader');
|
||||
jest.mock('./DocsSynchronizer');
|
||||
jest.mock('../cache/TechDocsCache');
|
||||
|
||||
const MockedConfigReader = ConfigReader as jest.MockedClass<
|
||||
typeof ConfigReader
|
||||
>;
|
||||
const MockDocsSynchronizer = DocsSynchronizer as jest.MockedClass<
|
||||
typeof DocsSynchronizer
|
||||
>;
|
||||
@@ -115,7 +111,13 @@ describe('createRouter', () => {
|
||||
preparers,
|
||||
generators,
|
||||
publisher,
|
||||
config: new ConfigReader({}),
|
||||
config: new ConfigReader({
|
||||
techdocs: {
|
||||
cache: {
|
||||
ttl: 1,
|
||||
},
|
||||
},
|
||||
}),
|
||||
logger: mockServices.logger.mock(),
|
||||
discovery,
|
||||
cache: mockServices.cache.mock(),
|
||||
@@ -143,9 +145,6 @@ describe('createRouter', () => {
|
||||
discovery.getBaseUrl.mockImplementation(async type => {
|
||||
return `http://backstage.local/api/${type}`;
|
||||
});
|
||||
MockedConfigReader.prototype.getOptionalNumber.mockImplementation(key =>
|
||||
key === 'techdocs.cache.ttl' ? 1 : undefined,
|
||||
);
|
||||
MockTechDocsCache.get.mockResolvedValue(undefined);
|
||||
MockTechDocsCache.set.mockResolvedValue();
|
||||
});
|
||||
@@ -326,13 +325,17 @@ data: {"updated":true}
|
||||
});
|
||||
|
||||
it('should check entity access when permissions are enabled', async () => {
|
||||
MockedConfigReader.prototype.getOptionalBoolean.mockImplementation(key =>
|
||||
key === 'permission.enabled' ? true : undefined,
|
||||
);
|
||||
const docsRouter = jest.fn((_req, res) => res.sendStatus(200));
|
||||
publisher.docsRouter.mockReturnValue(docsRouter);
|
||||
|
||||
const app = await createApp(outOfTheBoxOptions);
|
||||
const app = await createApp({
|
||||
...outOfTheBoxOptions,
|
||||
config: new ConfigReader({
|
||||
permission: {
|
||||
enabled: true,
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
MockCachedEntityLoader.prototype.load.mockResolvedValue(entity);
|
||||
|
||||
@@ -345,11 +348,14 @@ data: {"updated":true}
|
||||
});
|
||||
|
||||
it('should not return assets without corresponding entity access', async () => {
|
||||
MockedConfigReader.prototype.getOptionalBoolean.mockImplementation(key =>
|
||||
key === 'permission.enabled' ? true : undefined,
|
||||
);
|
||||
|
||||
const app = await createApp(outOfTheBoxOptions);
|
||||
const app = await createApp({
|
||||
...outOfTheBoxOptions,
|
||||
config: new ConfigReader({
|
||||
permission: {
|
||||
enabled: true,
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
MockCachedEntityLoader.prototype.load.mockResolvedValue(undefined);
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import { CatalogApi, CatalogClient } from '@backstage/catalog-client';
|
||||
import { stringifyEntityRef } from '@backstage/catalog-model';
|
||||
import { Config } from '@backstage/config';
|
||||
import { Config, readDurationFromConfig } from '@backstage/config';
|
||||
import { NotFoundError } from '@backstage/errors';
|
||||
import {
|
||||
DocsBuildStrategy,
|
||||
@@ -41,6 +41,7 @@ import {
|
||||
HttpAuthService,
|
||||
LoggerService,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { durationToMilliseconds } from '@backstage/types';
|
||||
|
||||
/**
|
||||
* Required dependencies for running TechDocs in the "out-of-the-box"
|
||||
@@ -130,9 +131,18 @@ export async function createRouter(
|
||||
|
||||
// Set up a cache client if configured.
|
||||
let cache: TechDocsCache | undefined;
|
||||
const defaultTtl = config.getOptionalNumber('techdocs.cache.ttl');
|
||||
if (defaultTtl) {
|
||||
const cacheClient = options.cache.withOptions({ defaultTtl });
|
||||
if (config.has('techdocs.cache.ttl')) {
|
||||
let ttlMs: number;
|
||||
if (typeof config.get('techdocs.cache.ttl') === 'number') {
|
||||
ttlMs = config.getNumber('techdocs.cache.ttl');
|
||||
} else {
|
||||
ttlMs = durationToMilliseconds(
|
||||
readDurationFromConfig(config, {
|
||||
key: 'techdocs.cache.ttl',
|
||||
}),
|
||||
);
|
||||
}
|
||||
const cacheClient = options.cache.withOptions({ defaultTtl: ttlMs });
|
||||
cache = TechDocsCache.fromConfig(config, { cache: cacheClient, logger });
|
||||
}
|
||||
|
||||
|
||||
@@ -8720,6 +8720,7 @@ __metadata:
|
||||
"@backstage/plugin-search-backend-module-techdocs": "workspace:^"
|
||||
"@backstage/plugin-techdocs-common": "workspace:^"
|
||||
"@backstage/plugin-techdocs-node": "workspace:^"
|
||||
"@backstage/types": "workspace:^"
|
||||
"@types/express": "npm:^4.17.6"
|
||||
express: "npm:^4.17.1"
|
||||
express-promise-router: "npm:^4.1.0"
|
||||
|
||||
Reference in New Issue
Block a user