1 /*
2  * Copyright 2010-2020 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 package com.amazonaws.http.protocol;
16
17 import java.io.IOException;
18 import java.net.Socket;
19
20 import org.apache.http.HttpClientConnection;
21 import org.apache.http.HttpException;
22 import org.apache.http.HttpRequest;
23 import org.apache.http.HttpResponse;
24 import org.apache.http.conn.ManagedHttpClientConnection;
25 import org.apache.http.protocol.HttpContext;
26 import org.apache.http.protocol.HttpRequestExecutor;
27
28 import com.amazonaws.internal.SdkMetricsSocket;
29 import com.amazonaws.internal.SdkSSLMetricsSocket;
30 import com.amazonaws.util.AWSRequestMetrics;
31 import com.amazonaws.util.AWSRequestMetrics.Field;
32
33 /**
34  * Used to capture the http send-request and receive-response latency metrics
35  * of the http client library, with no retries involved.
36  */

37 public class SdkHttpRequestExecutor extends HttpRequestExecutor {
38     @Override
39     protected HttpResponse doSendRequest(
40         final HttpRequest request,
41         final HttpClientConnection conn,
42         final HttpContext context)
43         throws IOException, HttpException {
44         AWSRequestMetrics awsRequestMetrics = (AWSRequestMetrics) context
45             .getAttribute(AWSRequestMetrics.SIMPLE_NAME);
46
47         if (awsRequestMetrics == null) {
48             return super.doSendRequest(request, conn, context);
49         }
50         if (conn instanceof ManagedHttpClientConnection) {
51             ManagedHttpClientConnection managedConn = (ManagedHttpClientConnection)conn;
52             Socket sock = managedConn.getSocket();
53             if (sock instanceof SdkMetricsSocket) {
54                 SdkMetricsSocket sdkMetricsSocket = (SdkMetricsSocket)sock;
55                 sdkMetricsSocket.setMetrics(awsRequestMetrics);
56             } else if (sock instanceof SdkSSLMetricsSocket) {
57                 SdkSSLMetricsSocket sdkSSLMetricsSocket = (SdkSSLMetricsSocket)sock;
58                 sdkSSLMetricsSocket.setMetrics(awsRequestMetrics);
59             }
60         }
61         awsRequestMetrics.startEvent(Field.HttpClientSendRequestTime);
62         try {
63             return super.doSendRequest(request, conn, context);
64         } finally {
65             awsRequestMetrics.endEvent(Field.HttpClientSendRequestTime);
66         }
67     }
68
69     @Override
70     protected HttpResponse doReceiveResponse(
71         final HttpRequest          request,
72         final HttpClientConnection conn,
73         final HttpContext          context)
74         throws HttpException, IOException {
75         AWSRequestMetrics awsRequestMetrics = (AWSRequestMetrics) context
76             .getAttribute(AWSRequestMetrics.SIMPLE_NAME);
77         if (awsRequestMetrics == null) {
78             return super.doReceiveResponse(request, conn, context);
79         }
80         awsRequestMetrics.startEvent(Field.HttpClientReceiveResponseTime);
81         try {
82             return super.doReceiveResponse(request, conn, context);
83         } finally {
84             awsRequestMetrics.endEvent(Field.HttpClientReceiveResponseTime);
85         }
86     }
87 }