Use Parameter Objects for Publisher Constructors
Refactored Techdocs publishers to use a single parameter object as the constructor argument to ease extendability as more options are introduced. Updated local publisher to use `.fromConfig` for instantiation so that it follows the same design pattern as the other publishers. Signed-off-by: Colton Padden <colton.padden@fastmail.com>
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
---
|
||||
'@backstage/techdocs-common': patch
|
||||
---
|
||||
|
||||
1. Techdocs publishers constructors now use parameter objects when being instantiated
|
||||
|
||||
2. The `LocalPublish` publisher can now be created using `fromConfig`:
|
||||
|
||||
```
|
||||
--- const publisher = new LocalPublish(config, logger, discovery);
|
||||
+++ const publisher = LocalPublish.fromConfig(config, logger, discovery);
|
||||
```
|
||||
@@ -57,6 +57,26 @@ const streamToBuffer = (stream: Readable): Promise<Buffer> => {
|
||||
};
|
||||
|
||||
export class AwsS3Publish implements PublisherBase {
|
||||
private readonly storageClient: aws.S3;
|
||||
private readonly bucketName: string;
|
||||
private readonly legacyPathCasing: boolean;
|
||||
private readonly logger: Logger;
|
||||
private readonly bucketRootPath: string;
|
||||
|
||||
constructor(options: {
|
||||
storageClient: aws.S3;
|
||||
bucketName: string;
|
||||
legacyPathCasing: boolean;
|
||||
logger: Logger;
|
||||
bucketRootPath: string;
|
||||
}) {
|
||||
this.storageClient = options.storageClient;
|
||||
this.bucketName = options.bucketName;
|
||||
this.legacyPathCasing = options.legacyPathCasing;
|
||||
this.logger = options.logger;
|
||||
this.bucketRootPath = options.bucketRootPath;
|
||||
}
|
||||
|
||||
static fromConfig(config: Config, logger: Logger): PublisherBase {
|
||||
let bucketName = '';
|
||||
try {
|
||||
@@ -112,13 +132,13 @@ export class AwsS3Publish implements PublisherBase {
|
||||
'techdocs.legacyUseCaseSensitiveTripletPaths',
|
||||
) || false;
|
||||
|
||||
return new AwsS3Publish(
|
||||
return new AwsS3Publish({
|
||||
storageClient,
|
||||
bucketName,
|
||||
bucketRootPath,
|
||||
legacyPathCasing,
|
||||
logger,
|
||||
bucketRootPath,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
private static buildCredentials(
|
||||
@@ -152,20 +172,6 @@ export class AwsS3Publish implements PublisherBase {
|
||||
return explicitCredentials;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly storageClient: aws.S3,
|
||||
private readonly bucketName: string,
|
||||
private readonly legacyPathCasing: boolean,
|
||||
private readonly logger: Logger,
|
||||
private readonly bucketRootPath: string,
|
||||
) {
|
||||
this.storageClient = storageClient;
|
||||
this.bucketName = bucketName;
|
||||
this.legacyPathCasing = legacyPathCasing;
|
||||
this.logger = logger;
|
||||
this.bucketRootPath = bucketRootPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the defined bucket exists. Being able to connect means the configuration is good
|
||||
* and the storage client will work.
|
||||
|
||||
@@ -47,6 +47,23 @@ import {
|
||||
const BATCH_CONCURRENCY = 3;
|
||||
|
||||
export class AzureBlobStoragePublish implements PublisherBase {
|
||||
private readonly storageClient: BlobServiceClient;
|
||||
private readonly containerName: string;
|
||||
private readonly legacyPathCasing: boolean;
|
||||
private readonly logger: Logger;
|
||||
|
||||
constructor(options: {
|
||||
storageClient: BlobServiceClient;
|
||||
containerName: string;
|
||||
legacyPathCasing: boolean;
|
||||
logger: Logger;
|
||||
}) {
|
||||
this.storageClient = options.storageClient;
|
||||
this.containerName = options.containerName;
|
||||
this.legacyPathCasing = options.legacyPathCasing;
|
||||
this.logger = options.logger;
|
||||
}
|
||||
|
||||
static fromConfig(config: Config, logger: Logger): PublisherBase {
|
||||
let containerName = '';
|
||||
try {
|
||||
@@ -95,24 +112,12 @@ export class AzureBlobStoragePublish implements PublisherBase {
|
||||
'techdocs.legacyUseCaseSensitiveTripletPaths',
|
||||
) || false;
|
||||
|
||||
return new AzureBlobStoragePublish(
|
||||
storageClient,
|
||||
containerName,
|
||||
legacyPathCasing,
|
||||
logger,
|
||||
);
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly storageClient: BlobServiceClient,
|
||||
private readonly containerName: string,
|
||||
private readonly legacyPathCasing: boolean,
|
||||
private readonly logger: Logger,
|
||||
) {
|
||||
this.storageClient = storageClient;
|
||||
this.containerName = containerName;
|
||||
this.legacyPathCasing = legacyPathCasing;
|
||||
this.logger = logger;
|
||||
return new AzureBlobStoragePublish({
|
||||
storageClient: storageClient,
|
||||
containerName: containerName,
|
||||
legacyPathCasing: legacyPathCasing,
|
||||
logger: logger,
|
||||
});
|
||||
}
|
||||
|
||||
async getReadiness(): Promise<ReadinessResponse> {
|
||||
|
||||
@@ -41,6 +41,26 @@ import {
|
||||
} from './types';
|
||||
|
||||
export class GoogleGCSPublish implements PublisherBase {
|
||||
private readonly storageClient: Storage;
|
||||
private readonly bucketName: string;
|
||||
private readonly legacyPathCasing: boolean;
|
||||
private readonly logger: Logger;
|
||||
private readonly bucketRootPath: string;
|
||||
|
||||
constructor(options: {
|
||||
storageClient: Storage;
|
||||
bucketName: string;
|
||||
legacyPathCasing: boolean;
|
||||
logger: Logger;
|
||||
bucketRootPath: string;
|
||||
}) {
|
||||
this.storageClient = options.storageClient;
|
||||
this.bucketName = options.bucketName;
|
||||
this.legacyPathCasing = options.legacyPathCasing;
|
||||
this.logger = options.logger;
|
||||
this.bucketRootPath = options.bucketRootPath;
|
||||
}
|
||||
|
||||
static fromConfig(config: Config, logger: Logger): PublisherBase {
|
||||
let bucketName = '';
|
||||
try {
|
||||
@@ -84,27 +104,13 @@ export class GoogleGCSPublish implements PublisherBase {
|
||||
'techdocs.legacyUseCaseSensitiveTripletPaths',
|
||||
) || false;
|
||||
|
||||
return new GoogleGCSPublish(
|
||||
return new GoogleGCSPublish({
|
||||
storageClient,
|
||||
bucketName,
|
||||
legacyPathCasing,
|
||||
logger,
|
||||
bucketRootPath,
|
||||
);
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly storageClient: Storage,
|
||||
private readonly bucketName: string,
|
||||
private readonly legacyPathCasing: boolean,
|
||||
private readonly logger: Logger,
|
||||
private readonly bucketRootPath: string,
|
||||
) {
|
||||
this.storageClient = storageClient;
|
||||
this.bucketName = bucketName;
|
||||
this.legacyPathCasing = legacyPathCasing;
|
||||
this.logger = logger;
|
||||
this.bucketRootPath = bucketRootPath;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -63,7 +63,11 @@ describe('local publisher', () => {
|
||||
|
||||
const mockConfig = new ConfigReader({});
|
||||
|
||||
const publisher = new LocalPublish(mockConfig, logger, testDiscovery);
|
||||
const publisher = LocalPublish.fromConfig(
|
||||
mockConfig,
|
||||
logger,
|
||||
testDiscovery,
|
||||
);
|
||||
const mockEntity = createMockEntity();
|
||||
const lowerMockEntity = createMockEntity(undefined, true);
|
||||
|
||||
@@ -90,7 +94,11 @@ describe('local publisher', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const publisher = new LocalPublish(mockConfig, logger, testDiscovery);
|
||||
const publisher = LocalPublish.fromConfig(
|
||||
mockConfig,
|
||||
logger,
|
||||
testDiscovery,
|
||||
);
|
||||
const mockEntity = createMockEntity();
|
||||
const lowerMockEntity = createMockEntity(undefined, true);
|
||||
|
||||
@@ -106,7 +114,11 @@ describe('local publisher', () => {
|
||||
|
||||
describe('docsRouter', () => {
|
||||
const mockConfig = new ConfigReader({});
|
||||
const publisher = new LocalPublish(mockConfig, logger, testDiscovery);
|
||||
const publisher = LocalPublish.fromConfig(
|
||||
mockConfig,
|
||||
logger,
|
||||
testDiscovery,
|
||||
);
|
||||
let app: express.Express;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -166,7 +178,7 @@ describe('local publisher', () => {
|
||||
legacyUseCaseSensitiveTripletPaths: true,
|
||||
},
|
||||
});
|
||||
const legacyPublisher = new LocalPublish(
|
||||
const legacyPublisher = LocalPublish.fromConfig(
|
||||
legacyConfig,
|
||||
logger,
|
||||
testDiscovery,
|
||||
|
||||
@@ -59,24 +59,37 @@ try {
|
||||
* called "static" at the root of techdocs-backend plugin.
|
||||
*/
|
||||
export class LocalPublish implements PublisherBase {
|
||||
private legacyPathCasing: boolean;
|
||||
private readonly legacyPathCasing: boolean;
|
||||
private readonly logger: Logger;
|
||||
private readonly discovery: PluginEndpointDiscovery;
|
||||
|
||||
// TODO: Use a static fromConfig method to create a LocalPublish instance, similar to aws/gcs publishers.
|
||||
// Move the logic of setting staticDocsDir based on config over to fromConfig,
|
||||
// and set the value as a class parameter.
|
||||
constructor(
|
||||
// @ts-ignore
|
||||
private readonly config: Config,
|
||||
private readonly logger: Logger,
|
||||
private readonly discovery: PluginEndpointDiscovery,
|
||||
) {
|
||||
this.config = config;
|
||||
this.logger = logger;
|
||||
this.discovery = discovery;
|
||||
this.legacyPathCasing =
|
||||
// TODO: Move the logic of setting staticDocsDir based on config over to
|
||||
// fromConfig, and set the value as a class parameter.
|
||||
constructor(options: {
|
||||
logger: Logger;
|
||||
discovery: PluginEndpointDiscovery;
|
||||
legacyPathCasing: boolean;
|
||||
}) {
|
||||
this.logger = options.logger;
|
||||
this.discovery = options.discovery;
|
||||
this.legacyPathCasing = options.legacyPathCasing;
|
||||
}
|
||||
|
||||
static fromConfig(
|
||||
config: Config,
|
||||
logger: Logger,
|
||||
discovery: PluginEndpointDiscovery,
|
||||
): PublisherBase {
|
||||
const legacyPathCasing =
|
||||
config.getOptionalBoolean(
|
||||
'techdocs.legacyUseCaseSensitiveTripletPaths',
|
||||
) || false;
|
||||
|
||||
return new LocalPublish({
|
||||
logger,
|
||||
discovery,
|
||||
legacyPathCasing,
|
||||
});
|
||||
}
|
||||
|
||||
async getReadiness(): Promise<ReadinessResponse> {
|
||||
|
||||
@@ -54,6 +54,20 @@ const bufferToStream = (buffer: Buffer): Readable => {
|
||||
};
|
||||
|
||||
export class OpenStackSwiftPublish implements PublisherBase {
|
||||
private readonly storageClient: SwiftClient;
|
||||
private readonly containerName: string;
|
||||
private readonly logger: Logger;
|
||||
|
||||
constructor(options: {
|
||||
storageClient: SwiftClient;
|
||||
containerName: string;
|
||||
logger: Logger;
|
||||
}) {
|
||||
this.storageClient = options.storageClient;
|
||||
this.containerName = options.containerName;
|
||||
this.logger = options.logger;
|
||||
}
|
||||
|
||||
static fromConfig(config: Config, logger: Logger): PublisherBase {
|
||||
let containerName = '';
|
||||
try {
|
||||
@@ -78,17 +92,7 @@ export class OpenStackSwiftPublish implements PublisherBase {
|
||||
secret: openStackSwiftConfig.getString('credentials.secret'),
|
||||
});
|
||||
|
||||
return new OpenStackSwiftPublish(storageClient, containerName, logger);
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly storageClient: SwiftClient,
|
||||
private readonly containerName: string,
|
||||
private readonly logger: Logger,
|
||||
) {
|
||||
this.storageClient = storageClient;
|
||||
this.containerName = containerName;
|
||||
this.logger = logger;
|
||||
return new OpenStackSwiftPublish({ storageClient, containerName, logger });
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -61,10 +61,10 @@ export class Publisher {
|
||||
return OpenStackSwiftPublish.fromConfig(config, logger);
|
||||
case 'local':
|
||||
logger.info('Creating Local publisher for TechDocs');
|
||||
return new LocalPublish(config, logger, discovery);
|
||||
return LocalPublish.fromConfig(config, logger, discovery);
|
||||
default:
|
||||
logger.info('Creating Local publisher for TechDocs');
|
||||
return new LocalPublish(config, logger, discovery);
|
||||
return LocalPublish.fromConfig(config, logger, discovery);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user