diff --git a/doc/api.md b/doc/api.md index 7ec9147..83c3733 100644 --- a/doc/api.md +++ b/doc/api.md @@ -197,6 +197,8 @@ OpenWhisk credentials can also be read from environment variables `__OW_NAMESPAC | [config] | object | used to init the sdk | | [config.ow] | [OpenWhiskCredentials](#OpenWhiskCredentials) | [OpenWhiskCredentials](#OpenWhiskCredentials). Set those if you want to use ootb credentials to access the state management service. OpenWhisk namespace and auth can also be passed through environment variables: `__OW_NAMESPACE` and `__OW_API_KEY` | | [config.region] | string | optional region to use, accepted values: `amer` (default), `emea`, `apac` | +| [config.logLevel] | string | optional log level for the HttpExponentialBackoff instance | +| [config.logRetryAfterSeconds] | number | Defaults to 10. if the request has to retry because of a 429, it will log the retry attempt as a warning if the Retry-After value is greater than this number. Set to 0 to disable. | diff --git a/lib/AdobeState.js b/lib/AdobeState.js index 01d36ce..fb84710 100644 --- a/lib/AdobeState.js +++ b/lib/AdobeState.js @@ -149,8 +149,10 @@ class AdobeState { * @param {string} apikey the apikey for the Adobe State Store * @param {string} env the Adobe environment (AIO_CLI_ENV) * @param {('amer'|'apac'|'emea')} [region] the region for the Adobe State Store. defaults to 'amer' + * @param {string} [logLevel] the log level for the HttpExponentialBackoff instance + * @param {number} [logRetryAfterSeconds] if the request has to retry because of a 429, it will log the retry attempt as a warning if the Retry-After value is greater than this number. Set to 0 to disable. */ - constructor (namespace, apikey, env, region) { + constructor (namespace, apikey, env, region, logLevel, logRetryAfterSeconds) { /** @private */ this.namespace = namespace /** @private */ @@ -162,7 +164,7 @@ class AdobeState { /** @private */ this.endpoint = this.getRegionalEndpoint(ENDPOINTS[env], region) /** @private */ - this.fetchRetry = new HttpExponentialBackoff() + this.fetchRetry = new HttpExponentialBackoff({ logLevel, logRetryAfterSeconds }) } /** @@ -265,7 +267,14 @@ class AdobeState { })) } - return new AdobeState(credentials.namespace, credentials.apikey, env, credentials.region) + return new AdobeState( + credentials.namespace, + credentials.apikey, + env, + credentials.region, + credentials.logLevel, + credentials.logRetryAfterSeconds + ) } /* **************************** ADOBE STATE STORE OPERATORS ***************************** */ diff --git a/lib/init.js b/lib/init.js index 15de0eb..ddc61ce 100644 --- a/lib/init.js +++ b/lib/init.js @@ -14,6 +14,7 @@ const logger = require('@adobe/aio-lib-core-logging')('@adobe/aio-lib-state', { const utils = require('./utils') const { AdobeState } = require('./AdobeState') +const DEFAULT_LOG_RETRY_AFTER_SECONDS = 10 /* *********************************** typedefs *********************************** */ /** @@ -43,15 +44,24 @@ const { AdobeState } = require('./AdobeState') * namespace and auth can also be passed through environment variables: * `__OW_NAMESPACE` and `__OW_API_KEY` * @param {string} [config.region] optional region to use, accepted values: `amer` (default), `emea`, `apac` + * @param {string} [config.logLevel] optional log level for the HttpExponentialBackoff instance + * @param {number} [config.logRetryAfterSeconds] Defaults to 10. if the request has to retry because of a 429, it will log the retry attempt as a warning if the Retry-After value is greater than this number. Set to 0 to disable. * @returns {Promise} An AdobeState instance */ async function init (config = {}) { const logConfig = utils.withHiddenFields(config, ['ow.auth']) - logger.debug(`init with config: ${JSON.stringify(logConfig, null, 2)}`) const { auth: apikey, namespace } = (config.ow ?? {}) - return AdobeState.init({ apikey, namespace, region: config.region }) + const { region, logLevel, logRetryAfterSeconds = DEFAULT_LOG_RETRY_AFTER_SECONDS } = config + + return AdobeState.init({ + apikey, + namespace, + region, + logLevel, + logRetryAfterSeconds + }) } module.exports = { init } diff --git a/test/init.test.js b/test/init.test.js index 5e53b7b..219b269 100644 --- a/test/init.test.js +++ b/test/init.test.js @@ -10,13 +10,24 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ const stateLib = require('../index') +const { HttpExponentialBackoff } = require('@adobe/aio-lib-core-networking') + +jest.mock('@adobe/aio-lib-core-networking') describe('init', () => { const env = process.env + const mockExponentialBackoff = jest.fn() beforeEach(() => { jest.resetModules() process.env = { ...env } + jest.clearAllMocks() + + HttpExponentialBackoff.mockImplementation((options) => { + return { + exponentialBackoff: mockExponentialBackoff + } + }) }) afterEach(() => { @@ -46,4 +57,44 @@ describe('init', () => { expect(store.namespace).toEqual(process.env.__OW_NAMESPACE) expect(store.apikey).toEqual(process.env.__OW_API_KEY) }) + + test('pass logLevel in config', async () => { + expect.hasAssertions() + const logLevel = 'debug' + const store = await stateLib.init({ ow: fakeOWCreds, logLevel }) + + expect(store.namespace).toEqual(fakeOWCreds.namespace) + expect(store.apikey).toEqual(fakeOWCreds.auth) + expect(HttpExponentialBackoff).toHaveBeenCalledWith({ logLevel, logRetryAfterSeconds: 10 }) + }) + + test('when logLevel is not provided, HttpExponentialBackoff receives undefined', async () => { + expect.hasAssertions() + const store = await stateLib.init({ ow: fakeOWCreds }) + + expect(store.namespace).toEqual(fakeOWCreds.namespace) + expect(store.apikey).toEqual(fakeOWCreds.auth) + expect(HttpExponentialBackoff).toHaveBeenCalledWith({ logLevel: undefined, logRetryAfterSeconds: 10 }) + }) + + test('pass logRetryAfterSeconds in config', async () => { + expect.hasAssertions() + const logRetryAfterSeconds = 20 + const store = await stateLib.init({ ow: fakeOWCreds, logRetryAfterSeconds }) + + expect(store.namespace).toEqual(fakeOWCreds.namespace) + expect(store.apikey).toEqual(fakeOWCreds.auth) + expect(HttpExponentialBackoff).toHaveBeenCalledWith({ logLevel: undefined, logRetryAfterSeconds }) + }) + + test('pass both logLevel and logRetryAfterSeconds in config', async () => { + expect.hasAssertions() + const logLevel = 'debug' + const logRetryAfterSeconds = 30 + const store = await stateLib.init({ ow: fakeOWCreds, logLevel, logRetryAfterSeconds }) + + expect(store.namespace).toEqual(fakeOWCreds.namespace) + expect(store.apikey).toEqual(fakeOWCreds.auth) + expect(HttpExponentialBackoff).toHaveBeenCalledWith({ logLevel, logRetryAfterSeconds }) + }) }) diff --git a/types.d.ts b/types.d.ts index d51483d..cfb2d1b 100644 --- a/types.d.ts +++ b/types.d.ts @@ -166,10 +166,14 @@ export type OpenWhiskCredentials = { * namespace and auth can also be passed through environment variables: * `__OW_NAMESPACE` and `__OW_API_KEY` * @param [config.region] - optional region to use, accepted values: `amer` (default), `emea`, `apac` + * @param [config.logLevel] - optional log level for the HttpExponentialBackoff instance + * @param [config.logRetryAfterSeconds] - Defaults to 10. if the request has to retry because of a 429, it will log the retry attempt as a warning if the Retry-After value is greater than this number. Set to 0 to disable. * @returns An AdobeState instance */ export function init(config?: { ow?: OpenWhiskCredentials; region?: string; + logLevel?: string; + logRetryAfterSeconds?: number; }): Promise;