Skip to content

Commit 45156cc

Browse files
mtdowlingadwsingh
authored andcommitted
Add optimizations and s3 tests
1 parent 86f8812 commit 45156cc

17 files changed

Lines changed: 39971 additions & 366 deletions

File tree

aws/client/aws-client-rulesengine/build.gradle.kts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
plugins {
22
id("smithy-java.module-conventions")
3+
id("me.champeau.jmh") version "0.7.3"
34
}
45

56
description = "This module provides AWS-Specific client rules engine functionality"
@@ -16,3 +17,25 @@ dependencies {
1617
testImplementation(project(":aws:client:aws-client-restxml"))
1718
testImplementation(project(":client:dynamic-client"))
1819
}
20+
21+
// Share the S3 model between JMH and tests.
22+
sourceSets {
23+
val sharedResources = "src/shared-resources"
24+
25+
named("test") {
26+
resources.srcDir(sharedResources)
27+
}
28+
29+
named("jmh") {
30+
resources.srcDir(sharedResources)
31+
}
32+
}
33+
34+
jmh {
35+
warmupIterations = 2
36+
iterations = 5
37+
fork = 1
38+
profilers.add("async:output=flamegraph")
39+
// profilers.add("gc")
40+
duplicateClassesStrategy = DuplicatesStrategy.WARN
41+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package software.amazon.smithy.java.aws.client.rulesengine;
7+
8+
import java.util.Map;
9+
import java.util.concurrent.TimeUnit;
10+
import org.openjdk.jmh.annotations.Benchmark;
11+
import org.openjdk.jmh.annotations.BenchmarkMode;
12+
import org.openjdk.jmh.annotations.Fork;
13+
import org.openjdk.jmh.annotations.Measurement;
14+
import org.openjdk.jmh.annotations.Mode;
15+
import org.openjdk.jmh.annotations.OutputTimeUnit;
16+
import org.openjdk.jmh.annotations.Scope;
17+
import org.openjdk.jmh.annotations.Setup;
18+
import org.openjdk.jmh.annotations.State;
19+
import org.openjdk.jmh.annotations.Warmup;
20+
import software.amazon.smithy.java.aws.client.core.settings.EndpointSettings;
21+
import software.amazon.smithy.java.client.core.auth.scheme.AuthSchemeResolver;
22+
import software.amazon.smithy.java.client.core.endpoint.EndpointResolver;
23+
import software.amazon.smithy.java.client.core.endpoint.EndpointResolverParams;
24+
import software.amazon.smithy.java.client.rulesengine.EndpointRulesPlugin;
25+
import software.amazon.smithy.java.client.rulesengine.RulesEngine;
26+
import software.amazon.smithy.java.context.Context;
27+
import software.amazon.smithy.java.core.serde.document.Document;
28+
import software.amazon.smithy.java.dynamicclient.DynamicClient;
29+
import software.amazon.smithy.model.Model;
30+
import software.amazon.smithy.model.loader.ModelAssembler;
31+
import software.amazon.smithy.model.pattern.UriPattern;
32+
import software.amazon.smithy.model.shapes.ServiceShape;
33+
import software.amazon.smithy.model.shapes.Shape;
34+
import software.amazon.smithy.model.shapes.ShapeId;
35+
import software.amazon.smithy.model.traits.HttpTrait;
36+
import software.amazon.smithy.model.transform.ModelTransformer;
37+
38+
@State(Scope.Benchmark)
39+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
40+
@BenchmarkMode(Mode.AverageTime)
41+
@Warmup(iterations = 2, time = 3)
42+
@Measurement(iterations = 3, time = 3)
43+
@Fork(1)
44+
public class Bench {
45+
private DynamicClient client;
46+
private EndpointResolver endpointResolver;
47+
private EndpointResolverParams endpointParams;
48+
49+
@Setup
50+
public void setup() {
51+
var model = Model.assembler()
52+
.discoverModels()
53+
.addImport(ResolverTest.class.getResource("s3.json"))
54+
.putProperty(ModelAssembler.ALLOW_UNKNOWN_TRAITS, true)
55+
.assemble()
56+
.unwrap();
57+
model = customizeS3Model(model);
58+
var service = model.expectShape(ShapeId.from("com.amazonaws.s3#AmazonS3"), ServiceShape.class);
59+
60+
var engine = new RulesEngine();
61+
var plugin = EndpointRulesPlugin.create(engine);
62+
63+
client = DynamicClient.builder()
64+
.model(model)
65+
.service(service.getId())
66+
.authSchemeResolver(AuthSchemeResolver.NO_AUTH)
67+
.addPlugin(plugin)
68+
.build();
69+
endpointResolver = client.config().endpointResolver();
70+
var ctx = Context.create();
71+
ctx.put(EndpointSettings.REGION, "us-east-1");
72+
73+
var inputValue = client.createStruct(ShapeId.from("com.amazonaws.s3#GetObjectRequest"),
74+
Document.of(Map.of(
75+
"Bucket",
76+
Document.of("foo"),
77+
"Key",
78+
Document.of("bar"))));
79+
endpointParams = EndpointResolverParams.builder()
80+
.context(ctx)
81+
.inputValue(inputValue)
82+
.operation(client.getOperation("GetObject"))
83+
.build();
84+
}
85+
86+
// S3 requires a customization to remove buckets from the path :(
87+
private static Model customizeS3Model(Model m) {
88+
return ModelTransformer.create().mapShapes(m, s -> {
89+
if (s.isOperationShape()) {
90+
var httpTrait = s.getTrait(HttpTrait.class).orElse(null);
91+
if (httpTrait != null && httpTrait.getUri().getLabel("Bucket").isPresent()) {
92+
// Remove the bucket from the URI pattern.
93+
var uriString = httpTrait.getUri().toString().replace("{Bucket}", "");
94+
uriString = uriString.replace("//", "/");
95+
var newUri = UriPattern.parse(uriString);
96+
var newHttpTrait = httpTrait.toBuilder().uri(newUri).build();
97+
return Shape.shapeToBuilder(s).addTrait(newHttpTrait).build();
98+
}
99+
}
100+
return s;
101+
});
102+
}
103+
104+
@Benchmark
105+
public Object evaluate() throws Exception {
106+
return endpointResolver.resolveEndpoint(endpointParams).get();
107+
}
108+
}

0 commit comments

Comments
 (0)