Skip to content

Commit 5e1e3a7

Browse files
Chase Coalwelltrivikr
Chase Coalwell
authored andcommitted
ssecMiddleware migration (#544)
* feat: rename package * feat: migrate middleware-ssec * feat: apply ssec middleware plugin
1 parent aba5417 commit 5e1e3a7

File tree

17 files changed

+175
-254
lines changed

17 files changed

+175
-254
lines changed

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

+20
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,26 @@
1919
import static software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin.Convention.HAS_MIDDLEWARE;
2020

2121
import java.util.List;
22+
import java.util.Set;
23+
2224
import software.amazon.smithy.aws.traits.ServiceTrait;
25+
import software.amazon.smithy.model.Model;
26+
import software.amazon.smithy.model.knowledge.OperationIndex;
27+
import software.amazon.smithy.model.shapes.OperationShape;
2328
import software.amazon.smithy.model.shapes.Shape;
2429
import software.amazon.smithy.typescript.codegen.TypeScriptDependency;
2530
import software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin;
2631
import software.amazon.smithy.typescript.codegen.integration.TypeScriptIntegration;
2732
import software.amazon.smithy.utils.ListUtils;
33+
import software.amazon.smithy.utils.SetUtils;
2834

2935
/**
3036
* Adds all built-in runtime client plugins to clients.
3137
*/
3238
public class AddBuiltinPlugins implements TypeScriptIntegration {
3339

40+
private static final Set<String> SSEC_OPERATIONS = SetUtils.of("SSECustomerKey", "CopySourceSSECustomerKey");
41+
3442
@Override
3543
public List<RuntimeClientPlugin> getClientPlugins() {
3644
// Note that order is significant because configurations might
@@ -74,10 +82,22 @@ public List<RuntimeClientPlugin> getClientPlugins() {
7482
.withConventions(AwsDependency.ADD_GLACIER_API_VERSION.dependency,
7583
"AddGlacierApiVersion", HAS_MIDDLEWARE)
7684
.servicePredicate((m, s) -> testServiceId(s, "Glacier"))
85+
.build(),
86+
RuntimeClientPlugin.builder()
87+
.withConventions(AwsDependency.SSEC_MIDDLEWARE.dependency, "Ssec", HAS_MIDDLEWARE)
88+
.servicePredicate((m, s) -> testServiceId(s, "S3"))
89+
.operationPredicate((m, s, o) -> testContainsMember(m, o, SSEC_OPERATIONS))
7790
.build()
7891
);
7992
}
8093

94+
private static boolean testContainsMember(Model model, OperationShape operationShape, Set<String> expectedMemberNames) {
95+
OperationIndex operationIndex = model.getKnowledge(OperationIndex.class);
96+
return operationIndex.getInput(operationShape)
97+
.filter(input -> input.getMemberNames().stream().anyMatch(expectedMemberNames::contains))
98+
.isPresent();
99+
}
100+
81101
private static boolean testServiceId(Shape serviceShape, String expectedId) {
82102
return serviceShape.getTrait(ServiceTrait.class).map(ServiceTrait::getSdkId).orElse("").equals(expectedId);
83103
}

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ public enum AwsDependency implements SymbolDependencyContainer {
3434
ACCEPTS_HEADER(NORMAL_DEPENDENCY, "@aws-sdk/middleware-sdk-api-gateway", "^0.1.0-preview.5"),
3535
VALIDATE_BUCKET_NAME(NORMAL_DEPENDENCY, "@aws-sdk/middleware-sdk-s3", "^0.1.0-preview.2"),
3636
ADD_EXPECT_CONTINUE(NORMAL_DEPENDENCY, "@aws-sdk/middleware-expect-continue", "^0.1.0-preview.5"),
37-
ADD_GLACIER_API_VERSION(NORMAL_DEPENDENCY, "@aws-sdk/middleware-sdk-glacier", "^0.1.0-preview.7");
37+
ADD_GLACIER_API_VERSION(NORMAL_DEPENDENCY, "@aws-sdk/middleware-sdk-glacier", "^0.1.0-preview.7"),
38+
SSEC_MIDDLEWARE(NORMAL_DEPENDENCY, "@aws-sdk/middleware-ssec", "^0.1.0-preview.5");
3839

3940
public final String packageName;
4041
public final String version;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

Diff for: packages/middleware-ssec/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# @aws-sdk/middleware-ssec
2+
3+
[![NPM version](https://img.shields.io/npm/v/@aws-sdk/middleware-ssec/preview.svg)](https://www.npmjs.com/package/@aws-sdk/middleware-ssec)
4+
[![NPM downloads](https://img.shields.io/npm/dm/@aws-sdk/middleware-ssec.svg)](https://www.npmjs.com/package/@aws-sdk/middleware-ssec)
File renamed without changes.

Diff for: packages/ssec-middleware/package.json renamed to packages/middleware-ssec/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"name": "@aws-sdk/ssec-middleware",
3-
"version": "0.1.0-preview.8",
2+
"name": "@aws-sdk/middleware-ssec",
3+
"version": "0.1.0-preview.5",
44
"scripts": {
55
"prepublishOnly": "tsc",
66
"pretest": "tsc -p tsconfig.test.json",
@@ -22,4 +22,4 @@
2222
"jest": "^24.7.1",
2323
"typescript": "~3.4.0"
2424
}
25-
}
25+
}

Diff for: packages/middleware-ssec/src/configuration.ts

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Decoder, Encoder, Hash } from "@aws-sdk/types";
2+
3+
export interface SsecMiddlewareInputConfig {}
4+
5+
interface PreviouslyResolved {
6+
base64Encoder: Encoder;
7+
md5: { new (): Hash };
8+
utf8Decoder: Decoder;
9+
}
10+
11+
export interface ResolvedSsecMiddlewareConfig {
12+
base64Encoder: Encoder;
13+
md5: { new (): Hash };
14+
utf8Decoder: Decoder;
15+
}
16+
17+
export function resolveSsecMiddlewareConfig<T>(
18+
input: T & PreviouslyResolved & SsecMiddlewareInputConfig
19+
): T & ResolvedSsecMiddlewareConfig {
20+
return {
21+
...input
22+
};
23+
}

Diff for: packages/middleware-ssec/src/index.spec.ts

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { ssecMiddleware } from "./";
2+
import { HashConstructor } from "@aws-sdk/types";
3+
4+
describe("ssecMiddleware", () => {
5+
const next = jest.fn();
6+
const decoder = jest.fn().mockResolvedValue(new Uint8Array(0));
7+
const encoder = jest.fn().mockReturnValue("base64");
8+
const mockHashUpdate = jest.fn();
9+
const mockHashDigest = jest.fn().mockReturnValue(new Uint8Array(0));
10+
const MockHash: HashConstructor = class {} as any;
11+
MockHash.prototype.update = mockHashUpdate;
12+
MockHash.prototype.digest = mockHashDigest;
13+
14+
beforeEach(() => {
15+
next.mockClear();
16+
decoder.mockClear();
17+
encoder.mockClear();
18+
mockHashUpdate.mockClear();
19+
mockHashDigest.mockClear();
20+
});
21+
22+
it("should base64 encode input keys and set respective MD5 inputs", async () => {
23+
const args = {
24+
input: {
25+
SSECustomerKey: "foo",
26+
CopySourceSSECustomerKey: "bar"
27+
}
28+
};
29+
30+
const handler = ssecMiddleware({
31+
base64Encoder: encoder,
32+
utf8Decoder: decoder,
33+
md5: MockHash
34+
})(next, {} as any);
35+
36+
await handler(args);
37+
38+
expect(next.mock.calls.length).toBe(1);
39+
expect(next).toHaveBeenCalledWith({
40+
input: {
41+
SSECustomerKey: "base64",
42+
SSECustomerKeyMD5: "base64",
43+
CopySourceSSECustomerKey: "base64",
44+
CopySourceSSECustomerKeyMD5: "base64"
45+
}
46+
});
47+
expect(decoder.mock.calls.length).toBe(2);
48+
expect(encoder.mock.calls.length).toBe(4);
49+
expect(mockHashUpdate.mock.calls.length).toBe(2);
50+
expect(mockHashDigest.mock.calls.length).toBe(2);
51+
});
52+
});

Diff for: packages/middleware-ssec/src/index.ts

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import {
2+
InitializeHandler,
3+
InitializeHandlerArguments,
4+
InitializeHandlerOptions,
5+
InitializeHandlerOutput,
6+
MetadataBearer,
7+
Pluggable,
8+
InitializeMiddleware,
9+
SourceData
10+
} from "@aws-sdk/types";
11+
import { ResolvedSsecMiddlewareConfig } from "./configuration";
12+
13+
export function ssecMiddleware(
14+
options: ResolvedSsecMiddlewareConfig
15+
): InitializeMiddleware<any, any> {
16+
return <Output extends MetadataBearer>(
17+
next: InitializeHandler<any, Output>
18+
): InitializeHandler<any, Output> => async (
19+
args: InitializeHandlerArguments<any>
20+
): Promise<InitializeHandlerOutput<Output>> => {
21+
let input = { ...args.input };
22+
const properties = [
23+
{
24+
target: "SSECustomerKey",
25+
hash: "SSECustomerKeyMD5"
26+
},
27+
{
28+
target: "CopySourceSSECustomerKey",
29+
hash: "CopySourceSSECustomerKeyMD5"
30+
}
31+
];
32+
33+
for (const prop of properties) {
34+
const value: SourceData | undefined = (input as any)[prop.target];
35+
if (value) {
36+
const valueView = ArrayBuffer.isView(value)
37+
? new Uint8Array(value.buffer, value.byteOffset, value.byteLength)
38+
: typeof value === "string"
39+
? options.utf8Decoder(value)
40+
: new Uint8Array(value);
41+
const encoded = options.base64Encoder(valueView);
42+
const hash = new options.md5();
43+
hash.update(valueView);
44+
input = {
45+
...(input as any),
46+
[prop.target]: encoded,
47+
[prop.hash]: options.base64Encoder(await hash.digest())
48+
};
49+
}
50+
}
51+
52+
return next({
53+
...args,
54+
input
55+
});
56+
};
57+
}
58+
59+
export const ssecMiddlewareOptions: InitializeHandlerOptions = {
60+
name: "ssecMiddleware",
61+
step: "initialize",
62+
tags: ["SSE"]
63+
};
64+
65+
export const getSsecPlugin = (
66+
config: ResolvedSsecMiddlewareConfig
67+
): Pluggable<any, any> => ({
68+
applyToStack: clientStack => {
69+
clientStack.add(ssecMiddleware(config), ssecMiddlewareOptions);
70+
}
71+
});
File renamed without changes.

Diff for: packages/ssec-middleware/README.md

-4
This file was deleted.

0 commit comments

Comments
 (0)