mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: Create initializer to instantiate dynamic pods
This commit is contained in:
parent
b78599182c
commit
28b077b84e
@ -18,6 +18,7 @@ export * from './authorization/WebAclAuthorizer';
|
|||||||
// Init
|
// Init
|
||||||
export * from './init/AclInitializer';
|
export * from './init/AclInitializer';
|
||||||
export * from './init/CliRunner';
|
export * from './init/CliRunner';
|
||||||
|
export * from './init/ConfigPodInitializer';
|
||||||
export * from './init/Initializer';
|
export * from './init/Initializer';
|
||||||
export * from './init/LoggerInitializer';
|
export * from './init/LoggerInitializer';
|
||||||
export * from './init/RootContainerInitializer';
|
export * from './init/RootContainerInitializer';
|
||||||
|
47
src/init/ConfigPodInitializer.ts
Normal file
47
src/init/ConfigPodInitializer.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
|
||||||
|
import { getLoggerFor } from '../logging/LogUtil';
|
||||||
|
import type { ComponentsJsFactory } from '../pods/generate/ComponentsJsFactory';
|
||||||
|
import { TEMPLATE, TEMPLATE_VARIABLE } from '../pods/generate/variables/Variables';
|
||||||
|
import type { KeyValueStorage } from '../storage/keyvalue/KeyValueStorage';
|
||||||
|
import type { ResourceStore } from '../storage/ResourceStore';
|
||||||
|
import { Initializer } from './Initializer';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes all pods that have been stored and loads them in memory.
|
||||||
|
* This reads the pod settings from a permanent storage and uses those
|
||||||
|
* to create the corresponding ResourceStores in memory,
|
||||||
|
* so this is required every time the server starts.
|
||||||
|
*
|
||||||
|
* Part of the dynamic pod creation.
|
||||||
|
* Reads the contents from the configuration storage, uses those values to instantiate ResourceStores,
|
||||||
|
* and then adds them to the routing storage.
|
||||||
|
* @see {@link ConfigPodManager}, {@link TemplatedPodGenerator}, {@link BaseUrlRouterRule}
|
||||||
|
*/
|
||||||
|
export class ConfigPodInitializer extends Initializer {
|
||||||
|
protected readonly logger = getLoggerFor(this);
|
||||||
|
private readonly storeFactory: ComponentsJsFactory;
|
||||||
|
private readonly configStorage: KeyValueStorage<string, unknown>;
|
||||||
|
private readonly routingStorage: KeyValueStorage<ResourceIdentifier, ResourceStore>;
|
||||||
|
|
||||||
|
public constructor(storeFactory: ComponentsJsFactory,
|
||||||
|
configStorage: KeyValueStorage<string, unknown>,
|
||||||
|
routingStorage: KeyValueStorage<ResourceIdentifier, ResourceStore>) {
|
||||||
|
super();
|
||||||
|
this.storeFactory = storeFactory;
|
||||||
|
this.configStorage = configStorage;
|
||||||
|
this.routingStorage = routingStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async handle(): Promise<void> {
|
||||||
|
let count = 0;
|
||||||
|
for await (const [ path, value ] of this.configStorage.entries()) {
|
||||||
|
const config = value as NodeJS.Dict<string>;
|
||||||
|
const store: ResourceStore =
|
||||||
|
await this.storeFactory.generate(config[TEMPLATE_VARIABLE.templateConfig]!, TEMPLATE.ResourceStore, config);
|
||||||
|
await this.routingStorage.set({ path }, store);
|
||||||
|
this.logger.debug(`Initialized pod at ${path}`);
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
this.logger.info(`Initialized ${count} dynamic pods.`);
|
||||||
|
}
|
||||||
|
}
|
44
test/unit/init/ConfigPodInitializer.test.ts
Normal file
44
test/unit/init/ConfigPodInitializer.test.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { ConfigPodInitializer } from '../../../src/init/ConfigPodInitializer';
|
||||||
|
import type { ResourceIdentifier } from '../../../src/ldp/representation/ResourceIdentifier';
|
||||||
|
import type { ComponentsJsFactory } from '../../../src/pods/generate/ComponentsJsFactory';
|
||||||
|
import { TEMPLATE, TEMPLATE_VARIABLE } from '../../../src/pods/generate/variables/Variables';
|
||||||
|
import type { KeyValueStorage } from '../../../src/storage/keyvalue/KeyValueStorage';
|
||||||
|
import type { ResourceStore } from '../../../src/storage/ResourceStore';
|
||||||
|
|
||||||
|
describe('A ConfigPodInitializer', (): void => {
|
||||||
|
let storeFactory: ComponentsJsFactory;
|
||||||
|
let configStorage: KeyValueStorage<string, unknown>;
|
||||||
|
let routingStorage: KeyValueStorage<ResourceIdentifier, ResourceStore>;
|
||||||
|
let initializer: ConfigPodInitializer;
|
||||||
|
const identifierA = { path: 'http://test.com/A' };
|
||||||
|
const identifierB = { path: 'http://test.com/B' };
|
||||||
|
const configA = { [TEMPLATE_VARIABLE.templateConfig]: 'templateA' };
|
||||||
|
const configB = { [TEMPLATE_VARIABLE.templateConfig]: 'templateB' };
|
||||||
|
|
||||||
|
beforeEach(async(): Promise<void> => {
|
||||||
|
storeFactory = {
|
||||||
|
generate: jest.fn().mockResolvedValue('store'),
|
||||||
|
} as any;
|
||||||
|
|
||||||
|
configStorage = new Map<string, unknown>() as any;
|
||||||
|
await configStorage.set(identifierA.path, configA);
|
||||||
|
await configStorage.set(identifierB.path, configB);
|
||||||
|
|
||||||
|
const map = new Map();
|
||||||
|
routingStorage = {
|
||||||
|
get: async(identifier: ResourceIdentifier): Promise<ResourceStore | undefined> => map.get(identifier.path),
|
||||||
|
set: async(identifier: ResourceIdentifier, value: ResourceStore): Promise<any> => map.set(identifier.path, value),
|
||||||
|
} as any;
|
||||||
|
|
||||||
|
initializer = new ConfigPodInitializer(storeFactory, configStorage, routingStorage);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('generates a pod for every entry in the config storage.', async(): Promise<void> => {
|
||||||
|
await initializer.handle();
|
||||||
|
expect(storeFactory.generate).toHaveBeenCalledTimes(2);
|
||||||
|
expect(storeFactory.generate).toHaveBeenCalledWith('templateA', TEMPLATE.ResourceStore, configA);
|
||||||
|
expect(storeFactory.generate).toHaveBeenCalledWith('templateB', TEMPLATE.ResourceStore, configB);
|
||||||
|
await expect(routingStorage.get(identifierA)).resolves.toBe('store');
|
||||||
|
await expect(routingStorage.get(identifierB)).resolves.toBe('store');
|
||||||
|
});
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user