add publisher extension point
Signed-off-by: John Philip <jphilip@spotify.com>
This commit is contained in:
@@ -15,7 +15,13 @@
|
||||
*/
|
||||
import { createExtensionPoint } from '@backstage/backend-plugin-api';
|
||||
import { DocsBuildStrategy } from './techdocsTypes';
|
||||
import { PreparerBase, RemoteProtocol, TechdocsGenerator } from './stages';
|
||||
import {
|
||||
PreparerBase,
|
||||
PublisherBase,
|
||||
PublisherType,
|
||||
RemoteProtocol,
|
||||
TechdocsGenerator,
|
||||
} from './stages';
|
||||
import * as winston from 'winston';
|
||||
|
||||
/**
|
||||
@@ -75,3 +81,22 @@ export const techdocsPreparerExtensionPoint =
|
||||
createExtensionPoint<TechdocsPreparerExtensionPoint>({
|
||||
id: 'techdocs.preparer',
|
||||
});
|
||||
|
||||
/**
|
||||
* Extension point type for configuring a custom Techdocs publisher
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface TechdocsPublisherExtensionPoint {
|
||||
registerPublisher(type: PublisherType, publisher: PublisherBase): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension point for configuring a custom Techdocs publisher
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const techdocsPublisherExtensionPoint =
|
||||
createExtensionPoint<TechdocsPublisherExtensionPoint>({
|
||||
id: 'techdocs.publisher',
|
||||
});
|
||||
|
||||
@@ -27,7 +27,9 @@ export {
|
||||
techdocsBuildsExtensionPoint,
|
||||
techdocsGeneratorExtensionPoint,
|
||||
techdocsPreparerExtensionPoint,
|
||||
techdocsPublisherExtensionPoint,
|
||||
type TechdocsBuildsExtensionPoint,
|
||||
type TechdocsGeneratorExtensionPoint,
|
||||
type TechdocsPreparerExtensionPoint,
|
||||
type TechdocsPublisherExtensionPoint,
|
||||
} from './extensions';
|
||||
|
||||
@@ -25,6 +25,7 @@ import { AwsS3Publish } from './awsS3';
|
||||
import { AzureBlobStoragePublish } from './azureBlobStorage';
|
||||
import { OpenStackSwiftPublish } from './openStackSwift';
|
||||
import { mockServices } from '@backstage/backend-test-utils';
|
||||
import { PublisherBase } from './types';
|
||||
|
||||
const logger = loggerToWinstonLogger(mockServices.logger.mock());
|
||||
const discovery: jest.Mocked<PluginEndpointDiscovery> = {
|
||||
@@ -184,4 +185,20 @@ describe('Publisher', () => {
|
||||
});
|
||||
expect(publisher).toBeInstanceOf(OpenStackSwiftPublish);
|
||||
});
|
||||
|
||||
it('registers a custom publisher if provided', async () => {
|
||||
const mockConfig = new ConfigReader({});
|
||||
|
||||
const customPublisher = {
|
||||
publish: jest.fn(),
|
||||
} as unknown as PublisherBase;
|
||||
|
||||
const publisher = await Publisher.fromConfig(mockConfig, {
|
||||
logger,
|
||||
discovery,
|
||||
customPublisher,
|
||||
});
|
||||
|
||||
expect(publisher).toBe(customPublisher);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,14 +20,47 @@ import { AzureBlobStoragePublish } from './azureBlobStorage';
|
||||
import { GoogleGCSPublish } from './googleStorage';
|
||||
import { LocalPublish } from './local';
|
||||
import { OpenStackSwiftPublish } from './openStackSwift';
|
||||
import { PublisherFactory, PublisherBase, PublisherType } from './types';
|
||||
import {
|
||||
PublisherFactory,
|
||||
PublisherBase,
|
||||
PublisherType,
|
||||
PublisherBuilder,
|
||||
} from './types';
|
||||
|
||||
/**
|
||||
* Factory class to create a TechDocs publisher based on defined publisher type in app config.
|
||||
* Uses `techdocs.publisher.type`.
|
||||
* @public
|
||||
*/
|
||||
export class Publisher {
|
||||
|
||||
type CustomPublisherType = PublisherType | 'techdocs';
|
||||
|
||||
export class Publisher implements PublisherBuilder {
|
||||
private publishers: Map<CustomPublisherType, PublisherBase> = new Map();
|
||||
|
||||
register(type: CustomPublisherType, publisher: PublisherBase): void {
|
||||
this.publishers.set(type, publisher);
|
||||
}
|
||||
|
||||
get(config: Config): PublisherBase {
|
||||
const publisherType = (config.getOptionalString(
|
||||
'techdocs.publisher.type',
|
||||
) ?? 'local') as PublisherType;
|
||||
|
||||
if (!publisherType) {
|
||||
throw new Error('TechDocs publisher type not specified for the entity');
|
||||
}
|
||||
|
||||
const publisher = this.publishers.get(publisherType);
|
||||
if (!publisher) {
|
||||
throw new Error(
|
||||
`TechDocs publisher '${publisherType}' is not registered`,
|
||||
);
|
||||
}
|
||||
|
||||
return publisher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a instance of TechDocs publisher
|
||||
* @param config - A Backstage configuration
|
||||
@@ -37,7 +70,14 @@ export class Publisher {
|
||||
config: Config,
|
||||
options: PublisherFactory,
|
||||
): Promise<PublisherBase> {
|
||||
const { logger, discovery } = options;
|
||||
const { logger, discovery, customPublisher } = options;
|
||||
|
||||
const publishers = new Publisher();
|
||||
|
||||
if (customPublisher) {
|
||||
publishers.register('techdocs', customPublisher);
|
||||
return customPublisher;
|
||||
}
|
||||
|
||||
const publisherType = (config.getOptionalString(
|
||||
'techdocs.publisher.type',
|
||||
@@ -46,26 +86,51 @@ export class Publisher {
|
||||
switch (publisherType) {
|
||||
case 'googleGcs':
|
||||
logger.info('Creating Google Storage Bucket publisher for TechDocs');
|
||||
return GoogleGCSPublish.fromConfig(config, logger);
|
||||
publishers.register(
|
||||
publisherType,
|
||||
GoogleGCSPublish.fromConfig(config, logger),
|
||||
);
|
||||
break;
|
||||
case 'awsS3':
|
||||
logger.info('Creating AWS S3 Bucket publisher for TechDocs');
|
||||
return await AwsS3Publish.fromConfig(config, logger);
|
||||
publishers.register(
|
||||
publisherType,
|
||||
await AwsS3Publish.fromConfig(config, logger),
|
||||
);
|
||||
break;
|
||||
case 'azureBlobStorage':
|
||||
logger.info(
|
||||
'Creating Azure Blob Storage Container publisher for TechDocs',
|
||||
);
|
||||
return AzureBlobStoragePublish.fromConfig(config, logger);
|
||||
publishers.register(
|
||||
publisherType,
|
||||
AzureBlobStoragePublish.fromConfig(config, logger),
|
||||
);
|
||||
break;
|
||||
case 'openStackSwift':
|
||||
logger.info(
|
||||
'Creating OpenStack Swift Container publisher for TechDocs',
|
||||
);
|
||||
return OpenStackSwiftPublish.fromConfig(config, logger);
|
||||
publishers.register(
|
||||
publisherType,
|
||||
OpenStackSwiftPublish.fromConfig(config, logger),
|
||||
);
|
||||
break;
|
||||
case 'local':
|
||||
logger.info('Creating Local publisher for TechDocs');
|
||||
return LocalPublish.fromConfig(config, logger, discovery);
|
||||
publishers.register(
|
||||
publisherType,
|
||||
LocalPublish.fromConfig(config, logger, discovery),
|
||||
);
|
||||
break;
|
||||
default:
|
||||
logger.info('Creating Local publisher for TechDocs');
|
||||
return LocalPublish.fromConfig(config, logger, discovery);
|
||||
publishers.register(
|
||||
publisherType,
|
||||
LocalPublish.fromConfig(config, logger, discovery),
|
||||
);
|
||||
}
|
||||
|
||||
return publishers.get(config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import { Entity, CompoundEntityRef } from '@backstage/catalog-model';
|
||||
import { PluginEndpointDiscovery } from '@backstage/backend-common';
|
||||
import { Logger } from 'winston';
|
||||
import express from 'express';
|
||||
import { Config } from '@backstage/config';
|
||||
|
||||
/**
|
||||
* Options for building publishers
|
||||
@@ -25,6 +26,7 @@ import express from 'express';
|
||||
export type PublisherFactory = {
|
||||
logger: Logger;
|
||||
discovery: PluginEndpointDiscovery;
|
||||
customPublisher?: PublisherBase | undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -157,3 +159,12 @@ export interface PublisherBase {
|
||||
*/
|
||||
migrateDocsCase?(migrateRequest: MigrateRequest): Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definition for a TechDocs publisher builder
|
||||
* @public
|
||||
*/
|
||||
export type PublisherBuilder = {
|
||||
register(type: PublisherType, publisher: PublisherBase): void;
|
||||
get(config: Config): PublisherBase;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user