Skip to content

Commit

Permalink
feat(config): enable swapping of configuration providers dynamically (#…
Browse files Browse the repository at this point in the history
…1818)

* feat(config): enable swapping of configuration providers dynamically

* refactor: move import location
  • Loading branch information
blacha authored Aug 18, 2021
1 parent eb56f26 commit e548ae5
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 39 deletions.
36 changes: 31 additions & 5 deletions packages/config/src/base.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,28 @@ import { BaseConfig } from './config/base';
import { ConfigPrefix } from './config/prefix';
import { ConfigLayer, ConfigTileSet, TileSetType } from './config/tile.set';

export abstract class BasemapsConfig {
abstract TileSet: BasemapsConfigObject<ConfigTileSet>;
abstract Imagery: BasemapsConfigObject<ConfigImagery>;
abstract Style: BasemapsConfigObject<ConfigVectorStyle>;
abstract Provider: BasemapsConfigObject<ConfigProvider>;
export class ConfigInstance {
cfg: BasemapsConfigProvider;

get TileSet(): BasemapsConfigObject<ConfigTileSet> {
return this.cfg.TileSet;
}

get Imagery(): BasemapsConfigObject<ConfigImagery> {
return this.cfg.Imagery;
}

get Style(): BasemapsConfigObject<ConfigVectorStyle> {
return this.cfg.Style;
}

get Provider(): BasemapsConfigObject<ConfigProvider> {
return this.cfg.Provider;
}

setConfigProvider(cfg: BasemapsConfigProvider): void {
this.cfg = cfg;
}

isTileSetRaster(s: ConfigTileSet | null): s is ConfigTileSetRaster {
if (s == null) return false;
Expand Down Expand Up @@ -57,6 +74,13 @@ export abstract class BasemapsConfig {
}
}

export abstract class BasemapsConfigProvider {
abstract TileSet: BasemapsConfigObject<ConfigTileSet>;
abstract Imagery: BasemapsConfigObject<ConfigImagery>;
abstract Style: BasemapsConfigObject<ConfigVectorStyle>;
abstract Provider: BasemapsConfigObject<ConfigProvider>;
}

export abstract class BasemapsConfigObject<T extends BaseConfig> {
prefix: ConfigPrefix;

Expand All @@ -78,3 +102,5 @@ export abstract class BasemapsConfigObject<T extends BaseConfig> {
/** Fetch all objects from the store */
abstract getAll(id: Set<string>): Promise<Map<string, T>>;
}

export const Config = new ConfigInstance();
29 changes: 17 additions & 12 deletions packages/config/src/dynamo/__tests__/config.imagery.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Epsg, EpsgCode, NamedBounds, QuadKey, TileMatrixSet, TileMatrixSets } from '@basemaps/geo';
import o from 'ospec';
import { createSandbox } from 'sinon';
import { Config } from '../../base.config';
import { ConfigImagery } from '../../config/imagery';
import { ConfigDynamo } from '../dynamo.config';
import { ConfigProviderDynamo } from '../dynamo.config';

export function qkToNamedBounds(quadKeys: string[]): NamedBounds[] {
const tms = TileMatrixSets.get(EpsgCode.Google);
Expand All @@ -12,50 +13,54 @@ export function qkToNamedBounds(quadKeys: string[]): NamedBounds[] {
}));
}

o.spec('ConfigDynamoImagery', () => {
const config = new ConfigDynamo('Foo');
o.spec('ConfigProvider.Imagery', () => {
const provider = new ConfigProviderDynamo('Foo');
const sandbox = createSandbox();

o.beforeEach(() => {
Config.setConfigProvider(provider);
});

o.afterEach(() => sandbox.restore());

const item: ConfigImagery = { id: 'im_foo', name: 'abc' } as any;

o('is', () => {
o(config.Imagery.is(item)).equals(true);
o(config.Imagery.is({ id: 'ts_foo' } as any)).equals(false);
if (config.Imagery.is(item)) {
o(Config.Imagery.is(item)).equals(true);
o(Config.Imagery.is({ id: 'ts_foo' } as any)).equals(false);
if (Config.Imagery.is(item)) {
o(item.name).equals('abc'); // tests compiler
}
});

o('Should get Imagery', async () => {
const get = sandbox.stub(config.Imagery, 'get').resolves(item);
const get = sandbox.stub(provider.Imagery, 'get').resolves(item);

const layer = { [2193]: 'foo' } as any;
const result = await config.getImagery(layer, Epsg.Nztm2000);
const result = await Config.getImagery(layer, Epsg.Nztm2000);
o(get.callCount).equals(1);
o(get.firstCall.firstArg).equals('im_foo');
o(result).deepEquals(item);
});

o('Should not get Imagery with wrong projection', async () => {
const layer = { [2193]: 'foo' } as any;
const result = await config.getImagery(layer, Epsg.Google);
const result = await Config.getImagery(layer, Epsg.Google);
o(result).equals(null);
});

o('Should not get Imagery with no imgId', async () => {
const rule = {} as any;
const result = await config.getImagery(rule, Epsg.Google);
const result = await Config.getImagery(rule, Epsg.Google);
o(result).equals(null);
});

o('Should get all Imagery with correct order', async () => {
const get = sandbox.stub(config.Imagery, 'get').resolves(item);
const get = sandbox.stub(provider.Imagery, 'get').resolves(item);

const layers = [{ [3857]: 'foo1' }, { [3857]: 'foo2' }, { [2193]: 'foo3', [3857]: 'foo4' }] as any;

const result = await config.getAllImagery(layers, Epsg.Google);
const result = await Config.getAllImagery(layers, Epsg.Google);
o(get.callCount).equals(3);
o(get.firstCall.firstArg).equals('im_foo1');
o(get.secondCall.firstArg).equals('im_foo2');
Expand Down
6 changes: 3 additions & 3 deletions packages/config/src/dynamo/__tests__/config.provider.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import o from 'ospec';
import { ConfigDynamo } from '../dynamo.config';
import { ConfigProviderDynamo } from '../dynamo.config';

o.spec('ConfigDynamoProvider', () => {
const Config = new ConfigDynamo('table');
o.spec('ConfigProviderDynamo', () => {
const Config = new ConfigProviderDynamo('table');

o.spec('id', () => {
o('should create ids', () => {
Expand Down
6 changes: 3 additions & 3 deletions packages/config/src/dynamo/dynamo.config.base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ import DynamoDB from 'aws-sdk/clients/dynamodb';
import { BasemapsConfigObject } from '../base.config';
import { BaseConfig } from '../config/base';
import { ConfigPrefix } from '../config/prefix';
import { ConfigDynamo } from './dynamo.config';
import { ConfigProviderDynamo } from './dynamo.config';

function toId(id: string): { id: { S: string } } {
return { id: { S: id } };
}

export class ConfigDynamoBase<T extends BaseConfig = BaseConfig> extends BasemapsConfigObject<T> {
cfg: ConfigDynamo;
cfg: ConfigProviderDynamo;

constructor(cfg: ConfigDynamo, prefix: ConfigPrefix) {
constructor(cfg: ConfigProviderDynamo, prefix: ConfigPrefix) {
super(prefix);
this.cfg = cfg;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/config/src/dynamo/dynamo.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import DynamoDB from 'aws-sdk/clients/dynamodb';
import { BasemapsConfig } from '../base.config';
import { BasemapsConfigProvider } from '../base.config';
import { BaseConfig } from '../config/base';
import { ConfigImagery } from '../config/imagery';
import { ConfigPrefix } from '../config/prefix';
Expand All @@ -9,7 +9,7 @@ import { ConfigVectorStyle } from '../config/vector.style';
import { ConfigDynamoBase } from './dynamo.config.base';
import { ConfigDynamoCached } from './dynamo.config.cached';

export class ConfigDynamo extends BasemapsConfig {
export class ConfigProviderDynamo extends BasemapsConfigProvider {
Prefix = ConfigPrefix;

dynamo: DynamoDB;
Expand Down
10 changes: 5 additions & 5 deletions packages/config/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export { BasemapsConfigProvider, Config, ConfigInstance } from './base.config';
export { BaseConfig } from './config/base';
export { ConfigImagery } from './config/imagery';
export { ConfigVectorStyle, Sources, StyleJson } from './config/vector.style';
export { ConfigProvider } from './config/provider';
export {
ConfigLayer,
Expand All @@ -10,8 +10,8 @@ export {
TileResizeKernel,
TileSetType,
} from './config/tile.set';
export { ConfigDynamo } from './dynamo/dynamo.config';
export { TileSetNameComponents, TileSetNameParser } from './tile.set.name';
export { ConfigVectorStyle, Sources, StyleJson } from './config/vector.style';
export { ConfigProviderDynamo } from './dynamo/dynamo.config';
export { ConfigDynamoBase } from './dynamo/dynamo.config.base';
export { BasemapsConfig } from './base.config';
export { MemoryConfig } from './memory/memory.config';
export { ConfigProviderMemory } from './memory/memory.config';
export { TileSetNameComponents, TileSetNameParser } from './tile.set.name';
4 changes: 2 additions & 2 deletions packages/config/src/memory/__tests__/memory.config.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import o from 'ospec';
import { ConfigImagery } from '../../config/imagery';
import { ConfigTileSet } from '../../config/tile.set';
import { MemoryConfig } from '../memory.config';
import { ConfigProviderMemory } from '../memory.config';

o.spec('MemoryConfig', () => {
const config = new MemoryConfig();
const config = new ConfigProviderMemory();
o.beforeEach(() => config.objects.clear());

const baseImg = { id: 'im_123' } as ConfigImagery;
Expand Down
8 changes: 4 additions & 4 deletions packages/config/src/memory/memory.config.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { BasemapsConfig, BasemapsConfigObject } from '../base.config';
import { BasemapsConfigProvider, BasemapsConfigObject } from '../base.config';
import { BaseConfig } from '../config/base';
import { ConfigImagery } from '../config/imagery';
import { ConfigPrefix } from '../config/prefix';
import { ConfigProvider } from '../config/provider';
import { ConfigTileSet } from '../config/tile.set';
import { ConfigVectorStyle } from '../config/vector.style';

export class MemoryConfig extends BasemapsConfig {
export class ConfigProviderMemory extends BasemapsConfigProvider {
Imagery = new MemoryConfigObject<ConfigImagery>(this, ConfigPrefix.Imagery);
Style = new MemoryConfigObject<ConfigVectorStyle>(this, ConfigPrefix.Style);
TileSet = new MemoryConfigObject<ConfigTileSet>(this, ConfigPrefix.TileSet);
Expand All @@ -22,9 +22,9 @@ export class MemoryConfig extends BasemapsConfig {

export class MemoryConfigObject<T extends BaseConfig> extends BasemapsConfigObject<T> {
prefix: ConfigPrefix;
cfg: MemoryConfig;
cfg: ConfigProviderMemory;

constructor(cfg: MemoryConfig, prefix: ConfigPrefix) {
constructor(cfg: ConfigProviderMemory, prefix: ConfigPrefix) {
super(prefix);
this.cfg = cfg;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/shared/src/aws/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/
process.env['AWS_NODEJS_CONNECTION_REUSE_ENABLED'] = '1';

import { ConfigDynamo, BasemapsConfig } from '@basemaps/config';
import { Config, ConfigProviderDynamo } from '@basemaps/config';
import S3 from 'aws-sdk/clients/s3';
import { ChainableTemporaryCredentials } from 'aws-sdk/lib/credentials/chainable_temporary_credentials';
import { Const } from '../const';
Expand All @@ -34,4 +34,4 @@ export const Aws = {
apiKey: new ApiKeyTable(),
};

export const Config: BasemapsConfig = new ConfigDynamo(Const.TileMetadata.TableName);
Config.setConfigProvider(new ConfigProviderDynamo(Const.TileMetadata.TableName));
3 changes: 2 additions & 1 deletion packages/shared/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// AWS needs to be exported first to make sure the AWS is configured before anything tries to use it
export { Aws, Config } from './aws/index';
export { Aws } from './aws/index';
export { Config } from '@basemaps/config';
// --
export { Const, Env } from './const';
export { ApiKeyTable, ApiKeyTableRecord } from './aws/api.key.table';
Expand Down

0 comments on commit e548ae5

Please sign in to comment.