• 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.testutils.service.http;
17 
18 import java.time.Duration;
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.Collections;
22 import java.util.LinkedList;
23 import java.util.List;
24 import java.util.concurrent.atomic.AtomicInteger;
25 import java.util.stream.Collectors;
26 import software.amazon.awssdk.http.ExecutableHttpRequest;
27 import software.amazon.awssdk.http.HttpExecuteRequest;
28 import software.amazon.awssdk.http.HttpExecuteResponse;
29 import software.amazon.awssdk.http.SdkHttpClient;
30 import software.amazon.awssdk.http.SdkHttpRequest;
31 import software.amazon.awssdk.utils.Pair;
32 
33 /**
34  * Mockable implementation of {@link SdkHttpClient}.
35  */
36 public final class MockSyncHttpClient implements SdkHttpClient, MockHttpClient {
37     private static final Duration DEFAULT_DURATION = Duration.ofMillis(50);
38     private final List<SdkHttpRequest> capturedRequests = new ArrayList<>();
39     private final List<Pair<HttpExecuteResponse, Duration>> responses = new LinkedList<>();
40     private final AtomicInteger responseIndex = new AtomicInteger(0);
41     private boolean isClosed;
42 
43     @Override
prepareRequest(HttpExecuteRequest request)44     public ExecutableHttpRequest prepareRequest(HttpExecuteRequest request) {
45         capturedRequests.add(request.httpRequest());
46         return new ExecutableHttpRequest() {
47             @Override
48             public HttpExecuteResponse call() {
49                 Pair<HttpExecuteResponse, Duration> responseDurationPair =
50                     responses.get(responseIndex.getAndIncrement() % responses.size());
51                 HttpExecuteResponse response = responseDurationPair.left();
52                 Duration duration = responseDurationPair.right();
53 
54                 try {
55                     Thread.sleep(duration.toMillis());
56                 } catch (InterruptedException e) {
57                     Thread.currentThread().interrupt();
58                 }
59 
60                 if (response == null) {
61                     throw new IllegalStateException("No responses remain.");
62                 }
63                 return response;
64             }
65 
66             @Override
67             public void abort() {
68             }
69         };
70     }
71 
72 
73     @Override
74     public void close() {
75         isClosed = true;
76     }
77 
78     @Override
79     public void reset() {
80         this.capturedRequests.clear();
81         this.responses.clear();
82         this.responseIndex.set(0);
83     }
84 
85     @Override
86     public void stubNextResponse(HttpExecuteResponse nextResponse) {
87         this.responses.clear();
88         this.responses.add(Pair.of(nextResponse, DEFAULT_DURATION));
89         this.responseIndex.set(0);
90     }
91 
92     @Override
93     public void stubNextResponse(HttpExecuteResponse nextResponse, Duration delay) {
94         this.responses.add(Pair.of(nextResponse, delay));
95         this.responseIndex.set(0);
96     }
97 
98     @Override
99     public void stubResponses(Pair<HttpExecuteResponse, Duration>... responses) {
100         this.responses.clear();
101         this.responses.addAll(Arrays.asList(responses));
102         this.responseIndex.set(0);
103     }
104 
105     @Override
106     public void stubResponses(HttpExecuteResponse... responses) {
107         this.responses.clear();
108         this.responses.addAll(Arrays.stream(responses).map(r -> Pair.of(r, DEFAULT_DURATION)).collect(Collectors.toList()));
109         this.responseIndex.set(0);
110     }
111 
112     @Override
113     public List<SdkHttpRequest> getRequests() {
114         return Collections.unmodifiableList(capturedRequests);
115     }
116 
117     @Override
118     public SdkHttpRequest getLastRequest() {
119         if (capturedRequests.isEmpty()) {
120             throw new IllegalStateException("No requests were captured by the mock");
121         }
122         return capturedRequests.get(capturedRequests.size() - 1);
123     }
124 
125     public boolean isClosed() {
126         return isClosed;
127     }
128 }
129