• 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.services.apigateway;
17 
18 import com.google.common.util.concurrent.RateLimiter;
19 import java.time.Duration;
20 import java.time.Instant;
21 import java.util.List;
22 import java.util.concurrent.atomic.AtomicInteger;
23 import junit.framework.Assert;
24 import org.junit.AfterClass;
25 import org.junit.BeforeClass;
26 import org.junit.Test;
27 import software.amazon.awssdk.services.apigateway.model.CreateApiKeyRequest;
28 import software.amazon.awssdk.services.apigateway.model.CreateApiKeyResponse;
29 import software.amazon.awssdk.services.apigateway.model.CreateResourceRequest;
30 import software.amazon.awssdk.services.apigateway.model.CreateResourceResponse;
31 import software.amazon.awssdk.services.apigateway.model.CreateRestApiRequest;
32 import software.amazon.awssdk.services.apigateway.model.CreateRestApiResponse;
33 import software.amazon.awssdk.services.apigateway.model.DeleteRestApiRequest;
34 import software.amazon.awssdk.services.apigateway.model.GetApiKeyRequest;
35 import software.amazon.awssdk.services.apigateway.model.GetApiKeyResponse;
36 import software.amazon.awssdk.services.apigateway.model.GetResourceRequest;
37 import software.amazon.awssdk.services.apigateway.model.GetResourceResponse;
38 import software.amazon.awssdk.services.apigateway.model.GetResourcesRequest;
39 import software.amazon.awssdk.services.apigateway.model.GetResourcesResponse;
40 import software.amazon.awssdk.services.apigateway.model.GetRestApiRequest;
41 import software.amazon.awssdk.services.apigateway.model.GetRestApiResponse;
42 import software.amazon.awssdk.services.apigateway.model.IntegrationType;
43 import software.amazon.awssdk.services.apigateway.model.NotFoundException;
44 import software.amazon.awssdk.services.apigateway.model.Op;
45 import software.amazon.awssdk.services.apigateway.model.PatchOperation;
46 import software.amazon.awssdk.services.apigateway.model.PutIntegrationRequest;
47 import software.amazon.awssdk.services.apigateway.model.PutIntegrationResponse;
48 import software.amazon.awssdk.services.apigateway.model.PutMethodRequest;
49 import software.amazon.awssdk.services.apigateway.model.PutMethodResponse;
50 import software.amazon.awssdk.services.apigateway.model.Resource;
51 import software.amazon.awssdk.services.apigateway.model.RestApi;
52 import software.amazon.awssdk.services.apigateway.model.TooManyRequestsException;
53 import software.amazon.awssdk.services.apigateway.model.UpdateApiKeyRequest;
54 import software.amazon.awssdk.services.apigateway.model.UpdateResourceRequest;
55 import software.amazon.awssdk.services.apigateway.model.UpdateRestApiRequest;
56 import software.amazon.awssdk.utils.Lazy;
57 import software.amazon.awssdk.utils.Logger;
58 
59 public class ServiceIntegrationTest extends IntegrationTestBase {
60     private static final Logger log = Logger.loggerFor(ServiceIntegrationTest.class);
61 
62     private static final String NAME_PREFIX = "java-sdk-integration-";
63     private static final String NAME = NAME_PREFIX + System.currentTimeMillis();
64 
65     private static final String DESCRIPTION = "fooDesc";
66 
67     // Limit deletes to once every 31 seconds
68     // https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html#api-gateway-control-service-limits-table
69     private static final Lazy<RateLimiter> DELETE_RATE_LIMITER = new Lazy<>(() -> RateLimiter.create(1.0 / 31));
70 
71     private static String restApiId = null;
72 
73     @BeforeClass
createRestApi()74     public static void createRestApi() {
75         deleteStaleRestApis();
76         CreateRestApiResponse createRestApiResult = apiGateway.createRestApi(
77                 CreateRestApiRequest.builder().name(NAME)
78                                           .description(DESCRIPTION).build());
79 
80         Assert.assertNotNull(createRestApiResult);
81         Assert.assertNotNull(createRestApiResult.description());
82         Assert.assertNotNull(createRestApiResult.id());
83         Assert.assertNotNull(createRestApiResult.name());
84         Assert.assertNotNull(createRestApiResult.createdDate());
85         Assert.assertEquals(createRestApiResult.name(), NAME);
86         Assert.assertEquals(createRestApiResult.description(), DESCRIPTION);
87 
88         restApiId = createRestApiResult.id();
89     }
90 
91     @AfterClass
deleteRestApiKey()92     public static void deleteRestApiKey() {
93         if (restApiId != null) {
94             DELETE_RATE_LIMITER.getValue().acquire();
95             try {
96                 apiGateway.deleteRestApi(DeleteRestApiRequest.builder().restApiId(restApiId).build());
97             } catch (TooManyRequestsException e) {
98                 log.warn(() -> String.format("Failed to delete REST API %s (%s). This API should be deleted automatically in a "
99                                              + "future 'deleteStaleRestApis' execution.",
100                                              NAME, restApiId), e);
101             }
102         }
103     }
104 
deleteStaleRestApis()105     private static void deleteStaleRestApis() {
106         Instant startTime = Instant.now();
107         Duration maxRunTime = Duration.ofMinutes(5);
108         Duration maxApiAge = Duration.ofDays(7);
109         AtomicInteger success = new AtomicInteger();
110         AtomicInteger failure = new AtomicInteger();
111 
112         log.info(() -> String.format("Searching for stale REST APIs older than %s days...", maxApiAge.toDays()));
113         for (RestApi api : apiGateway.getRestApisPaginator().items()) {
114             if (Instant.now().isAfter(startTime.plus(maxRunTime))) {
115                 log.info(() -> String.format("More than %s has elapsed trying to delete stale REST APIs, giving up for this run. "
116                                              + "Successfully deleted: %s. Failed to delete: %s.",
117                                              maxRunTime, success.get(), failure.get()));
118                 return;
119             }
120             Duration apiAge = Duration.between(api.createdDate(), Instant.now());
121             if (api.name().startsWith(NAME_PREFIX) && apiAge.compareTo(maxApiAge) > 0) {
122                 DELETE_RATE_LIMITER.getValue().acquire();
123                 try {
124                     apiGateway.deleteRestApi(r -> r.restApiId(api.id()));
125                     log.info(() -> String.format("Successfully deleted REST API %s (%s) which was %s days old.",
126                                                  api.name(), api.id(), apiAge.toDays()));
127                     success.incrementAndGet();
128                 } catch (Exception e) {
129                     log.error(() -> String.format("Failed to delete REST API %s (%s) which is %s days old.",
130                                                   api.name(), api.id(), apiAge.toDays()), e);
131                     failure.incrementAndGet();
132                 }
133             }
134         }
135         log.info(() -> String.format("Finished searching for stale REST APIs. Successfully deleted: %s. Failed to delete: %s.",
136                                      success.get(), failure.get()));
137     }
138 
139     @Test
testUpdateRetrieveRestApi()140     public void testUpdateRetrieveRestApi() {
141         PatchOperation patch = PatchOperation.builder().op(Op.REPLACE)
142                                                    .path("/description").value("updatedDesc").build();
143         apiGateway.updateRestApi(UpdateRestApiRequest.builder().restApiId(restApiId)
144                                                            .patchOperations(patch).build());
145 
146         GetRestApiResponse getRestApiResult = apiGateway
147                 .getRestApi(GetRestApiRequest.builder().restApiId(restApiId).build());
148 
149         Assert.assertNotNull(getRestApiResult);
150         Assert.assertNotNull(getRestApiResult.description());
151         Assert.assertNotNull(getRestApiResult.id());
152         Assert.assertNotNull(getRestApiResult.name());
153         Assert.assertNotNull(getRestApiResult.createdDate());
154         Assert.assertEquals(getRestApiResult.name(), NAME);
155         Assert.assertEquals(getRestApiResult.description(), "updatedDesc");
156     }
157 
158     @Test
testCreateUpdateRetrieveApiKey()159     public void testCreateUpdateRetrieveApiKey() {
160         CreateApiKeyResponse createApiKeyResult = apiGateway
161                 .createApiKey(CreateApiKeyRequest.builder().name(NAME)
162                                                        .description(DESCRIPTION).build());
163 
164         Assert.assertNotNull(createApiKeyResult);
165         Assert.assertNotNull(createApiKeyResult.description());
166         Assert.assertNotNull(createApiKeyResult.id());
167         Assert.assertNotNull(createApiKeyResult.name());
168         Assert.assertNotNull(createApiKeyResult.createdDate());
169         Assert.assertNotNull(createApiKeyResult.enabled());
170         Assert.assertNotNull(createApiKeyResult.lastUpdatedDate());
171         Assert.assertNotNull(createApiKeyResult.stageKeys());
172 
173         String apiKeyId = createApiKeyResult.id();
174         Assert.assertEquals(createApiKeyResult.name(), NAME);
175         Assert.assertEquals(createApiKeyResult.description(), DESCRIPTION);
176 
177         PatchOperation patch = PatchOperation.builder().op(Op.REPLACE)
178                                                    .path("/description").value("updatedDesc").build();
179         apiGateway.updateApiKey(UpdateApiKeyRequest.builder().apiKey(apiKeyId)
180                                                          .patchOperations(patch).build());
181 
182         GetApiKeyResponse getApiKeyResult = apiGateway
183                 .getApiKey(GetApiKeyRequest.builder().apiKey(apiKeyId).build());
184 
185         Assert.assertNotNull(getApiKeyResult);
186         Assert.assertNotNull(getApiKeyResult.description());
187         Assert.assertNotNull(getApiKeyResult.id());
188         Assert.assertNotNull(getApiKeyResult.name());
189         Assert.assertNotNull(getApiKeyResult.createdDate());
190         Assert.assertNotNull(getApiKeyResult.enabled());
191         Assert.assertNotNull(getApiKeyResult.lastUpdatedDate());
192         Assert.assertNotNull(getApiKeyResult.stageKeys());
193         Assert.assertEquals(getApiKeyResult.id(), apiKeyId);
194         Assert.assertEquals(getApiKeyResult.name(), NAME);
195         Assert.assertEquals(getApiKeyResult.description(), "updatedDesc");
196     }
197 
198     @Test
testResourceOperations()199     public void testResourceOperations() {
200         GetResourcesResponse resourcesResult = apiGateway
201                 .getResources(GetResourcesRequest.builder()
202                                       .restApiId(restApiId).build());
203         List<Resource> resources = resourcesResult.items();
204         Assert.assertEquals(resources.size(), 1);
205         Resource rootResource = resources.get(0);
206         Assert.assertNotNull(rootResource);
207         Assert.assertEquals(rootResource.path(), "/");
208         String rootResourceId = rootResource.id();
209 
210         CreateResourceResponse createResourceResult = apiGateway
211                 .createResource(CreateResourceRequest.builder()
212                                         .restApiId(restApiId)
213                                         .pathPart("fooPath")
214                                         .parentId(rootResourceId).build());
215         Assert.assertNotNull(createResourceResult);
216         Assert.assertNotNull(createResourceResult.id());
217         Assert.assertNotNull(createResourceResult.parentId());
218         Assert.assertNotNull(createResourceResult.path());
219         Assert.assertNotNull(createResourceResult.pathPart());
220         Assert.assertEquals(createResourceResult.pathPart(), "fooPath");
221         Assert.assertEquals(createResourceResult.parentId(), rootResourceId);
222 
223         PatchOperation patch = PatchOperation.builder().op(Op.REPLACE)
224                                                    .path("/pathPart").value("updatedPath").build();
225         apiGateway.updateResource(UpdateResourceRequest.builder()
226                                           .restApiId(restApiId)
227                                           .resourceId(createResourceResult.id())
228                                           .patchOperations(patch).build());
229 
230         GetResourceResponse getResourceResult = apiGateway
231                 .getResource(GetResourceRequest.builder()
232                                      .restApiId(restApiId)
233                                      .resourceId(createResourceResult.id()).build());
234         Assert.assertNotNull(getResourceResult);
235         Assert.assertNotNull(getResourceResult.id());
236         Assert.assertNotNull(getResourceResult.parentId());
237         Assert.assertNotNull(getResourceResult.path());
238         Assert.assertNotNull(getResourceResult.pathPart());
239         Assert.assertEquals(getResourceResult.pathPart(), "updatedPath");
240         Assert.assertEquals(getResourceResult.parentId(), rootResourceId);
241 
242         PutMethodResponse putMethodResult = apiGateway
243                 .putMethod(PutMethodRequest.builder().restApiId(restApiId)
244                                                  .resourceId(createResourceResult.id())
245                                                  .authorizationType("AWS_IAM").httpMethod("PUT").build());
246         Assert.assertNotNull(putMethodResult);
247         Assert.assertNotNull(putMethodResult.authorizationType());
248         Assert.assertNotNull(putMethodResult.apiKeyRequired());
249         Assert.assertNotNull(putMethodResult.httpMethod());
250         Assert.assertEquals(putMethodResult.authorizationType(), "AWS_IAM");
251         Assert.assertEquals(putMethodResult.httpMethod(), "PUT");
252 
253         PutIntegrationResponse putIntegrationResult = apiGateway
254                 .putIntegration(PutIntegrationRequest.builder()
255                                         .restApiId(restApiId)
256                                         .resourceId(createResourceResult.id())
257                                         .httpMethod("PUT").type(IntegrationType.MOCK)
258                                         .uri("http://foo.bar")
259                                         .integrationHttpMethod("GET").build());
260         Assert.assertNotNull(putIntegrationResult);
261         Assert.assertNotNull(putIntegrationResult.cacheNamespace());
262         Assert.assertNotNull(putIntegrationResult.type());
263         Assert.assertEquals(putIntegrationResult.type(),
264                             IntegrationType.MOCK);
265     }
266 
267     @Test(expected = NotFoundException.class)
resourceWithDotSignedCorrectly()268     public void resourceWithDotSignedCorrectly() {
269         apiGateway.createResource(r -> r.restApiId(restApiId).pathPart("fooPath").parentId("."));
270     }
271 
272     @Test(expected = NotFoundException.class)
resourceWithDoubleDotSignedCorrectly()273     public void resourceWithDoubleDotSignedCorrectly() {
274         apiGateway.createResource(r -> r.restApiId(restApiId).pathPart("fooPath").parentId(".."));
275     }
276 
277     @Test(expected = NotFoundException.class)
resourceWithEncodedCharactersSignedCorrectly()278     public void resourceWithEncodedCharactersSignedCorrectly() {
279         apiGateway.createResource(r -> r.restApiId(restApiId).pathPart("fooPath").parentId("foo/../bar"));
280     }
281 }
282