Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add KEYS_API_URL configuration #240

Merged
merged 2 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions src/common/config/config-loader.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,25 @@ const DEFAULTS = {
RPC_URL: 'some-rpc-url',
RABBITMQ_URL: 'some-rabbit-url',
RABBITMQ_LOGIN: 'some-rabbit-login',
KEYS_API_URL: 'keys-api',
};

const extractError = async <T>(
fn: Promise<T>,
): Promise<[ValidationError[], T]> => {
try {
return [[], await fn];
} catch (error: any) {
return [error as ValidationError[], undefined as unknown as T];
}
};

const toHaveProblemWithRecords = (
recordsKeys: string[],
errors: ValidationError[],
) => {
const errorKeys = errors.map((error) => error.property);
expect(recordsKeys.sort()).toEqual(errorKeys.sort());
};

describe('ConfigLoaderService base spec', () => {
Expand Down Expand Up @@ -106,6 +125,96 @@ describe('ConfigLoaderService base spec', () => {
});
});

describe('kapi url config', () => {
test('all invariants are empty', async () => {
const prepConfig = plainToClass(InMemoryConfiguration, {
RABBITMQ_PASSCODE: 'some-rabbit-passcode',
...DEFAULTS,
KEYS_API_URL: undefined,
});
const [validationErrors] = await extractError(
configLoaderService.loadSecrets(prepConfig),
);

toHaveProblemWithRecords(
['KEYS_API_URL', 'KEYS_API_PORT', 'KEYS_API_HOST'],
validationErrors,
);
});

test('KEYS_API_URL is set and the rest is default', async () => {
const KEYS_API_URL = 'kapi-url';
const KEYS_API_HOST = '';
const KEYS_API_PORT = 0;
const prepConfig = plainToClass(InMemoryConfiguration, {
RABBITMQ_PASSCODE: 'some-rabbit-passcode',
...DEFAULTS,
KEYS_API_URL,
});
const [validationErrors, result] = await extractError(
configLoaderService.loadSecrets(prepConfig),
);
expect(validationErrors).toHaveLength(0);
expect(result.KEYS_API_URL).toBe(KEYS_API_URL);
expect(result.KEYS_API_HOST).toBe(KEYS_API_HOST);
expect(result.KEYS_API_PORT).toBe(KEYS_API_PORT);
});

test('KEYS_API_URL is empty and the rest is set', async () => {
const KEYS_API_URL = undefined;
const KEYS_API_HOST = 'kapi-host';
const KEYS_API_PORT = 2222;
const prepConfig = plainToClass(InMemoryConfiguration, {
RABBITMQ_PASSCODE: 'some-rabbit-passcode',
...DEFAULTS,
KEYS_API_URL,
KEYS_API_HOST,
KEYS_API_PORT,
});
const [validationErrors, result] = await extractError(
configLoaderService.loadSecrets(prepConfig),
);
expect(validationErrors).toHaveLength(0);
expect(result.KEYS_API_URL).toBe(KEYS_API_URL);
expect(result.KEYS_API_HOST).toBe(KEYS_API_HOST);
expect(result.KEYS_API_PORT).toBe(KEYS_API_PORT);
});

test('KEYS_API_URL and KEYS_API_PORT are empty and the KEYS_API_HOST is set', async () => {
const KEYS_API_URL = undefined;
const KEYS_API_HOST = 'kapi-host';
const KEYS_API_PORT = 0;
const prepConfig = plainToClass(InMemoryConfiguration, {
RABBITMQ_PASSCODE: 'some-rabbit-passcode',
...DEFAULTS,
KEYS_API_URL,
KEYS_API_HOST,
KEYS_API_PORT,
});
const [validationErrors] = await extractError(
configLoaderService.loadSecrets(prepConfig),
);
toHaveProblemWithRecords(['KEYS_API_PORT'], validationErrors);
});

test('KEYS_API_URL and KEYS_API_HOST are empty and the KEYS_API_PORT is set', async () => {
const KEYS_API_URL = undefined;
const KEYS_API_HOST = '';
const KEYS_API_PORT = 2222;
const prepConfig = plainToClass(InMemoryConfiguration, {
RABBITMQ_PASSCODE: 'some-rabbit-passcode',
...DEFAULTS,
KEYS_API_URL,
KEYS_API_HOST,
KEYS_API_PORT,
});
const [validationErrors] = await extractError(
configLoaderService.loadSecrets(prepConfig),
);
toHaveProblemWithRecords(['KEYS_API_HOST'], validationErrors);
});
});
Copy link
Contributor

@Amuhar Amuhar Sep 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we also need test 'KEYS_API_URL, KEYS_API_HOST, KEYS_API_PORT are set'


describe('wallet', () => {
let configLoaderService: ConfigLoaderService;
const DEFAULTS_WITH_RABBIT = {
Expand Down
1 change: 1 addition & 0 deletions src/common/config/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface Configuration {
REGISTRY_KEYS_QUERY_CONCURRENCY: number;
KEYS_API_PORT: number;
KEYS_API_HOST: string;
KEYS_API_URL: string;
LOCATOR_DEVNET_ADDRESS: string;
WALLET_MIN_BALANCE: ethers.BigNumber;
WALLET_CRITICAL_BALANCE: ethers.BigNumber;
Expand Down
15 changes: 12 additions & 3 deletions src/common/config/in-memory-configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,24 @@ export class InMemoryConfiguration implements Configuration {
@Transform(({ value }) => parseInt(value, 10), { toClassOnly: true })
REGISTRY_KEYS_QUERY_CONCURRENCY = 5;

@ValidateIf((conf) => !conf.KEYS_API_URL)
@IsNotEmpty()
@IsNumber()
@Min(1)
@Transform(({ value }) => parseInt(value, 10), { toClassOnly: true })
KEYS_API_PORT = 3001;
KEYS_API_PORT = 0;

@IsOptional()
@ValidateIf((conf) => !conf.KEYS_API_URL)
@IsNotEmpty()
@IsString()
KEYS_API_HOST = '';

@ValidateIf((conf) => {
return !conf.KEYS_API_PORT && !conf.KEYS_API_HOST;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so we want to use KEYS_API_URL only if both conf.KEYS_API_PORT and conf.KEYS_API_HOST were not set, right ?

})
@IsNotEmpty()
@IsString()
KEYS_API_HOST = 'http://localhost';
KEYS_API_URL = '';

@IsOptional()
@IsString()
Expand Down
13 changes: 10 additions & 3 deletions src/keys-api/keys-api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ export class KeysApiService {
protected readonly fetchService: FetchService,
) {}

private getBaseUrl() {
const baseUrl =
this.config.KEYS_API_URL ||
`${this.config.KEYS_API_HOST}:${this.config.KEYS_API_PORT}`;
return baseUrl;
}

protected async fetch<Response>(url: string, requestInit?: RequestInit) {
const controller = new AbortController();
const { signal } = controller;
Expand All @@ -24,8 +31,7 @@ export class KeysApiService {
controller.abort();
}, FETCH_REQUEST_TIMEOUT);

const baseUrl = `${this.config.KEYS_API_HOST}:${this.config.KEYS_API_PORT}`;

const baseUrl = this.getBaseUrl();
try {
const res: Response = await this.fetchService.fetchJson(
`${baseUrl}${url}`,
Expand All @@ -34,9 +40,10 @@ export class KeysApiService {
...requestInit,
},
);

clearTimeout(timer);
return res;
} catch (error) {
} catch (error: any) {
clearTimeout(timer);
throw error;
}
Expand Down
Loading