Skip to content

Commit

Permalink
fix(endpoints): resolve service-specific endpoint once per client (#1382
Browse files Browse the repository at this point in the history
)
  • Loading branch information
kuhe committed Sep 3, 2024
1 parent a2bb933 commit c8c53ae
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/hot-items-sing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@smithy/middleware-endpoint": patch
---

resolve service-specific endpoint once per client
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ import { loadConfig } from "@smithy/node-config-provider";

import { getEndpointUrlConfig } from "./getEndpointUrlConfig";

export const getEndpointFromConfig = async (serviceId: string) => loadConfig(getEndpointUrlConfig(serviceId))();
/**
* @internal
*/
export const getEndpointFromConfig = async (serviceId?: string) => loadConfig(getEndpointUrlConfig(serviceId ?? ""))();
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,19 @@ export const getEndpointFromInstructions = async <
context?: HandlerExecutionContext
): Promise<EndpointV2> => {
if (!clientConfig.endpoint) {
const endpointFromConfig = await getEndpointFromConfig(clientConfig.serviceId || "");
let endpointFromConfig: string | undefined;

// This field is guaranteed by the type indicated by the config resolver, but is new
// and some existing standalone calls to this function may not provide the function, so
// this check should remain here.
if (clientConfig.serviceConfiguredEndpoint) {
endpointFromConfig = await clientConfig.serviceConfiguredEndpoint();
} else {
endpointFromConfig = await getEndpointFromConfig(clientConfig.serviceId);
}

if (endpointFromConfig) {
clientConfig.endpoint = () => Promise.resolve(toEndpointV1(endpointFromConfig));
clientConfig.endpoint = () => Promise.resolve(toEndpointV1(endpointFromConfig!));
}
}

Expand Down
26 changes: 25 additions & 1 deletion packages/middleware-endpoint/src/resolveEndpointConfig.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Endpoint, EndpointParameters, EndpointV2, Logger, Provider, UrlParser } from "@smithy/types";
import { normalizeProvider } from "@smithy/util-middleware";

import { getEndpointFromConfig } from "./adaptors/getEndpointFromConfig";
import { toEndpointV1 } from "./adaptors/toEndpointV1";

/**
Expand Down Expand Up @@ -42,13 +43,20 @@ export interface EndpointInputConfig<T extends EndpointParameters = EndpointPara
* Enables FIPS compatible endpoints.
*/
useFipsEndpoint?: boolean | Provider<boolean>;

/**
* @internal
* This field is used internally so you should not fill any value to this field.
*/
serviceConfiguredEndpoint?: never;
}

interface PreviouslyResolved<T extends EndpointParameters = EndpointParameters> {
urlParser: UrlParser;
region: Provider<string>;
endpointProvider: (params: T, context?: { logger?: Logger }) => EndpointV2;
logger?: Logger;
serviceId?: string;
}

/**
Expand Down Expand Up @@ -95,6 +103,12 @@ export interface EndpointResolvedConfig<T extends EndpointParameters = EndpointP
* @internal
*/
serviceId?: string;

/**
* A configured endpoint global or specific to the service from ENV or AWS SDK configuration files.
* @internal
*/
serviceConfiguredEndpoint?: Provider<string | undefined>;
}

/**
Expand All @@ -111,12 +125,22 @@ export const resolveEndpointConfig = <T, P extends EndpointParameters = Endpoint

const isCustomEndpoint = !!endpoint;

return {
const resolvedConfig = {
...input,
endpoint: customEndpointProvider,
tls,
isCustomEndpoint,
useDualstackEndpoint: normalizeProvider(input.useDualstackEndpoint ?? false),
useFipsEndpoint: normalizeProvider(input.useFipsEndpoint ?? false),
} as T & EndpointResolvedConfig<P>;

let configuredEndpointPromise: undefined | Promise<string | undefined> = undefined;
resolvedConfig.serviceConfiguredEndpoint = async () => {
if (input.serviceId && !configuredEndpointPromise) {
configuredEndpointPromise = getEndpointFromConfig(input.serviceId);
}
return configuredEndpointPromise;
};

return resolvedConfig;
};

0 comments on commit c8c53ae

Please sign in to comment.