-
Notifications
You must be signed in to change notification settings - Fork 574
Expand file tree
/
Copy pathSpringDelegatingLambdaContainerHandler.java
More file actions
103 lines (89 loc) · 4.44 KB
/
SpringDelegatingLambdaContainerHandler.java
File metadata and controls
103 lines (89 loc) · 4.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package com.amazonaws.serverless.proxy.spring;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.amazonaws.serverless.exceptions.ContainerInitializationException;
import com.amazonaws.serverless.proxy.AsyncInitializationWrapper;
import com.amazonaws.serverless.proxy.InitializationTypeHelper;
import com.amazonaws.serverless.proxy.internal.InitializableLambdaContainerHandler;
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
import org.springframework.cloud.function.serverless.web.FunctionClassUtils;
import org.springframework.cloud.function.serverless.web.ServerlessMVC;
import com.amazonaws.serverless.proxy.internal.servlet.AwsProxyHttpServletResponseWriter;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import tools.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
/*
* Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
* with the License. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
/**
* An implementation of {@link RequestStreamHandler} which delegates to
* Spring Cloud Function serverless web module managed by Spring team.
*
* It requires no sub-classing from the user other then being identified as "Handler".
* The configuration class(es) should be provided via MAIN_CLASS environment variable.
*
*/
public class SpringDelegatingLambdaContainerHandler implements RequestStreamHandler {
private final SpringDelegatingInitHandler initHandler;
private final ObjectMapper mapper;
private final AwsProxyHttpServletResponseWriter responseWriter;
private final AsyncInitializationWrapper asyncInitWrapper;
public SpringDelegatingLambdaContainerHandler() throws ContainerInitializationException {
this(new Class[] {FunctionClassUtils.getStartClass()});
}
public SpringDelegatingLambdaContainerHandler(final Class<?>... startupClasses) throws ContainerInitializationException {
this.initHandler = new SpringDelegatingInitHandler(startupClasses);
if (InitializationTypeHelper.isAsyncInitializationDisabled()) {
initHandler.initialize();
this.asyncInitWrapper = null;
} else {
this.asyncInitWrapper = new AsyncInitializationWrapper();
asyncInitWrapper.start(initHandler);
}
this.mapper = new ObjectMapper();
this.responseWriter = new AwsProxyHttpServletResponseWriter();
}
@Override
public void handleRequest(InputStream input, OutputStream output, Context lambdaContext) throws IOException {
// Wait for async initialization to complete if needed to avoid race condition
if (asyncInitWrapper != null) {
try {
asyncInitWrapper.getInitializationLatch().await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IOException("Initialization interrupted", e);
}
}
ServerlessMVC mvc = initHandler.getMvc();
HttpServletRequest httpServletRequest = AwsSpringHttpProcessingUtils
.generateHttpServletRequest(input, lambdaContext, mvc.getServletContext(), this.mapper);
AwsProxyResponse awsProxyResponse = AwsSpringHttpProcessingUtils.processRequest(httpServletRequest, mvc, responseWriter);
this.mapper.writeValue(output, awsProxyResponse);
}
private static final class SpringDelegatingInitHandler implements InitializableLambdaContainerHandler {
private ServerlessMVC mvc;
private final Class<?>[] startupClasses;
public SpringDelegatingInitHandler(final Class<?>... startupClasses) {
this.startupClasses = startupClasses;
}
@Override
public void initialize() throws ContainerInitializationException {
this.mvc = ServerlessMVC.INSTANCE(this.startupClasses);
this.mvc.waitForContext();
}
public ServerlessMVC getMvc() {
return this.mvc;
}
}
}