diff --git a/src/AzureAppConfigurationImpl.ts b/src/AzureAppConfigurationImpl.ts index 746fb959..2e88f461 100644 --- a/src/AzureAppConfigurationImpl.ts +++ b/src/AzureAppConfigurationImpl.ts @@ -7,11 +7,11 @@ import { AzureAppConfiguration, ConfigurationObjectConstructionOptions } from ". import { AzureAppConfigurationOptions } from "./AzureAppConfigurationOptions"; import { IKeyValueAdapter } from "./IKeyValueAdapter"; import { JsonKeyValueAdapter } from "./JsonKeyValueAdapter"; -import { DefaultRefreshIntervalInMs, MinimumRefreshIntervalInMs } from "./RefreshOptions"; +import { DEFAULT_REFRESH_INTERVAL_IN_MS, MIN_REFRESH_INTERVAL_IN_MS } from "./RefreshOptions"; import { Disposable } from "./common/disposable"; import { AzureKeyVaultKeyValueAdapter } from "./keyvault/AzureKeyVaultKeyValueAdapter"; import { RefreshTimer } from "./refresh/RefreshTimer"; -import { CorrelationContextHeaderName } from "./requestTracing/constants"; +import { CORRELATION_CONTEXT_HEADER_NAME } from "./requestTracing/constants"; import { createCorrelationContextHeader, requestTracingEnabled } from "./requestTracing/utils"; import { KeyFilter, LabelFilter, SettingSelector } from "./types"; @@ -33,7 +33,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration { #isInitialLoadCompleted: boolean = false; // Refresh - #refreshInterval: number = DefaultRefreshIntervalInMs; + #refreshInterval: number = DEFAULT_REFRESH_INTERVAL_IN_MS; #onRefreshListeners: Array<() => any> = []; /** * Aka watched settings. @@ -64,8 +64,8 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration { // custom refresh interval if (refreshIntervalInMs !== undefined) { - if (refreshIntervalInMs < MinimumRefreshIntervalInMs) { - throw new Error(`The refresh interval cannot be less than ${MinimumRefreshIntervalInMs} milliseconds.`); + if (refreshIntervalInMs < MIN_REFRESH_INTERVAL_IN_MS) { + throw new Error(`The refresh interval cannot be less than ${MIN_REFRESH_INTERVAL_IN_MS} milliseconds.`); } else { this.#refreshInterval = refreshIntervalInMs; @@ -139,10 +139,11 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration { keyFilter: selector.keyFilter, labelFilter: selector.labelFilter }; + if (this.#requestTracingEnabled) { listOptions.requestOptions = { customHeaders: { - [CorrelationContextHeaderName]: createCorrelationContextHeader(this.#options, this.#isInitialLoadCompleted) + [CORRELATION_CONTEXT_HEADER_NAME]: createCorrelationContextHeader(this.#options, this.#isInitialLoadCompleted) } } } @@ -348,7 +349,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration { if (this.#requestTracingEnabled) { options.requestOptions = { customHeaders: { - [CorrelationContextHeaderName]: createCorrelationContextHeader(this.#options, this.#isInitialLoadCompleted) + [CORRELATION_CONTEXT_HEADER_NAME]: createCorrelationContextHeader(this.#options, this.#isInitialLoadCompleted) } } } diff --git a/src/RefreshOptions.ts b/src/RefreshOptions.ts index fd17183c..12a7474c 100644 --- a/src/RefreshOptions.ts +++ b/src/RefreshOptions.ts @@ -3,8 +3,8 @@ import { WatchedSetting } from "./WatchedSetting"; -export const DefaultRefreshIntervalInMs = 30 * 1000; -export const MinimumRefreshIntervalInMs = 1 * 1000; +export const DEFAULT_REFRESH_INTERVAL_IN_MS = 30 * 1000; +export const MIN_REFRESH_INTERVAL_IN_MS = 1 * 1000; export interface RefreshOptions { /** diff --git a/src/load.ts b/src/load.ts index b98db7d4..d5559c07 100644 --- a/src/load.ts +++ b/src/load.ts @@ -8,7 +8,7 @@ import { AzureAppConfigurationImpl } from "./AzureAppConfigurationImpl"; import { AzureAppConfigurationOptions, MaxRetries, MaxRetryDelayInMs } from "./AzureAppConfigurationOptions"; import * as RequestTracing from "./requestTracing/constants"; -const MinDelayForUnhandedError: number = 5000; // 5 seconds +const MIN_DELAY_FOR_UNHANDLED_ERROR: number = 5000; // 5 seconds /** * Loads the data from Azure App Configuration service and returns an instance of AzureAppConfiguration. @@ -70,7 +70,7 @@ export async function load( // load() method is called in the application's startup code path. // Unhandled exceptions cause application crash which can result in crash loops as orchestrators attempt to restart the application. // Knowing the intended usage of the provider in startup code path, we mitigate back-to-back crash loops from overloading the server with requests by waiting a minimum time to propagate fatal errors. - const delay = MinDelayForUnhandedError - (Date.now() - startTimestamp); + const delay = MIN_DELAY_FOR_UNHANDLED_ERROR - (Date.now() - startTimestamp); if (delay > 0) { await new Promise((resolve) => setTimeout(resolve, delay)); } @@ -84,7 +84,7 @@ function instanceOfTokenCredential(obj: unknown) { function getClientOptions(options?: AzureAppConfigurationOptions): AppConfigurationClientOptions | undefined { // user-agent - let userAgentPrefix = RequestTracing.UserAgentPrefix; // Default UA for JavaScript Provider + let userAgentPrefix = RequestTracing.USER_AGENT_PREFIX; // Default UA for JavaScript Provider const userAgentOptions = options?.clientOptions?.userAgentOptions; if (userAgentOptions?.userAgentPrefix) { userAgentPrefix = `${userAgentOptions.userAgentPrefix} ${userAgentPrefix}`; // Prepend if UA prefix specified by user diff --git a/src/refresh/RefreshTimer.ts b/src/refresh/RefreshTimer.ts index 3ae824b1..ce485947 100644 --- a/src/refresh/RefreshTimer.ts +++ b/src/refresh/RefreshTimer.ts @@ -16,14 +16,14 @@ * - Because of the jitter, the maximum backoff time is actually `MaximumBackoffInMs` * (1 + `JitterRatio`). */ -const MinimumBackoffInMs = 30 * 1000; // 30s -const MaximumBackoffInMs = 10 * 60 * 1000; // 10min -const MaxSafeExponential = 30; // Used to avoid overflow. bitwise operations in JavaScript are limited to 32 bits. It overflows at 2^31 - 1. -const JitterRatio = 0.25; +const MIN_BACKOFF_IN_MS = 30 * 1000; // 30s +const MAX_BACKOFF_IN_MS = 10 * 60 * 1000; // 10min +const MAX_SAFE_EXPONENTIAL = 30; // Used to avoid overflow. bitwise operations in JavaScript are limited to 32 bits. It overflows at 2^31 - 1. +const JITTER_RATIO = 0.25; export class RefreshTimer { - #minBackoff: number = MinimumBackoffInMs; - #maxBackoff: number = MaximumBackoffInMs; + #minBackoff: number = MIN_BACKOFF_IN_MS; + #maxBackoff: number = MAX_BACKOFF_IN_MS; #failedAttempts: number = 0; #backoffEnd: number; // Timestamp #interval: number; @@ -70,14 +70,14 @@ export class RefreshTimer { } // exponential: minBackoffMs * 2^(failedAttempts-1) - const exponential = Math.min(this.#failedAttempts - 1, MaxSafeExponential); + const exponential = Math.min(this.#failedAttempts - 1, MAX_SAFE_EXPONENTIAL); let calculatedBackoffMs = minBackoffMs * (1 << exponential); if (calculatedBackoffMs > maxBackoffMs) { calculatedBackoffMs = maxBackoffMs; } // jitter: random value between [-1, 1) * jitterRatio * calculatedBackoffMs - const jitter = JitterRatio * (Math.random() * 2 - 1); + const jitter = JITTER_RATIO * (Math.random() * 2 - 1); return calculatedBackoffMs * (1 + jitter); } diff --git a/src/requestTracing/constants.ts b/src/requestTracing/constants.ts index a08e36f4..be33aa5d 100644 --- a/src/requestTracing/constants.ts +++ b/src/requestTracing/constants.ts @@ -1,48 +1,48 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { Version } from "../version"; +import { VERSION } from "../version"; -export const RequestTracingDisabledEnvironmentVariable = "AZURE_APP_CONFIGURATION_TRACING_DISABLED"; +export const ENV_AZURE_APP_CONFIGURATION_TRACING_DISABLED = "AZURE_APP_CONFIGURATION_TRACING_DISABLED"; // User Agent -export const UserAgentPrefix = `javascript-appconfiguration-provider/${Version}`; +export const USER_AGENT_PREFIX = `javascript-appconfiguration-provider/${VERSION}`; // Correlation Context -export const CorrelationContextHeaderName = "Correlation-Context"; +export const CORRELATION_CONTEXT_HEADER_NAME = "Correlation-Context"; // Env -export const NodeJSEnvironmentVariable = "NODE_ENV"; -export const NodeJSDevEnvironmentVariableValue = "development"; -export const EnvironmentKey = "Env"; -export const DevEnvironmentValue = "Dev"; +export const NODEJS_ENV_VAR = "NODE_ENV"; +export const NODEJS_DEV_ENV_VAL = "development"; +export const ENV_KEY = "Env"; +export const DEV_ENV_VAL = "Dev"; // Host Type -export const HostTypeKey = "Host"; +export const HOST_TYPE_KEY = "Host"; export enum HostType { - AzureFunction = "AzureFunction", - AzureWebApp = "AzureWebApp", - ContainerApp = "ContainerApp", - Kubernetes = "Kubernetes", - ServiceFabric = "ServiceFabric", + AZURE_FUNCTION = "AzureFunction", + AZURE_WEB_APP = "AzureWebApp", + CONTAINER_APP = "ContainerApp", + KUBERNETES = "Kubernetes", + SERVICE_FABRIC = "ServiceFabric", // Client-side - Browser = "Web", - WebWorker = "WebWorker" + BROWSER = "Web", + WEB_WORKER = "WebWorker" } // Environment variables to identify Host type. -export const AzureFunctionEnvironmentVariable = "FUNCTIONS_EXTENSION_VERSION"; -export const AzureWebAppEnvironmentVariable = "WEBSITE_SITE_NAME"; -export const ContainerAppEnvironmentVariable = "CONTAINER_APP_NAME"; -export const KubernetesEnvironmentVariable = "KUBERNETES_PORT"; -export const ServiceFabricEnvironmentVariable = "Fabric_NodeName"; // See: https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-environment-variables-reference +export const AZURE_FUNCTION_ENV_VAR = "FUNCTIONS_EXTENSION_VERSION"; +export const AZURE_WEB_APP_ENV_VAR = "WEBSITE_SITE_NAME"; +export const CONTAINER_APP_ENV_VAR = "CONTAINER_APP_NAME"; +export const KUBERNETES_ENV_VAR = "KUBERNETES_PORT"; +export const SERVICE_FABRIC_ENV_VAR = "Fabric_NodeName"; // See: https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-environment-variables-reference // Request Type -export const RequestTypeKey = "RequestType"; +export const REQUEST_TYPE_KEY = "RequestType"; export enum RequestType { - Startup = "Startup", - Watch = "Watch" + STARTUP = "Startup", + WATCH = "Watch" } // Tag names -export const KeyVaultConfiguredTag = "UsesKeyVault"; +export const KEY_VAULT_CONFIGURED_TAG = "UsesKeyVault"; diff --git a/src/requestTracing/utils.ts b/src/requestTracing/utils.ts index 8966a308..e82ffe52 100644 --- a/src/requestTracing/utils.ts +++ b/src/requestTracing/utils.ts @@ -3,21 +3,21 @@ import { AzureAppConfigurationOptions } from "../AzureAppConfigurationOptions"; import { - AzureFunctionEnvironmentVariable, - AzureWebAppEnvironmentVariable, - ContainerAppEnvironmentVariable, - DevEnvironmentValue, - EnvironmentKey, + AZURE_FUNCTION_ENV_VAR, + AZURE_WEB_APP_ENV_VAR, + CONTAINER_APP_ENV_VAR, + DEV_ENV_VAL, + ENV_AZURE_APP_CONFIGURATION_TRACING_DISABLED, + ENV_KEY, + HOST_TYPE_KEY, HostType, - HostTypeKey, - KeyVaultConfiguredTag, - KubernetesEnvironmentVariable, - NodeJSDevEnvironmentVariableValue, - NodeJSEnvironmentVariable, - RequestTracingDisabledEnvironmentVariable, + KEY_VAULT_CONFIGURED_TAG, + KUBERNETES_ENV_VAR, + NODEJS_DEV_ENV_VAL, + NODEJS_ENV_VAR, + REQUEST_TYPE_KEY, RequestType, - RequestTypeKey, - ServiceFabricEnvironmentVariable + SERVICE_FABRIC_ENV_VAR } from "./constants"; // Utils @@ -29,15 +29,15 @@ export function createCorrelationContextHeader(options: AzureAppConfigurationOpt UsersKeyVault */ const keyValues = new Map(); - keyValues.set(RequestTypeKey, isInitialLoadCompleted ? RequestType.Watch : RequestType.Startup); - keyValues.set(HostTypeKey, getHostType()); - keyValues.set(EnvironmentKey, isDevEnvironment() ? DevEnvironmentValue : undefined); + keyValues.set(REQUEST_TYPE_KEY, isInitialLoadCompleted ? RequestType.WATCH : RequestType.STARTUP); + keyValues.set(HOST_TYPE_KEY, getHostType()); + keyValues.set(ENV_KEY, isDevEnvironment() ? DEV_ENV_VAL : undefined); const tags: string[] = []; if (options?.keyVaultOptions) { const { credential, secretClients, secretResolver } = options.keyVaultOptions; if (credential !== undefined || secretClients?.length || secretResolver !== undefined) { - tags.push(KeyVaultConfiguredTag); + tags.push(KEY_VAULT_CONFIGURED_TAG); } } @@ -55,7 +55,7 @@ export function createCorrelationContextHeader(options: AzureAppConfigurationOpt } export function requestTracingEnabled(): boolean { - const requestTracingDisabledEnv = getEnvironmentVariable(RequestTracingDisabledEnvironmentVariable); + const requestTracingDisabledEnv = getEnvironmentVariable(ENV_AZURE_APP_CONFIGURATION_TRACING_DISABLED); const disabled = requestTracingDisabledEnv?.toLowerCase() === "true"; return !disabled; } @@ -71,27 +71,27 @@ function getEnvironmentVariable(name: string) { function getHostType(): string | undefined { let hostType: string | undefined; - if (getEnvironmentVariable(AzureFunctionEnvironmentVariable)) { - hostType = HostType.AzureFunction; - } else if (getEnvironmentVariable(AzureWebAppEnvironmentVariable)) { - hostType = HostType.AzureWebApp; - } else if (getEnvironmentVariable(ContainerAppEnvironmentVariable)) { - hostType = HostType.ContainerApp; - } else if (getEnvironmentVariable(KubernetesEnvironmentVariable)) { - hostType = HostType.Kubernetes; - } else if (getEnvironmentVariable(ServiceFabricEnvironmentVariable)) { - hostType = HostType.ServiceFabric; + if (getEnvironmentVariable(AZURE_FUNCTION_ENV_VAR)) { + hostType = HostType.AZURE_FUNCTION; + } else if (getEnvironmentVariable(AZURE_WEB_APP_ENV_VAR)) { + hostType = HostType.AZURE_WEB_APP; + } else if (getEnvironmentVariable(CONTAINER_APP_ENV_VAR)) { + hostType = HostType.CONTAINER_APP; + } else if (getEnvironmentVariable(KUBERNETES_ENV_VAR)) { + hostType = HostType.KUBERNETES; + } else if (getEnvironmentVariable(SERVICE_FABRIC_ENV_VAR)) { + hostType = HostType.SERVICE_FABRIC; } else if (isBrowser()) { - hostType = HostType.Browser; + hostType = HostType.BROWSER; } else if (isWebWorker()) { - hostType = HostType.WebWorker; + hostType = HostType.WEB_WORKER; } return hostType; } function isDevEnvironment(): boolean { - const envType = getEnvironmentVariable(NodeJSEnvironmentVariable); - if (NodeJSDevEnvironmentVariableValue === envType?.toLowerCase()) { + const envType = getEnvironmentVariable(NODEJS_ENV_VAR); + if (NODEJS_DEV_ENV_VAL === envType?.toLowerCase()) { return true; } return false; diff --git a/src/version.ts b/src/version.ts index 6da52662..694d8ff9 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,4 +1,4 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -export const Version = "1.0.0-preview"; \ No newline at end of file +export const VERSION = "1.0.0-preview"; \ No newline at end of file