Skip to content

Commit 9ef76c3

Browse files
mtdowlingadwsingh
authored andcommitted
Move to blocking client, towards virtual threads
Rather than build everything from the bottom up around the complexity of CompletableFutures and Flows, migrating to a blocking approach and remove the async client and async methods. We will move towards more virtual threads-based approaches, and increase the minimum Java version. The server has not yet been updated, and we should look at possible ways to implement blocking/queue style event streams if possible. This change also requires us to bump the minimum version from Java 17 to 21.
1 parent 6bf2bf1 commit 9ef76c3

File tree

87 files changed

+597
-1620
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+597
-1620
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ and building services. These examples can be used as a template for a new projec
3535
## Usage
3636

3737
> [!WARNING]
38-
> Smithy-Java only supports **Java 17** or later. Older Java versions are not supported.
38+
> Smithy-Java only supports **Java 21** or later. Older Java versions are not supported.
3939
4040
### Codegen (Gradle)
4141

auth-api/src/main/java/software/amazon/smithy/java/auth/api/NullSigner.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
package software.amazon.smithy.java.auth.api;
77

8-
import java.util.concurrent.CompletableFuture;
98
import software.amazon.smithy.java.auth.api.identity.Identity;
109
import software.amazon.smithy.java.context.Context;
1110

@@ -31,7 +30,7 @@ private NullSigner() {}
3130
* @return the request as-is.
3231
*/
3332
@Override
34-
public CompletableFuture<Object> sign(Object request, Identity identity, Context properties) {
35-
return CompletableFuture.completedFuture(request);
33+
public Object sign(Object request, Identity identity, Context properties) {
34+
return request;
3635
}
3736
}

auth-api/src/main/java/software/amazon/smithy/java/auth/api/Signer.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
package software.amazon.smithy.java.auth.api;
77

8-
import java.util.concurrent.CompletableFuture;
98
import software.amazon.smithy.java.auth.api.identity.Identity;
109
import software.amazon.smithy.java.context.Context;
1110

@@ -25,7 +24,7 @@ public interface Signer<RequestT, IdentityT extends Identity> extends AutoClosea
2524
* @param properties Signing properties.
2625
* @return the signed request.
2726
*/
28-
CompletableFuture<RequestT> sign(RequestT request, IdentityT identity, Context properties);
27+
RequestT sign(RequestT request, IdentityT identity, Context properties);
2928

3029
@SuppressWarnings("unchecked")
3130
static <RequestT, IdentityT extends Identity> Signer<RequestT, IdentityT> nullSigner() {

auth-api/src/main/java/software/amazon/smithy/java/auth/api/identity/IdentityResolver.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
package software.amazon.smithy.java.auth.api.identity;
77

88
import java.util.List;
9-
import java.util.concurrent.CompletableFuture;
109
import software.amazon.smithy.java.context.Context;
1110

1211
/**
@@ -20,9 +19,9 @@ public interface IdentityResolver<IdentityT extends Identity> {
2019
* error string. Unexpected errors like malformed input or networking errors are allowed to throw exceptions.
2120
*
2221
* @param requestProperties The request properties used to resolve an Identity.
23-
* @return a CompletableFuture for the resolved identity result.
22+
* @return the resolved identity result.
2423
*/
25-
CompletableFuture<IdentityResult<IdentityT>> resolveIdentity(Context requestProperties);
24+
IdentityResult<IdentityT> resolveIdentity(Context requestProperties);
2625

2726
/**
2827
* Retrieve the class of the identity resolved by this identity resolver.
@@ -42,7 +41,8 @@ static <I extends Identity> IdentityResolver<I> chain(List<IdentityResolver<I>>
4241
}
4342

4443
/**
45-
* Create an implementation of {@link IdentityResolver} that returns a specific, pre-defined instance of {@link Identity}.
44+
* Create an implementation of {@link IdentityResolver} that returns a specific, pre-defined instance of
45+
* {@link Identity}.
4646
*/
4747
static <I extends Identity> IdentityResolver<I> of(I identity) {
4848
return new StaticIdentityResolver<>(identity);

auth-api/src/main/java/software/amazon/smithy/java/auth/api/identity/IdentityResolverChain.java

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import java.util.ArrayList;
99
import java.util.List;
1010
import java.util.Objects;
11-
import java.util.concurrent.CompletableFuture;
1211
import software.amazon.smithy.java.context.Context;
1312

1413
final class IdentityResolverChain<IdentityT extends Identity> implements IdentityResolver<IdentityT> {
@@ -29,35 +28,15 @@ public Class<IdentityT> identityType() {
2928
}
3029

3130
@Override
32-
public CompletableFuture<IdentityResult<IdentityT>> resolveIdentity(Context requestProperties) {
31+
public IdentityResult<IdentityT> resolveIdentity(Context requestProperties) {
3332
List<IdentityResult<?>> errors = new ArrayList<>();
34-
return executeChain(resolvers.get(0), requestProperties, errors, 0);
35-
}
36-
37-
private CompletableFuture<IdentityResult<IdentityT>> executeChain(
38-
IdentityResolver<IdentityT> resolver,
39-
Context requestProperties,
40-
List<IdentityResult<?>> errors,
41-
int idx
42-
) {
43-
var result = resolver.resolveIdentity(requestProperties);
44-
if (idx + 1 < resolvers.size()) {
45-
var nextResolver = resolvers.get(idx + 1);
46-
return result.thenCompose(ir -> {
47-
if (ir.error() != null) {
48-
errors.add(ir);
49-
return executeChain(nextResolver, requestProperties, errors, idx + 1);
50-
}
51-
return CompletableFuture.completedFuture(ir);
52-
});
53-
}
54-
55-
return result.thenApply(ir -> {
56-
if (ir.error() != null) {
57-
errors.add(ir);
58-
return IdentityResult.ofError(IdentityResolverChain.class, "Attempted resolvers: " + errors);
33+
for (IdentityResolver<IdentityT> resolver : resolvers) {
34+
IdentityResult<IdentityT> result = resolver.resolveIdentity(requestProperties);
35+
if (result.error() == null) {
36+
return result;
5937
}
60-
return ir;
61-
});
38+
errors.add(result);
39+
}
40+
return IdentityResult.ofError(IdentityResolverChain.class, "Attempted resolvers: " + errors);
6241
}
6342
}

auth-api/src/main/java/software/amazon/smithy/java/auth/api/identity/StaticIdentityResolver.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,20 @@
66
package software.amazon.smithy.java.auth.api.identity;
77

88
import java.util.Objects;
9-
import java.util.concurrent.CompletableFuture;
109
import software.amazon.smithy.java.context.Context;
1110

1211
final class StaticIdentityResolver<IdentityT extends Identity> implements IdentityResolver<IdentityT> {
1312

1413
private final IdentityT identity;
15-
private final CompletableFuture<IdentityResult<IdentityT>> result;
14+
private final IdentityResult<IdentityT> result;
1615

1716
public StaticIdentityResolver(IdentityT identity) {
1817
this.identity = Objects.requireNonNull(identity);
19-
this.result = CompletableFuture.completedFuture(IdentityResult.of(identity));
18+
this.result = IdentityResult.of(identity);
2019
}
2120

2221
@Override
23-
public CompletableFuture<IdentityResult<IdentityT>> resolveIdentity(Context requestProperties) {
22+
public IdentityResult<IdentityT> resolveIdentity(Context requestProperties) {
2423
return result;
2524
}
2625

aws/aws-event-streams/src/main/java/software/amazon/smithy/java/aws/events/RpcEventStreamsUtil.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ public static Flow.Publisher<ByteBuffer> bodyForEventStreaming(
3232
return EventStreamFrameEncodingProcessor.create(eventStream, eventStreamEncodingFactory, input);
3333
}
3434

35-
public static <O extends SerializableStruct> CompletableFuture<O> deserializeResponse(
35+
// TODO: Make more synchronous
36+
public static <O extends SerializableStruct> O deserializeResponse(
3637
EventDecoderFactory<AwsEventFrame> eventDecoderFactory,
3738
DataStream bodyDataStream
3839
) {
@@ -63,7 +64,7 @@ public void onComplete() {
6364
}
6465
});
6566

66-
return result;
67+
return result.join();
6768
}
6869

6970
private static Schema streamingMember(Schema schema) {

aws/aws-sigv4/src/jmh/java/software/amazon/smithy/java/aws/client/auth/scheme/sigv4/SigV4SignerTrials.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@
55

66
package software.amazon.smithy.java.aws.client.auth.scheme.sigv4;
77

8-
import java.io.IOException;
98
import java.net.URI;
109
import java.nio.charset.StandardCharsets;
1110
import java.security.Security;
1211
import java.util.Collections;
1312
import java.util.List;
1413
import java.util.Map;
15-
import java.util.concurrent.ExecutionException;
1614
import java.util.concurrent.TimeUnit;
1715
import org.openjdk.jmh.annotations.Benchmark;
1816
import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -110,9 +108,9 @@ public void setup() throws Exception {
110108
}
111109

112110
@Benchmark
113-
public void sign() throws IOException, ExecutionException, InterruptedException {
111+
public void sign() {
114112
if (!skipTest) {
115-
signer.sign(request, TEST_IDENTITY, TEST_PROPERTIES).get();
113+
signer.sign(request, TEST_IDENTITY, TEST_PROPERTIES);
116114
} else {
117115
System.out.println("Skipping benchmark on Windows");
118116
}

aws/aws-sigv4/src/main/java/software/amazon/smithy/java/aws/client/auth/scheme/sigv4/SigV4Signer.java

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import java.util.Set;
2323
import java.util.SortedMap;
2424
import java.util.TreeMap;
25-
import java.util.concurrent.CompletableFuture;
2625
import javax.crypto.Mac;
2726
import javax.crypto.spec.SecretKeySpec;
2827
import software.amazon.smithy.java.auth.api.Signer;
@@ -98,11 +97,7 @@ public void close() {
9897
}
9998

10099
@Override
101-
public CompletableFuture<HttpRequest> sign(
102-
HttpRequest request,
103-
AwsCredentialsIdentity identity,
104-
Context properties
105-
) {
100+
public HttpRequest sign(HttpRequest request, AwsCredentialsIdentity identity, Context properties) {
106101
var region = properties.expect(SigV4Settings.REGION);
107102
var name = properties.expect(SigV4Settings.SIGNING_NAME);
108103
var clock = properties.getOrDefault(SigV4Settings.CLOCK, Clock.systemUTC());
@@ -111,32 +106,31 @@ public CompletableFuture<HttpRequest> sign(
111106
// TODO: Support chunk encoding
112107
// TODO: support UNSIGNED
113108

114-
return getPayloadHash(request.body()).thenApply(payloadHash -> {
115-
var signedHeaders = createSignedHeaders(
116-
request.method(),
117-
request.uri(),
118-
request.headers(),
119-
payloadHash,
120-
region,
121-
name,
122-
clock.instant(),
123-
identity.accessKeyId(),
124-
identity.secretAccessKey(),
125-
identity.sessionToken(),
126-
!request.body().hasKnownLength());
127-
// Don't let the cached buffers grow too large.
128-
var sb = signingResources.sb;
129-
if (sb.length() > BUFFER_SIZE) {
130-
sb.setLength(BUFFER_SIZE);
131-
sb.trimToSize();
132-
}
133-
sb.setLength(0);
134-
return request.toBuilder().headers(HttpHeaders.of(signedHeaders)).build();
135-
});
109+
var payloadHash = getPayloadHash(request.body());
110+
var signedHeaders = createSignedHeaders(
111+
request.method(),
112+
request.uri(),
113+
request.headers(),
114+
payloadHash,
115+
region,
116+
name,
117+
clock.instant(),
118+
identity.accessKeyId(),
119+
identity.secretAccessKey(),
120+
identity.sessionToken(),
121+
!request.body().hasKnownLength());
122+
// Don't let the cached buffers grow too large.
123+
var sb = signingResources.sb;
124+
if (sb.length() > BUFFER_SIZE) {
125+
sb.setLength(BUFFER_SIZE);
126+
sb.trimToSize();
127+
}
128+
sb.setLength(0);
129+
return request.toBuilder().headers(HttpHeaders.of(signedHeaders)).build();
136130
}
137131

138-
private CompletableFuture<String> getPayloadHash(DataStream dataStream) {
139-
return dataStream.asByteBuffer().thenApply(this::hexHash);
132+
private String getPayloadHash(DataStream dataStream) {
133+
return hexHash(dataStream.waitForByteBuffer());
140134
}
141135

142136
private String hexHash(ByteBuffer bytes) {

aws/aws-sigv4/src/test/java/software/amazon/smithy/java/aws/client/auth/scheme/sigv4/SigV4TestRunner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ private static HttpRequest parseRequest(String fileName) {
159159
Result createResult(
160160
Signer<HttpRequest, AwsCredentialsIdentity> signer
161161
) throws ExecutionException, InterruptedException {
162-
var signedRequest = signer.sign(request, context.identity, context.properties).get();
162+
var signedRequest = signer.sign(request, context.identity, context.properties);
163163
boolean isValid = signedRequest.headers().equals(expected.headers())
164164
&& signedRequest.uri().equals(expected.uri())
165165
&& signedRequest.method().equals(expected.method());

0 commit comments

Comments
 (0)