Skip to content

Commit cf33f63

Browse files
author
Chase Coalwell
committed
feat: migrate and apply middleware
1 parent 8edfde6 commit cf33f63

File tree

5 files changed

+186
-93
lines changed

5 files changed

+186
-93
lines changed

codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddBuiltinPlugins.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ public class AddBuiltinPlugins implements TypeScriptIntegration {
4949
"PutBucketReplication"
5050
);
5151

52+
private static final Set<String> NON_BUCKET_ENDPOINT_OPERATIONS = SetUtils.of(
53+
"CreateBucket",
54+
"DeleteBucket",
55+
"ListBuckets"
56+
);
57+
5258
@Override
5359
public List<RuntimeClientPlugin> getClientPlugins() {
5460
// Note that order is significant because configurations might
@@ -104,6 +110,12 @@ public List<RuntimeClientPlugin> getClientPlugins() {
104110
.servicePredicate((m, s) -> testServiceId(s, "S3"))
105111
.operationPredicate((m, s, o) -> o.getId().getName().equals("CreateBucket"))
106112
.build(),
113+
RuntimeClientPlugin.builder()
114+
.withConventions(AwsDependency.BUCKET_ENDPOINT_MIDDLEWARE.dependency, "BucketEndpoint",
115+
HAS_MIDDLEWARE)
116+
.servicePredicate((m, s) -> testServiceId(s, "S3"))
117+
.operationPredicate((m, s, o) -> !NON_BUCKET_ENDPOINT_OPERATIONS.contains(o.getId().getName()))
118+
.build(),
107119
RuntimeClientPlugin.builder()
108120
.withConventions(AwsDependency.BODY_CHECKSUM.dependency, "ApplyMd5BodyChecksum",
109121
HAS_MIDDLEWARE)

codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AwsDependency.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public enum AwsDependency implements SymbolDependencyContainer {
4040
MD5_BROWSER(NORMAL_DEPENDENCY, "@aws-sdk/md5-js", "^0.1.0-preview.8"),
4141
STREAM_HASHER_NODE(NORMAL_DEPENDENCY, "@aws-sdk/hash-stream-node", "^0.1.0-preview.4"),
4242
STREAM_HASHER_BROWSER(NORMAL_DEPENDENCY, "@aws-sdk/hash-blob-browser", "^0.1.0-preview.4"),
43+
BUCKET_ENDPOINT_MIDDLEWARE(NORMAL_DEPENDENCY, "@aws-sdk/middleware-bucket-endpoint", "^0.1.0-preview.5"),
4344
BODY_CHECKSUM(NORMAL_DEPENDENCY, "@aws-sdk/middleware-apply-body-checksum", "^0.1.0-preview.5");
4445

4546
public final String packageName;

packages/middleware-bucket-endpoint/src/bucketEndpointMiddleware.spec.ts

Lines changed: 81 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import {
2-
BucketEndpointAwareInput,
3-
bucketEndpointMiddleware
4-
} from "./bucketEndpointMiddleware";
5-
import { HttpRequest } from "@aws-sdk/types";
1+
import { bucketEndpointMiddleware } from "./bucketEndpointMiddleware";
2+
import { HttpRequest } from "@aws-sdk/protocol-http";
3+
import { resolveBucketEndpointConfig } from "./configurations";
64

75
describe("bucketEndpointMiddleware", () => {
8-
const input: BucketEndpointAwareInput = { Bucket: "bucket" };
9-
const request: HttpRequest<never> = {
6+
const input = { Bucket: "bucket" };
7+
const requestInput = {
108
method: "GET",
119
headers: {},
1210
protocol: "https:",
@@ -20,7 +18,11 @@ describe("bucketEndpointMiddleware", () => {
2018
});
2119

2220
it("should convert the request provided into one directed to a virtual hosted-style endpoint", async () => {
23-
const handler = bucketEndpointMiddleware()(next, {} as any);
21+
const request = new HttpRequest(requestInput);
22+
const handler = bucketEndpointMiddleware(resolveBucketEndpointConfig({}))(
23+
next,
24+
{} as any
25+
);
2426
await handler({ input, request });
2527

2628
const {
@@ -34,9 +36,12 @@ describe("bucketEndpointMiddleware", () => {
3436
});
3537

3638
it("should not convert the request provided into one directed to a virtual hosted-style endpoint if so configured", async () => {
37-
const handler = bucketEndpointMiddleware({
38-
forcePathStyle: true
39-
})(next, {} as any);
39+
const request = new HttpRequest(requestInput);
40+
const handler = bucketEndpointMiddleware(
41+
resolveBucketEndpointConfig({
42+
forcePathStyle: true
43+
})
44+
)(next, {} as any);
4045
await handler({ input, request });
4146

4247
const {
@@ -50,7 +55,11 @@ describe("bucketEndpointMiddleware", () => {
5055
});
5156

5257
it("should not convert the request provided into one directed to a virtual hosted-style endpoint if so directed on the input", async () => {
53-
const handler = bucketEndpointMiddleware()(next, {} as any);
58+
const request = new HttpRequest(requestInput);
59+
const handler = bucketEndpointMiddleware(resolveBucketEndpointConfig({}))(
60+
next,
61+
{} as any
62+
);
5463
await handler({ input: { ...input, $forcePathStyle: true }, request });
5564

5665
const {
@@ -62,9 +71,12 @@ describe("bucketEndpointMiddleware", () => {
6271
});
6372

6473
it("should convert the request provided into one directed to a virtual hosted-style endpoint if path-style is disabled on the input", async () => {
65-
const handler = bucketEndpointMiddleware({
66-
forcePathStyle: true
67-
})(next, {} as any);
74+
const request = new HttpRequest(requestInput);
75+
const handler = bucketEndpointMiddleware(
76+
resolveBucketEndpointConfig({
77+
forcePathStyle: true
78+
})
79+
)(next, {} as any);
6880
await handler({ input: { ...input, $forcePathStyle: false }, request });
6981

7082
const {
@@ -76,9 +88,12 @@ describe("bucketEndpointMiddleware", () => {
7688
});
7789

7890
it("should not convert the request provided into one without the bucket in the path if so configured", async () => {
79-
const handler = bucketEndpointMiddleware({
80-
preformedBucketEndpoint: true
81-
})(next, {} as any);
91+
const request = new HttpRequest(requestInput);
92+
const handler = bucketEndpointMiddleware(
93+
resolveBucketEndpointConfig({
94+
preformedBucketEndpoint: true
95+
})
96+
)(next, {} as any);
8297
await handler({
8398
input,
8499
request: { ...request, hostname: "example.com" }
@@ -94,8 +109,12 @@ describe("bucketEndpointMiddleware", () => {
94109
expect(path).toBe("/");
95110
});
96111

97-
it("should use the bucket name as a virtual hosted-style endpoint if so configured on the input", async () => {
98-
const handler = bucketEndpointMiddleware()(next, {} as any);
112+
it("should use the bucket name as a virtual hosted-style endpoint if so configured", async () => {
113+
const request = new HttpRequest(requestInput);
114+
const handler = bucketEndpointMiddleware(resolveBucketEndpointConfig({}))(
115+
next,
116+
{} as any
117+
);
99118
await handler({
100119
input: { Bucket: "files.domain.com", $bucketEndpoint: true },
101120
request: { ...request, path: "/files.domain.com/path/to/key.ext" }
@@ -110,9 +129,12 @@ describe("bucketEndpointMiddleware", () => {
110129
});
111130

112131
it("should use a transfer acceleration endpoint if so configured", async () => {
113-
const handler = bucketEndpointMiddleware({
114-
useAccelerateEndpoint: true
115-
})(next, {} as any);
132+
const request = new HttpRequest(requestInput);
133+
const handler = bucketEndpointMiddleware(
134+
resolveBucketEndpointConfig({
135+
useAccelerateEndpoint: true
136+
})
137+
)(next, {} as any);
116138
await handler({ input, request });
117139

118140
const {
@@ -126,7 +148,11 @@ describe("bucketEndpointMiddleware", () => {
126148
});
127149

128150
it("should use a transfer acceleration endpoint if so directed on the input", async () => {
129-
const handler = bucketEndpointMiddleware()(next, {} as any);
151+
const request = new HttpRequest(requestInput);
152+
const handler = bucketEndpointMiddleware(resolveBucketEndpointConfig({}))(
153+
next,
154+
{} as any
155+
);
130156
await handler({
131157
input: { ...input, $useAccelerateEndpoint: true },
132158
request
@@ -141,9 +167,12 @@ describe("bucketEndpointMiddleware", () => {
141167
});
142168

143169
it("should not use a transfer acceleration endpoint if disabled on the input", async () => {
144-
const handler = bucketEndpointMiddleware({
145-
useAccelerateEndpoint: true
146-
})(next, {} as any);
170+
const request = new HttpRequest(requestInput);
171+
const handler = bucketEndpointMiddleware(
172+
resolveBucketEndpointConfig({
173+
useAccelerateEndpoint: true
174+
})
175+
)(next, {} as any);
147176
await handler({
148177
input: { ...input, $useAccelerateEndpoint: false },
149178
request
@@ -158,9 +187,12 @@ describe("bucketEndpointMiddleware", () => {
158187
});
159188

160189
it("should use a dualstack endpoint if so configured", async () => {
161-
const handler = bucketEndpointMiddleware({
162-
useDualstackEndpoint: true
163-
})(next, {} as any);
190+
const request = new HttpRequest(requestInput);
191+
const handler = bucketEndpointMiddleware(
192+
resolveBucketEndpointConfig({
193+
useDualstackEndpoint: true
194+
})
195+
)(next, {} as any);
164196
await handler({ input, request });
165197

166198
const {
@@ -174,7 +206,11 @@ describe("bucketEndpointMiddleware", () => {
174206
});
175207

176208
it("should use a dualstack endpoint if so directed on the input", async () => {
177-
const handler = bucketEndpointMiddleware()(next, {} as any);
209+
const request = new HttpRequest(requestInput);
210+
const handler = bucketEndpointMiddleware(resolveBucketEndpointConfig({}))(
211+
next,
212+
{} as any
213+
);
178214
await handler({
179215
input: { ...input, $useDualstackEndpoint: true },
180216
request
@@ -189,9 +225,12 @@ describe("bucketEndpointMiddleware", () => {
189225
});
190226

191227
it("should not use a dualstack endpoint if disabled on the input", async () => {
192-
const handler = bucketEndpointMiddleware({
193-
useDualstackEndpoint: true
194-
})(next, {} as any);
228+
const request = new HttpRequest(requestInput);
229+
const handler = bucketEndpointMiddleware(
230+
resolveBucketEndpointConfig({
231+
useDualstackEndpoint: true
232+
})
233+
)(next, {} as any);
195234
await handler({
196235
input: { ...input, $useDualstackEndpoint: false },
197236
request
@@ -205,11 +244,14 @@ describe("bucketEndpointMiddleware", () => {
205244
expect(path).toBe("/");
206245
});
207246

208-
it("should use an accelerate dualstack endpoint if so directed on the input", async () => {
209-
const handler = bucketEndpointMiddleware({
210-
useAccelerateEndpoint: true,
211-
useDualstackEndpoint: true
212-
})(next, {} as any);
247+
it("should use an accelerate dualstack endpoint if configured", async () => {
248+
const request = new HttpRequest(requestInput);
249+
const handler = bucketEndpointMiddleware(
250+
resolveBucketEndpointConfig({
251+
useAccelerateEndpoint: true,
252+
useDualstackEndpoint: true
253+
})
254+
)(next, {} as any);
213255
await handler({ input, request });
214256

215257
const {
Lines changed: 57 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,76 @@
11
import { bucketHostname } from "./bucketHostname";
2+
import { BucketEndpointResolvedConfig } from "./configurations";
23
import {
34
BuildHandler,
45
BuildHandlerArguments,
6+
BuildHandlerOptions,
7+
BuildHandlerOutput,
58
BuildMiddleware,
6-
MetadataBearer
9+
MetadataBearer,
10+
Pluggable
711
} from "@aws-sdk/types";
12+
import { HttpRequest } from "@aws-sdk/protocol-http";
813

9-
export interface BucketEndpointAwareInput {
10-
Bucket: string;
11-
$bucketEndpoint?: boolean;
12-
$forcePathStyle?: boolean;
13-
$useAccelerateEndpoint?: boolean;
14-
$useDualstackEndpoint?: boolean;
15-
}
16-
17-
export interface bucketEndpointMiddlewareConfiguration {
18-
forcePathStyle?: boolean;
19-
preformedBucketEndpoint?: boolean;
20-
useAccelerateEndpoint?: boolean;
21-
useDualstackEndpoint?: boolean;
22-
}
23-
24-
export function bucketEndpointMiddleware({
25-
forcePathStyle = false,
26-
preformedBucketEndpoint = false,
27-
useAccelerateEndpoint = false,
28-
useDualstackEndpoint = false
29-
}: bucketEndpointMiddlewareConfiguration = {}): BuildMiddleware<any, any, any> {
30-
return <
31-
Input extends BucketEndpointAwareInput,
32-
Output extends MetadataBearer
33-
>(
34-
next: BuildHandler<Input, Output, any>
35-
): BuildHandler<Input, Output, any> => async (
36-
args: BuildHandlerArguments<Input, any>
37-
): Promise<Output> => {
14+
export function bucketEndpointMiddleware(
15+
options: BucketEndpointResolvedConfig
16+
): BuildMiddleware<any, any> {
17+
return <Output extends MetadataBearer>(
18+
next: BuildHandler<any, Output>
19+
): BuildHandler<any, Output> => async (
20+
args: BuildHandlerArguments<any>
21+
): Promise<BuildHandlerOutput<Output>> => {
3822
const {
3923
Bucket: bucketName,
4024
$bucketEndpoint,
41-
$forcePathStyle = forcePathStyle,
42-
$useAccelerateEndpoint = useAccelerateEndpoint,
43-
$useDualstackEndpoint = useDualstackEndpoint
25+
$forcePathStyle = options.forcePathStyle,
26+
$useAccelerateEndpoint = options.useAccelerateEndpoint,
27+
$useDualstackEndpoint = options.useDualstackEndpoint
4428
} = args.input;
45-
let replaceBucketInPath = preformedBucketEndpoint || $bucketEndpoint;
46-
const request = { ...args.request };
47-
48-
if ($bucketEndpoint) {
49-
request.hostname = bucketName;
50-
} else if (!preformedBucketEndpoint) {
51-
const { hostname, bucketEndpoint } = bucketHostname({
52-
bucketName,
53-
baseHostname: request.hostname,
54-
accelerateEndpoint: $useAccelerateEndpoint,
55-
dualstackEndpoint: $useDualstackEndpoint,
56-
pathStyleEndpoint: $forcePathStyle,
57-
sslCompatible: request.protocol === "https:"
58-
});
29+
let replaceBucketInPath =
30+
options.preformedBucketEndpoint || $bucketEndpoint;
31+
let request = args.request;
32+
if (HttpRequest.isInstance(request)) {
33+
if ($bucketEndpoint) {
34+
request.hostname = bucketName;
35+
} else if (!options.preformedBucketEndpoint) {
36+
const { hostname, bucketEndpoint } = bucketHostname({
37+
bucketName,
38+
baseHostname: request.hostname,
39+
accelerateEndpoint: $useAccelerateEndpoint,
40+
dualstackEndpoint: $useDualstackEndpoint,
41+
pathStyleEndpoint: $forcePathStyle,
42+
sslCompatible: request.protocol === "https:"
43+
});
5944

60-
request.hostname = hostname;
61-
replaceBucketInPath = bucketEndpoint;
62-
}
45+
request.hostname = hostname;
46+
replaceBucketInPath = bucketEndpoint;
47+
}
6348

64-
if (replaceBucketInPath) {
65-
request.path = request.path.replace(/^(\/)?[^\/]+/, "");
66-
if (request.path === "") {
67-
request.path = "/";
49+
if (replaceBucketInPath) {
50+
request.path = request.path.replace(/^(\/)?[^\/]+/, "");
51+
if (request.path === "") {
52+
request.path = "/";
53+
}
6854
}
6955
}
7056

7157
return next({ ...args, request });
7258
};
7359
}
60+
61+
export const bucketEndpointMiddlewareOptions: BuildHandlerOptions = {
62+
step: "build",
63+
tags: ["BUCKET_ENDPOINT"],
64+
name: "bucketEndpointMiddleware"
65+
};
66+
67+
export const getBucketEndpointPlugin = (
68+
options: BucketEndpointResolvedConfig
69+
): Pluggable<any, any> => ({
70+
applyToStack: clientStack => {
71+
clientStack.add(
72+
bucketEndpointMiddleware(options),
73+
bucketEndpointMiddlewareOptions
74+
);
75+
}
76+
});

0 commit comments

Comments
 (0)