• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 package software.amazon.awssdk.http.crt.internal;
17 
18 import static software.amazon.awssdk.http.HttpMetric.AVAILABLE_CONCURRENCY;
19 import static software.amazon.awssdk.http.HttpMetric.CONCURRENCY_ACQUIRE_DURATION;
20 import static software.amazon.awssdk.http.HttpMetric.LEASED_CONCURRENCY;
21 import static software.amazon.awssdk.http.HttpMetric.MAX_CONCURRENCY;
22 import static software.amazon.awssdk.http.HttpMetric.PENDING_CONCURRENCY_ACQUIRES;
23 import static software.amazon.awssdk.utils.NumericUtils.saturatedCast;
24 
25 import java.io.IOException;
26 import java.time.Duration;
27 import javax.net.ssl.SSLHandshakeException;
28 import software.amazon.awssdk.annotations.SdkInternalApi;
29 import software.amazon.awssdk.crt.http.HttpClientConnection;
30 import software.amazon.awssdk.crt.http.HttpClientConnectionManager;
31 import software.amazon.awssdk.crt.http.HttpException;
32 import software.amazon.awssdk.crt.http.HttpManagerMetrics;
33 import software.amazon.awssdk.metrics.MetricCollector;
34 
35 @SdkInternalApi
36 public final class CrtUtils {
37     public static final int CRT_TLS_NEGOTIATION_ERROR_CODE = 1029;
38 
CrtUtils()39     private CrtUtils() {
40     }
41 
wrapWithIoExceptionIfRetryable(HttpException httpException)42     public static Throwable wrapWithIoExceptionIfRetryable(HttpException httpException) {
43         Throwable toThrow = httpException;
44 
45         if (HttpClientConnection.isErrorRetryable(httpException)) {
46             // IOExceptions get retried, and if the CRT says this error is retryable,
47             // it's semantically an IOException anyway.
48             toThrow = new IOException(httpException);
49         }
50         return toThrow;
51     }
52 
wrapConnectionFailureException(Throwable throwable)53     public static Throwable wrapConnectionFailureException(Throwable throwable) {
54         Throwable toThrow = new IOException("An exception occurred when acquiring a connection", throwable);
55         if (throwable instanceof HttpException) {
56             HttpException httpException = (HttpException) throwable;
57 
58             if (httpException.getErrorCode() == CRT_TLS_NEGOTIATION_ERROR_CODE) {
59                 toThrow = new SSLHandshakeException(httpException.getMessage());
60             }
61         }
62 
63         return toThrow;
64     }
65 
reportMetrics(HttpClientConnectionManager connManager, MetricCollector metricCollector, long acquireStartTime)66     public static void reportMetrics(HttpClientConnectionManager connManager, MetricCollector metricCollector,
67                                       long acquireStartTime) {
68         long acquireCompletionTime = System.nanoTime();
69         Duration acquireTimeTaken = Duration.ofNanos(acquireCompletionTime - acquireStartTime);
70         metricCollector.reportMetric(CONCURRENCY_ACQUIRE_DURATION, acquireTimeTaken);
71         HttpManagerMetrics managerMetrics = connManager.getManagerMetrics();
72         // currently this executor only handles HTTP 1.1. Until H2 is added, the max concurrency settings are 1:1 with TCP
73         // connections. When H2 is added, this code needs to be updated to handle stream multiplexing
74         metricCollector.reportMetric(MAX_CONCURRENCY, connManager.getMaxConnections());
75         metricCollector.reportMetric(AVAILABLE_CONCURRENCY, saturatedCast(managerMetrics.getAvailableConcurrency()));
76         metricCollector.reportMetric(LEASED_CONCURRENCY, saturatedCast(managerMetrics.getLeasedConcurrency()));
77         metricCollector.reportMetric(PENDING_CONCURRENCY_ACQUIRES, saturatedCast(managerMetrics.getPendingConcurrencyAcquires()));
78     }
79 
80 }
81