Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/next-release/feature-AWSSDKforJavav2-5eb5d9f.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "feature",
"category": "AWS SDK for Java v2",
"contributor": "",
"description": "Move `ApplyUserAgentStage` to later position in request pipeline to ensure all business metrics are properly recorded before finalizing user agent."
}
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,12 @@ public <OutputT> CompletableFuture<OutputT> execute(
.first(RequestPipelineBuilder
.first(MakeRequestMutableStage::new)
.then(ApplyTransactionIdStage::new)
.then(ApplyUserAgentStage::new)
.then(MergeCustomHeadersStage::new)
.then(MergeCustomQueryParamsStage::new)
.then(QueryParametersToBodyStage::new)
.then(() -> new CompressRequestStage(httpClientDependencies))
.then(() -> new HttpChecksumStage(ClientType.ASYNC))
.then(ApplyUserAgentStage::new)
.then(MakeRequestImmutableStage::new)
.then(RequestPipelineBuilder
.first(AsyncSigningStage::new)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,12 @@ public <OutputT> OutputT execute(HttpResponseHandler<Response<OutputT>> response
.first(RequestPipelineBuilder
.first(MakeRequestMutableStage::new)
.then(ApplyTransactionIdStage::new)
.then(ApplyUserAgentStage::new)
.then(MergeCustomHeadersStage::new)
.then(MergeCustomQueryParamsStage::new)
.then(QueryParametersToBodyStage::new)
.then(() -> new CompressRequestStage(httpClientDependencies))
.then(() -> new HttpChecksumStage(ClientType.SYNC))
.then(ApplyUserAgentStage::new)
.then(MakeRequestImmutableStage::new)
// End of mutating request
.then(RequestPipelineBuilder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public enum BusinessMetricFeatureId {
RETRY_MODE_STANDARD("E"),
RETRY_MODE_ADAPTIVE("F"),
S3_TRANSFER("G"),
GZIP_REQUEST_COMPRESSION("L"), //TODO(metrics): Not working, compression happens after header
GZIP_REQUEST_COMPRESSION("L"),
PROTOCOL_RPC_V2_CBOR("M"),
ENDPOINT_OVERRIDE("N"),
ACCOUNT_ID_MODE_PREFERRED("P"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.protocolrestjson.ProtocolRestJsonAsyncClient;
import software.amazon.awssdk.services.protocolrestjson.ProtocolRestJsonAsyncClientBuilder;
import software.amazon.awssdk.services.protocolrestjson.ProtocolRestJsonClient;
import software.amazon.awssdk.services.protocolrestjson.ProtocolRestJsonClientBuilder;
import software.amazon.awssdk.services.protocolrestjson.internal.ServiceVersionInfo;
import software.amazon.awssdk.services.protocolrestjson.model.PaginatedOperationWithResultKeyResponse;
import software.amazon.awssdk.services.protocolrestjson.paginators.PaginatedOperationWithResultKeyPublisher;
Expand Down Expand Up @@ -162,7 +164,7 @@ void when_paginatedOperationIsCalled_correctMetricIsAdded() throws Exception {
}

@Test
void when_compressedOperationIsCalled_metricIsRecordedButNotAddedToUserAgentString() throws Exception {
void when_asyncCompressedOperationIsCalled_metricIsRecordedAndAddedToUserAgentString() throws Exception {
ProtocolRestJsonAsyncClientBuilder clientBuilder = asyncClientBuilderForProtocolRestJson();

assertThatThrownBy(() -> clientBuilder.build().putOperationWithRequestCompression(r -> r.body(SdkBytes.fromUtf8String(
Expand All @@ -173,7 +175,22 @@ void when_compressedOperationIsCalled_metricIsRecordedButNotAddedToUserAgentStri
BusinessMetricCollection attribute = interceptor.executionAttributes().getAttribute(SdkInternalExecutionAttribute.BUSINESS_METRICS);
assertThat(attribute).isNotNull();
assertThat(attribute.recordedMetrics()).contains(BusinessMetricFeatureId.GZIP_REQUEST_COMPRESSION.value());
assertThat(userAgent).doesNotMatch(METRIC_SEARCH_PATTERN.apply(BusinessMetricFeatureId.GZIP_REQUEST_COMPRESSION.value()));
assertThat(userAgent).matches(METRIC_SEARCH_PATTERN.apply(BusinessMetricFeatureId.GZIP_REQUEST_COMPRESSION.value()));
}

@Test
void when_syncCompressedOperationIsCalled_metricIsRecordedAndAddedToUserAgentString() throws Exception {
ProtocolRestJsonClientBuilder clientBuilder = syncClientBuilderForProtocolRestJson();

assertThatThrownBy(() -> clientBuilder.build().putOperationWithRequestCompression(r -> r.body(SdkBytes.fromUtf8String(
"whoo")).overrideConfiguration(o -> o.compressionConfiguration(c -> c.minimumCompressionThresholdInBytes(1)))))
.hasMessageContaining("stop");

String userAgent = assertAndGetUserAgentString();
BusinessMetricCollection attribute = interceptor.executionAttributes().getAttribute(SdkInternalExecutionAttribute.BUSINESS_METRICS);
assertThat(attribute).isNotNull();
assertThat(attribute.recordedMetrics()).contains(BusinessMetricFeatureId.GZIP_REQUEST_COMPRESSION.value());
assertThat(userAgent).matches(METRIC_SEARCH_PATTERN.apply(BusinessMetricFeatureId.GZIP_REQUEST_COMPRESSION.value()));
}

private String assertAndGetUserAgentString() {
Expand All @@ -196,6 +213,13 @@ private ProtocolRestJsonAsyncClientBuilder asyncClientBuilderForProtocolRestJson
.overrideConfiguration(c -> c.addExecutionInterceptor(interceptor));
}

private ProtocolRestJsonClientBuilder syncClientBuilderForProtocolRestJson() {
return ProtocolRestJsonClient.builder()
.region(Region.US_WEST_2)
.credentialsProvider(CREDENTIALS_PROVIDER)
.overrideConfiguration(c -> c.addExecutionInterceptor(interceptor));
}

public static class CapturingInterceptor implements ExecutionInterceptor {
private Context.BeforeTransmission context;
private ExecutionAttributes executionAttributes;
Expand Down
Loading