Skip to content

Commit 7fbf9d0

Browse files
committed
feat: parse derializing utils as parameters
* use config interface as middleware parameter * use smithy command as super class of all commands so we can support use() in commands
1 parent 5cae1e2 commit 7fbf9d0

File tree

17 files changed

+265
-248
lines changed

17 files changed

+265
-248
lines changed

clients/node/client-rds-data-node/RDSDataClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export class RDSDataClient extends SmithyClient<HttpOptions, InputTypesUnion, Ou
3838
let intermediaConfig_3 = EndpointsConfig.resolve(intermediaConfig_2);
3939
let intermediaConfig_4 = RetryConfig.resolve(intermediaConfig_3);
4040
this.config = intermediaConfig_4;
41-
super.use(contentLengthPlugin(this.config.bodyLengthChecker));
41+
super.use(contentLengthPlugin(this.config));
4242
if (this.config.maxRetries > 0) {
4343
this.middlewareStack.add(
4444
__aws_sdk_retry_middleware.retryMiddleware(

clients/node/client-rds-data-node/RDSDataConfiguration.ts

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,29 @@ import { NodeHttpHandler } from "@aws-sdk/node-http-handler";
44
import { defaultProvider as regionDefaultProvider } from "@aws-sdk/region-provider";
55
import { parseUrl } from "@aws-sdk/url-parser-node";
66
import { calculateBodyLength } from "@aws-sdk/util-body-length-node";
7-
import { Protocol, HashConstructor, StreamCollector, Provider, Credentials, UrlParser } from "@aws-sdk/types";
8-
import { HttpRequest, HttpResponse, HttpHandler } from "@aws-sdk/protocol-http";
97
import { streamCollector } from '@aws-sdk/stream-collector-node';
108
import { RestJsonProtocol } from "@aws-sdk/protocol-rest-json";
11-
import { AwsAuthConfiguration, RegionConfiguration, RetryConfig, EndpointsConfig, ProtocolConfig } from '@aws-sdk/config-resolver';
12-
13-
export interface AWSClientRuntimeConfiguration {
14-
httpHandler?: HttpHandler;
15-
protocolDefaultProvider?: (handler: HttpHandler) => Protocol<HttpRequest, HttpResponse>
16-
signingName?: string;
17-
service?: string;
18-
sha256?: HashConstructor;
19-
credentialDefaultProvider?: (input: any) => Provider<Credentials>;
20-
regionDefaultProvider?: (input: any) => Provider<string>;
21-
urlParser?: UrlParser,
22-
bodyLengthChecker?: (body: any) => number | undefined;
23-
streamCollector?: StreamCollector<any>
24-
}
9+
import { fromUtf8, toUtf8 } from '@aws-sdk/util-utf8-node';
10+
import { fromBase64, toBase64 } from '@aws-sdk/util-base64-node';
11+
import { AwsAuthConfiguration, RegionConfiguration, RetryConfig, EndpointsConfig, ProtocolConfig, AWSClientRuntimeConfiguration } from '@aws-sdk/config-resolver';
2512

2613
export type AWSClientRuntimeResolvedConfiguration = Required<AWSClientRuntimeConfiguration>;
2714

2815
export const RDSRuntimeConfiguration: AWSClientRuntimeResolvedConfiguration = {
29-
httpHandler: new NodeHttpHandler(),
3016
protocolDefaultProvider: (handler) => new RestJsonProtocol(handler),
3117
signingName: "rds-data",
3218
service: "rds-data",
19+
httpHandler: new NodeHttpHandler(),
3320
sha256: Hash.bind(null, "sha256"),
3421
credentialDefaultProvider,
3522
regionDefaultProvider,
3623
urlParser: parseUrl,
3724
bodyLengthChecker: calculateBodyLength,
38-
streamCollector
25+
streamCollector,
26+
base64Decoder: fromBase64,
27+
base64Encoder: toBase64,
28+
utf8Decoder: fromUtf8,
29+
utf8Encoder: toUtf8
3930
}
4031

4132
export type RDSDataConfiguration = AWSClientRuntimeConfiguration &

clients/node/client-rds-data-node/commands/ExecuteStatementCommand.ts

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import * as __aws_sdk_middleware_stack from "@aws-sdk/middleware-stack";
2-
import { serializerMiddleware } from "@aws-sdk/middleware-serializer";
1+
import { Command } from '@aws-sdk/smithy-client';
2+
import { serializerPlugin } from "@aws-sdk/middleware-serializer";
33
import { deserializerMiddleware } from "@aws-sdk/middleware-deserializer";
44
import * as __aws_sdk_types from "@aws-sdk/types";
55
import { RDSDataResolvedConfiguration } from "../RDSDataConfiguration";
66
import { HttpRequest } from '@aws-sdk/protocol-http';
77
import { executeStatementSerializer, executeStatementDeserializer } from '../protocol/ExecuteStatement'
8-
import { FinalizeHandlerArguments } from '@aws-sdk/types';
8+
import { FinalizeHandlerArguments, MiddlewareStack } from '@aws-sdk/types';
99

1010
/**
1111
* To remove this when move to Smithy model
@@ -15,16 +15,14 @@ type ExecuteStatementOutput = any;
1515
type InputTypesUnion = any;
1616
type OutputTypesUnion = any;
1717

18-
export class ExecuteStatementCommand {
19-
readonly middlewareStack = new __aws_sdk_middleware_stack.MiddlewareStack<
20-
ExecuteStatementInput,
21-
ExecuteStatementOutput
22-
>();
18+
export class ExecuteStatementCommand extends Command<ExecuteStatementInput, ExecuteStatementOutput> {
2319

24-
constructor(readonly input: ExecuteStatementInput) {}
20+
constructor(readonly input: ExecuteStatementInput) {
21+
super();
22+
}
2523

2624
resolveMiddleware(
27-
clientStack: __aws_sdk_middleware_stack.MiddlewareStack<
25+
clientStack: MiddlewareStack<
2826
InputTypesUnion,
2927
OutputTypesUnion
3028
>,
@@ -33,17 +31,7 @@ export class ExecuteStatementCommand {
3331
): __aws_sdk_types.Handler<ExecuteStatementInput, ExecuteStatementOutput> {
3432
const { httpHandler } = configuration;
3533

36-
this.middlewareStack.add(
37-
serializerMiddleware(
38-
configuration.protocol,
39-
executeStatementSerializer
40-
),
41-
{
42-
step: "serialize",
43-
priority: 90,
44-
tags: { SERIALIZER: true }
45-
}
46-
);
34+
this.use(serializerPlugin(configuration, executeStatementSerializer));
4735
this.middlewareStack.add(
4836
deserializerMiddleware<ExecuteStatementInput, ExecuteStatementOutput>(
4937
configuration.protocol,
@@ -63,7 +51,7 @@ export class ExecuteStatementCommand {
6351
};
6452

6553
return stack.resolve(
66-
(request: FinalizeHandlerArguments<any>) => {return httpHandler.handle(request.request as HttpRequest, options || {})},
54+
(request: FinalizeHandlerArguments<any>) => { return httpHandler.handle(request.request as HttpRequest, options || {}) },
6755
handlerExecutionContext
6856
);
6957
}

packages/config-resolver/src/components.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import {
77
DelayDecider,
88
UrlParser,
99
Protocol,
10-
HttpOptions
10+
HttpOptions,
11+
StreamCollector,
12+
Decoder,
13+
Encoder
1114
} from "@aws-sdk/types";
1215
import { SignatureV4 } from "@aws-sdk/signature-v4";
1316
import {
@@ -17,6 +20,28 @@ import {
1720
HttpResponse
1821
} from "@aws-sdk/protocol-http";
1922

23+
export interface RuntimeDependencies {
24+
httpHandler?: HttpHandler;
25+
sha256?: HashConstructor;
26+
credentialDefaultProvider?: (input: any) => Provider<Credentials>;
27+
regionDefaultProvider?: (input: any) => Provider<string>;
28+
urlParser?: UrlParser;
29+
bodyLengthChecker?: (body: any) => number | undefined;
30+
streamCollector?: StreamCollector<any>;
31+
base64Decoder?: Decoder;
32+
base64Encoder?: Encoder;
33+
utf8Decoder?: Decoder;
34+
utf8Encoder?: Encoder;
35+
}
36+
37+
export interface AWSClientRuntimeConfiguration extends RuntimeDependencies {
38+
protocolDefaultProvider?: (
39+
handler: HttpHandler
40+
) => Protocol<HttpRequest, HttpResponse>;
41+
signingName?: string;
42+
service?: string;
43+
}
44+
2045
export function normalizeProvider<T>(input: T | Provider<T>): Provider<T> {
2146
if (typeof input === "object") {
2247
const promisified = Promise.resolve(input);

packages/middleware-content-length/src/index.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
import { HttpRequest } from "@aws-sdk/protocol-http";
1111

1212
export function contentLengthMiddleware(
13-
bodyLengthCalculator: BodyLengthCalculator
13+
bodyLengthChecker: BodyLengthCalculator
1414
): BuildMiddleware<any, any> {
1515
return <Output extends MetadataBearer>(
1616
next: BuildHandler<any, Output>
@@ -27,7 +27,7 @@ export function contentLengthMiddleware(
2727
.map(str => str.toLowerCase())
2828
.indexOf("content-length") === -1
2929
) {
30-
const length = bodyLengthCalculator(body);
30+
const length = bodyLengthChecker(body);
3131
if (length !== undefined) {
3232
request.headers = {
3333
...request.headers,
@@ -44,11 +44,11 @@ export function contentLengthMiddleware(
4444
};
4545
}
4646

47-
export function contentLengthPlugin(
48-
bodyLengthCalculator: BodyLengthCalculator
49-
): InjectableMiddleware {
47+
export function contentLengthPlugin(options: {
48+
bodyLengthChecker: BodyLengthCalculator;
49+
}): InjectableMiddleware {
5050
return {
51-
middleware: contentLengthMiddleware(bodyLengthCalculator),
51+
middleware: contentLengthMiddleware(options.bodyLengthChecker),
5252
step: "build",
5353
tags: { SET_CONTENT_LENGTH: true }
5454
};

packages/middleware-serializer/src/index.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,42 @@ import {
44
SerializeHandlerArguments,
55
SerializeMiddleware,
66
SerializeHandlerOutput,
7-
Protocol
7+
Protocol,
8+
SerializerConfig,
9+
InjectableMiddleware
810
} from "@aws-sdk/types";
911

1012
export function serializerMiddleware<
1113
Input extends object,
1214
Output extends object
1315
>(
14-
protocol: Protocol<any, any>,
16+
options: SerializerMiddlewareConfig,
1517
serializer: RequestSerializer<any>
1618
): SerializeMiddleware<Input, Output> {
1719
return (
1820
next: SerializeHandler<Input, Output>
1921
): SerializeHandler<Input, Output> => async (
2022
args: SerializeHandlerArguments<Input>
2123
): Promise<SerializeHandlerOutput<Output>> => {
22-
const request = protocol.serialize(serializer, args.input);
24+
const request = options.protocol.serialize(serializer, args.input, options);
2325
return next({
2426
...args,
2527
request
2628
});
2729
};
2830
}
31+
32+
export interface SerializerMiddlewareConfig extends SerializerConfig {
33+
protocol: Protocol<any, any>;
34+
}
35+
36+
export function serializerPlugin(
37+
config: SerializerMiddlewareConfig,
38+
serializer: RequestSerializer<any>
39+
): InjectableMiddleware {
40+
return {
41+
middleware: serializerMiddleware(config, serializer),
42+
step: "serialize",
43+
tags: { SERIALIZER: true }
44+
};
45+
}

packages/smithy-client/src/client.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { MiddlewareStack } from "@aws-sdk/middleware-stack";
2+
import {
3+
Protocol,
4+
Command,
5+
MetadataBearer,
6+
InjectableMiddleware,
7+
HandlerOptions as InjectOptions
8+
} from "@aws-sdk/types";
9+
10+
export interface SmithyConfiguration<HandlerOptions> {
11+
protocol: Protocol<any, any, HandlerOptions>;
12+
}
13+
14+
export type SmithyResolvedConfiguration<HandlerOptions> = SmithyConfiguration<
15+
HandlerOptions
16+
>;
17+
18+
export class SmithyClient<
19+
HandlerOptions = any,
20+
ClientInput extends object = any,
21+
ClientOutput extends MetadataBearer = any
22+
> {
23+
public middlewareStack = new MiddlewareStack<ClientInput, ClientOutput>();
24+
readonly config: SmithyResolvedConfiguration<HandlerOptions>;
25+
constructor(config: SmithyConfiguration<HandlerOptions>) {
26+
this.config = config;
27+
}
28+
use(
29+
injectable: InjectableMiddleware<ClientInput, ClientOutput>,
30+
options: InjectOptions = {}
31+
) {
32+
const { middleware, step, priority, tags } = injectable;
33+
this.middlewareStack.add(
34+
// @ts-ignore
35+
middleware,
36+
{
37+
step: options.step || step,
38+
priority: options.priority || priority,
39+
tags: { ...tags, ...options.tags }
40+
}
41+
);
42+
}
43+
send<InputType extends ClientInput, OutputType extends ClientOutput>(
44+
command: Command<
45+
ClientInput,
46+
InputType,
47+
ClientOutput,
48+
OutputType,
49+
SmithyResolvedConfiguration<HandlerOptions>
50+
>,
51+
options?: HandlerOptions
52+
): Promise<OutputType>;
53+
send<InputType extends ClientInput, OutputType extends ClientOutput>(
54+
command: Command<
55+
ClientInput,
56+
InputType,
57+
ClientOutput,
58+
OutputType,
59+
SmithyResolvedConfiguration<HandlerOptions>
60+
>,
61+
options: HandlerOptions,
62+
cb: (err: any, data?: OutputType) => void
63+
): void;
64+
send<InputType extends ClientInput, OutputType extends ClientOutput>(
65+
command: Command<
66+
ClientInput,
67+
InputType,
68+
ClientOutput,
69+
OutputType,
70+
SmithyResolvedConfiguration<HandlerOptions>
71+
>,
72+
options?: HandlerOptions,
73+
cb?: (err: any, data?: OutputType) => void
74+
): Promise<OutputType> | void {
75+
const handler = command.resolveMiddleware(
76+
this.middlewareStack as any,
77+
this.config,
78+
options
79+
);
80+
if (cb) {
81+
handler(command)
82+
.then(result => cb(null, result.output), (err: any) => cb(err))
83+
.catch(
84+
// prevent any errors thrown in the callback from triggering an
85+
// unhandled promise rejection
86+
() => {}
87+
);
88+
} else {
89+
return handler(command).then(result => result.output);
90+
}
91+
}
92+
}

packages/smithy-client/src/command.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { MiddlewareStack } from "@aws-sdk/middleware-stack";
2+
import {
3+
InjectableMiddleware,
4+
HandlerOptions as InjectOptions
5+
} from "@aws-sdk/types";
6+
7+
export class Command<InputType extends object, OutputType extends object> {
8+
readonly middlewareStack = new MiddlewareStack<InputType, OutputType>();
9+
use(
10+
injectable: InjectableMiddleware<InputType, OutputType>,
11+
options: InjectOptions = {}
12+
) {
13+
const { middleware, step, priority, tags } = injectable;
14+
this.middlewareStack.add(
15+
// @ts-ignore
16+
middleware,
17+
{
18+
step: options.step || step,
19+
priority: options.priority || priority,
20+
tags: { ...tags, ...options.tags }
21+
}
22+
);
23+
}
24+
}

0 commit comments

Comments
 (0)