Skip to content

Commit a4b9ab0

Browse files
committed
Lots of new integration tests for springboot2 support
1 parent e87a86e commit a4b9ab0

File tree

22 files changed

+386
-35
lines changed

22 files changed

+386
-35
lines changed

aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/SpringBootAppTest.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import com.amazonaws.serverless.proxy.internal.testutils.MockLambdaContext;
77
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
88
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
9+
import com.amazonaws.serverless.proxy.model.Headers;
10+
import com.amazonaws.serverless.proxy.model.MultiValuedTreeMap;
911
import com.amazonaws.serverless.proxy.spring.echoapp.model.SingleValueModel;
1012
import com.amazonaws.serverless.proxy.spring.springbootapp.LambdaHandler;
1113
import com.amazonaws.serverless.proxy.spring.springbootapp.TestController;
@@ -17,6 +19,8 @@
1719
import javax.ws.rs.core.HttpHeaders;
1820
import java.io.IOException;
1921

22+
import static com.amazonaws.serverless.proxy.spring.springbootapp.TestController.CUSTOM_HEADER_NAME;
23+
import static com.amazonaws.serverless.proxy.spring.springbootapp.TestController.CUSTOM_QS_NAME;
2024
import static org.junit.Assert.*;
2125

2226

@@ -34,6 +38,54 @@ public void testMethod_springSecurity_doesNotThrowException() {
3438
validateSingleValueModel(resp, TestController.TEST_VALUE);
3539
}
3640

41+
@Test
42+
public void testMethod_testRequestFromString_doesNotThrowNpe() throws IOException {
43+
AwsProxyRequest req = new AwsProxyRequestBuilder().fromJsonString("{\n" +
44+
" \"resource\": \"/missing-params\",\n" +
45+
" \"path\": \"/missing-params\",\n" +
46+
" \"httpMethod\": \"GET\",\n" +
47+
" \"headers\": null,\n" +
48+
" \"multiValueHeaders\": null,\n" +
49+
" \"queryStringParameters\": null,\n" +
50+
" \"multiValueQueryStringParameters\": null,\n" +
51+
" \"pathParameters\": null,\n" +
52+
" \"stageVariables\": null,\n" +
53+
" \"requestContext\": {\n" +
54+
" \"resourcePath\": \"/path/resource\",\n" +
55+
" \"httpMethod\": \"POST\",\n" +
56+
" \"path\": \"//path/resource\",\n" +
57+
" \"accountId\": \"accountIdNumber\",\n" +
58+
" \"protocol\": \"HTTP/1.1\",\n" +
59+
" \"stage\": \"test-invoke-stage\",\n" +
60+
" \"domainPrefix\": \"testPrefix\",\n" +
61+
" \"identity\": {\n" +
62+
" \"cognitoIdentityPoolId\": null,\n" +
63+
" \"cognitoIdentityId\": null,\n" +
64+
" \"apiKey\": \"test-invoke-api-key\",\n" +
65+
" \"principalOrgId\": null,\n" +
66+
" \"cognitoAuthenticationType\": null,\n" +
67+
" \"userArn\": \"actual arn\",\n" +
68+
" \"apiKeyId\": \"test-invoke-api-key-id\"\n" +
69+
" }\n" +
70+
" },\n" +
71+
" \"body\": \"{ \\\"Key1\\\": \\\"Value1\\\", \\\"Key2\\\": \\\"Value2\\\", \\\"Key3\\\": \\\"Vaue3\\\" }\",\n" +
72+
" \"isBase64Encoded\": \"false\"\n" +
73+
"}").build();
74+
75+
AwsProxyResponse resp = handler.handleRequest(req, context);
76+
assertNotNull(resp);
77+
// Spring identifies the missing header
78+
assertEquals(400, resp.getStatusCode());
79+
req.setMultiValueHeaders(new Headers());
80+
req.getMultiValueHeaders().add(CUSTOM_HEADER_NAME, "val");
81+
resp = handler.handleRequest(req, context);
82+
assertEquals(400, resp.getStatusCode());
83+
req.setMultiValueQueryStringParameters(new MultiValuedTreeMap<>());
84+
req.getMultiValueQueryStringParameters().add(CUSTOM_QS_NAME, "val");
85+
resp = handler.handleRequest(req, context);
86+
assertEquals(200, resp.getStatusCode());
87+
}
88+
3789
@Test
3890
public void defaultError_requestForward_springBootForwardsToDefaultErrorPage() {
3991
AwsProxyRequest req = new AwsProxyRequestBuilder("/test2", "GET").build();

aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/echoapp/EchoSpringAppConfig.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
import com.amazonaws.serverless.exceptions.ContainerInitializationException;
44
import com.amazonaws.serverless.proxy.AwsProxyExceptionHandler;
55
import com.amazonaws.serverless.proxy.AwsProxySecurityContextWriter;
6+
import com.amazonaws.serverless.proxy.InitializationWrapper;
67
import com.amazonaws.serverless.proxy.internal.servlet.AwsProxyHttpServletRequestReader;
78
import com.amazonaws.serverless.proxy.internal.servlet.AwsProxyHttpServletResponseWriter;
89
import com.amazonaws.serverless.proxy.internal.servlet.AwsServletRegistration;
910
import com.amazonaws.serverless.proxy.internal.testutils.MockLambdaContext;
1011
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
1112
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
1213
import com.amazonaws.serverless.proxy.spring.SpringLambdaContainerHandler;
14+
import com.amazonaws.serverless.proxy.spring.SpringProxyHandlerBuilder;
1315
import com.fasterxml.jackson.databind.ObjectMapper;
1416
import org.springframework.beans.factory.annotation.Autowired;
1517
import org.springframework.context.annotation.Bean;
@@ -37,16 +39,11 @@ public class EchoSpringAppConfig {
3739

3840
@Bean
3941
public SpringLambdaContainerHandler springLambdaContainerHandler() throws ContainerInitializationException {
40-
SpringLambdaContainerHandler handler = new SpringLambdaContainerHandler<>(
41-
AwsProxyRequest.class,
42-
AwsProxyResponse.class,
43-
new AwsProxyHttpServletRequestReader(),
44-
new AwsProxyHttpServletResponseWriter(),
45-
new AwsProxySecurityContextWriter(),
46-
new AwsProxyExceptionHandler(),
47-
applicationContext);
48-
handler.setRefreshContext(false);
49-
handler.initialize();
42+
SpringLambdaContainerHandler handler = new SpringProxyHandlerBuilder()
43+
.defaultProxy()
44+
.initializationWrapper(new InitializationWrapper())
45+
.springApplicationContext(applicationContext)
46+
.buildAndInitialize();
5047
handler.onStartup(c -> {
5148
FilterRegistration.Dynamic registration = c.addFilter("UnauthenticatedFilter", UnauthenticatedFilter.class);
5249
// update the registration to map to a path

aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/springbootapp/TestController.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@
77
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
88
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
99
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
10-
import org.springframework.web.bind.annotation.PathVariable;
11-
import org.springframework.web.bind.annotation.RequestMapping;
12-
import org.springframework.web.bind.annotation.RequestMethod;
13-
import org.springframework.web.bind.annotation.RequestParam;
14-
import org.springframework.web.bind.annotation.RestController;
10+
import org.springframework.web.bind.annotation.*;
1511
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
1612
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
1713
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@@ -27,6 +23,8 @@
2723
public class TestController extends WebSecurityConfigurerAdapter {
2824
public static final String TEST_VALUE = "test";
2925
public static final String UTF8_TEST_STRING = "health心跳测试完成。可正常使用";
26+
public static final String CUSTOM_HEADER_NAME = "X-Custom-Header";
27+
public static final String CUSTOM_QS_NAME = "qs";
3028

3129
// workaround to address the most annoying issue in the world: https://blog.georgovassilis.com/2015/10/29/spring-mvc-rest-controller-says-406-when-emails-are-part-url-path/
3230
@Configuration
@@ -49,6 +47,14 @@ public SingleValueModel testGet() {
4947
return value;
5048
}
5149

50+
@RequestMapping(path = "/missing-params", method = {RequestMethod.GET})
51+
public Map<String, Boolean> testInvalidParameters(@RequestHeader(CUSTOM_HEADER_NAME) String h1, @RequestParam(CUSTOM_QS_NAME) String qsValue) {
52+
Map<String, Boolean> output = new HashMap<>();
53+
output.put("header", h1 == null);
54+
output.put("queryString", qsValue == null);
55+
return output;
56+
}
57+
5258
@RequestMapping(path = "/test/{domain}", method = { RequestMethod.GET})
5359
public SingleValueModel testDomainInPath(@PathVariable("domain") String domainName) {
5460
SingleValueModel value = new SingleValueModel();

aws-serverless-java-container-springboot2/pom.xml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
<properties>
2020
<spring.version>5.1.9.RELEASE</spring.version>
21+
<springsecurity.version>5.1.6.RELEASE</springsecurity.version>
2122
<springboot.version>2.1.8.RELEASE</springboot.version>
2223

2324
<maven.compiler.source>1.8</maven.compiler.source>
@@ -50,7 +51,24 @@
5051
<version>${springboot.version}</version>
5152
<optional>true</optional>
5253
</dependency>
53-
54+
<dependency>
55+
<groupId>org.springframework.security</groupId>
56+
<artifactId>spring-security-config</artifactId>
57+
<version>${springsecurity.version}</version>
58+
<scope>test</scope>
59+
</dependency>
60+
<dependency>
61+
<groupId>org.springframework.security</groupId>
62+
<artifactId>spring-security-web</artifactId>
63+
<version>${springsecurity.version}</version>
64+
<scope>test</scope>
65+
</dependency>
66+
<dependency>
67+
<groupId>org.jetbrains</groupId>
68+
<artifactId>annotations</artifactId>
69+
<version>17.0.0</version>
70+
<scope>compile</scope>
71+
</dependency>
5472
</dependencies>
5573

5674
<build>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.amazonaws.serverless.proxy.spring;
2+
3+
import com.amazonaws.serverless.proxy.internal.LambdaContainerHandler;
4+
import com.amazonaws.serverless.proxy.internal.testutils.AwsProxyRequestBuilder;
5+
import com.amazonaws.serverless.proxy.internal.testutils.MockLambdaContext;
6+
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
7+
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
8+
import com.amazonaws.serverless.proxy.spring.securityapp.LambdaHandler;
9+
import com.amazonaws.serverless.proxy.spring.securityapp.MessageController;
10+
import com.amazonaws.serverless.proxy.spring.securityapp.SecurityConfig;
11+
import com.fasterxml.jackson.core.JsonProcessingException;
12+
import org.junit.Test;
13+
14+
import javax.ws.rs.core.HttpHeaders;
15+
import javax.ws.rs.core.MediaType;
16+
17+
import static org.junit.Assert.assertEquals;
18+
import static org.junit.Assert.assertTrue;
19+
20+
public class SecurityAppTest {
21+
22+
LambdaHandler handler = new LambdaHandler();
23+
MockLambdaContext lambdaContext = new MockLambdaContext();
24+
25+
public SecurityAppTest() {
26+
System.setProperty("logging.level.root", "DEBUG");
27+
}
28+
29+
@Test
30+
public void helloRequest_withAuth_respondsWithSingleMessage() {
31+
AwsProxyRequest req = new AwsProxyRequestBuilder("/hello", "GET").build();
32+
AwsProxyResponse resp = handler.handleRequest(req, lambdaContext);
33+
assertEquals(401, resp.getStatusCode());
34+
assertTrue(resp.getMultiValueHeaders().containsKey(HttpHeaders.WWW_AUTHENTICATE));
35+
req = new AwsProxyRequestBuilder("/hello", "GET")
36+
.basicAuth(SecurityConfig.USERNAME, SecurityConfig.PASSWORD)
37+
.header(HttpHeaders.ACCEPT, MediaType.TEXT_PLAIN)
38+
.build();
39+
resp = handler.handleRequest(req, lambdaContext);
40+
assertEquals(200, resp.getStatusCode());
41+
}
42+
43+
public void helloRequest_withoutAuith_respondsWithError() {
44+
45+
}
46+
}

aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/serverless/proxy/spring/ServletAppTest.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
package com.amazonaws.servlerss.proxy.spring;
1+
package com.amazonaws.serverless.proxy.spring;
22

33
import com.amazonaws.serverless.proxy.internal.testutils.AwsProxyRequestBuilder;
44
import com.amazonaws.serverless.proxy.internal.testutils.MockLambdaContext;
55
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
66
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
7-
import com.amazonaws.servlerss.proxy.spring.servletapp.LambdaHandler;
8-
import com.amazonaws.servlerss.proxy.spring.servletapp.MessageController;
7+
import com.amazonaws.serverless.proxy.spring.servletapp.LambdaHandler;
8+
import com.amazonaws.serverless.proxy.spring.servletapp.MessageController;
9+
import org.junit.Assert;
910
import org.junit.Test;
1011

1112
import static org.junit.Assert.assertEquals;
@@ -19,6 +20,6 @@ public class ServletAppTest {
1920
public void helloRequest_respondsWithSingleMessage() {
2021
AwsProxyRequest req = new AwsProxyRequestBuilder("/hello", "GET").build();
2122
AwsProxyResponse resp = handler.handleRequest(req, lambdaContext);
22-
assertEquals(MessageController.HELLO_MESSAGE, resp.getBody());
23+
Assert.assertEquals(MessageController.HELLO_MESSAGE, resp.getBody());
2324
}
2425
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.amazonaws.serverless.proxy.spring;
2+
3+
import com.amazonaws.serverless.proxy.internal.testutils.AwsProxyRequestBuilder;
4+
import com.amazonaws.serverless.proxy.internal.testutils.MockLambdaContext;
5+
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
6+
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
7+
import com.amazonaws.serverless.proxy.spring.slowapp.LambdaHandler;
8+
import com.amazonaws.serverless.proxy.spring.slowapp.MessageController;
9+
import com.amazonaws.serverless.proxy.spring.slowapp.SlowTestApplication;
10+
import org.junit.Assert;
11+
import org.junit.Test;
12+
13+
import java.time.Instant;
14+
15+
import static org.junit.Assert.assertEquals;
16+
import static org.junit.Assert.assertTrue;
17+
18+
public class SlowAppTest {
19+
20+
@Test
21+
public void slowAppInit_continuesInBackgroundThread_returnsCorrect() {
22+
LambdaHandler slowApp = new LambdaHandler();
23+
System.out.println("Start time: " + slowApp.getConstructorTime());
24+
assertTrue(slowApp.getConstructorTime() < 10_000);
25+
AwsProxyRequest req = new AwsProxyRequestBuilder("/hello", "GET").build();
26+
long startRequestTime = Instant.now().toEpochMilli();
27+
AwsProxyResponse resp = slowApp.handleRequest(req, new MockLambdaContext());
28+
long endRequestTime = Instant.now().toEpochMilli();
29+
assertTrue(endRequestTime - startRequestTime > SlowTestApplication.SlowDownInit.INIT_SLEEP_TIME_MS - 10_000);
30+
assertEquals(200, resp.getStatusCode());
31+
Assert.assertEquals(MessageController.HELLO_MESSAGE, resp.getBody());
32+
}
33+
}

aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/serverless/proxy/spring/WebFluxAppTest.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
package com.amazonaws.servlerss.proxy.spring;
1+
package com.amazonaws.serverless.proxy.spring;
22

33
import com.amazonaws.serverless.proxy.internal.testutils.AwsProxyRequestBuilder;
44
import com.amazonaws.serverless.proxy.internal.testutils.MockLambdaContext;
55
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
66
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
7-
import com.amazonaws.servlerss.proxy.spring.webfluxapp.LambdaHandler;
8-
import com.amazonaws.servlerss.proxy.spring.webfluxapp.MessageController;
7+
import com.amazonaws.serverless.proxy.spring.webfluxapp.LambdaHandler;
8+
import com.amazonaws.serverless.proxy.spring.webfluxapp.MessageController;
9+
import org.junit.Assert;
910
import org.junit.Test;
1011

1112
import static org.junit.Assert.assertEquals;
@@ -19,7 +20,7 @@ public class WebFluxAppTest {
1920
public void helloRequest_respondsWithSingleMessage() {
2021
AwsProxyRequest req = new AwsProxyRequestBuilder("/single", "GET").build();
2122
AwsProxyResponse resp = handler.handleRequest(req, lambdaContext);
22-
assertEquals(MessageController.MESSAGE, resp.getBody());
23+
Assert.assertEquals(MessageController.MESSAGE, resp.getBody());
2324
}
2425

2526
@Test

aws-serverless-java-container-springboot2/src/test/java/com/amazonaws/serverless/proxy/spring/embedded/ServerlessServletEmbeddedServerFactoryTest.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
package com.amazonaws.servlerss.proxy.spring.embedded;
1+
package com.amazonaws.serverless.proxy.spring.embedded;
22

33
import com.amazonaws.serverless.exceptions.ContainerInitializationException;
44
import com.amazonaws.serverless.proxy.AwsProxyExceptionHandler;
55
import com.amazonaws.serverless.proxy.AwsProxySecurityContextWriter;
6-
import com.amazonaws.serverless.proxy.SyncInitializationWrapper;
6+
import com.amazonaws.serverless.proxy.InitializationWrapper;
77
import com.amazonaws.serverless.proxy.internal.servlet.AwsProxyHttpServletRequestReader;
88
import com.amazonaws.serverless.proxy.internal.servlet.AwsProxyHttpServletResponseWriter;
99
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
1010
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
1111
import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler;
12-
import com.amazonaws.serverless.proxy.spring.embedded.ServerlessServletEmbeddedServerFactory;
1312
import org.junit.Test;
1413
import org.springframework.boot.web.servlet.ServletContextInitializer;
1514

@@ -19,15 +18,15 @@
1918
import static org.junit.Assert.fail;
2019

2120
public class ServerlessServletEmbeddedServerFactoryTest {
22-
private SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler = new SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse>(
21+
private SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler = new SpringBootLambdaContainerHandler<>(
2322
AwsProxyRequest.class,
2423
AwsProxyResponse.class,
2524
new AwsProxyHttpServletRequestReader(),
2625
new AwsProxyHttpServletResponseWriter(),
2726
new AwsProxySecurityContextWriter(),
2827
new AwsProxyExceptionHandler(),
2928
null,
30-
new SyncInitializationWrapper()
29+
new InitializationWrapper()
3130
);
3231

3332
public ServerlessServletEmbeddedServerFactoryTest() throws ContainerInitializationException {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.amazonaws.serverless.proxy.spring.securityapp;
2+
3+
import com.amazonaws.serverless.exceptions.ContainerInitializationException;
4+
import com.amazonaws.serverless.proxy.internal.servlet.AwsProxyHttpServletRequest;
5+
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
6+
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
7+
import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler;
8+
import com.amazonaws.services.lambda.runtime.Context;
9+
import com.amazonaws.services.lambda.runtime.RequestHandler;
10+
11+
public class LambdaHandler implements RequestHandler<AwsProxyRequest, AwsProxyResponse> {
12+
private static SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
13+
14+
static {
15+
try {
16+
handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(ServletApplication.class);
17+
} catch (ContainerInitializationException e) {
18+
e.printStackTrace();
19+
}
20+
}
21+
22+
@Override
23+
public AwsProxyResponse handleRequest(AwsProxyRequest awsProxyRequest, Context context) {
24+
return handler.proxy(awsProxyRequest, context);
25+
}
26+
}

0 commit comments

Comments
 (0)