Skip to content

Commit 5d82f78

Browse files
committed
First import of changes for #142 - build is broken but working on fixes
1 parent 6cd0ab7 commit 5d82f78

File tree

12 files changed

+216
-154
lines changed

12 files changed

+216
-154
lines changed

aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/LambdaContainerHandler.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
package com.amazonaws.serverless.proxy.internal;
1414

1515

16+
import com.amazonaws.serverless.exceptions.ContainerInitializationException;
1617
import com.amazonaws.serverless.proxy.LogFormatter;
1718
import com.amazonaws.serverless.proxy.internal.servlet.ApacheCombinedServletLogFormatter;
1819
import com.amazonaws.serverless.proxy.model.ContainerConfig;
@@ -100,6 +101,8 @@ protected LambdaContainerHandler(Class<RequestType> requestClass,
100101
this.responseWriter = responseWriter;
101102
this.securityContextWriter = securityContextWriter;
102103
this.exceptionHandler = exceptionHandler;
104+
objectReader = getObjectMapper().readerFor(requestTypeClass);
105+
objectWriter = getObjectMapper().writerFor(responseTypeClass);
103106
}
104107

105108

@@ -113,6 +116,8 @@ protected LambdaContainerHandler(Class<RequestType> requestClass,
113116
protected abstract void handleRequest(ContainerRequestType containerRequest, ContainerResponseType containerResponse, Context lambdaContext)
114117
throws Exception;
115118

119+
public abstract void initialize()
120+
throws ContainerInitializationException;
116121

117122
//-------------------------------------------------------------
118123
// Methods - Public
@@ -191,16 +196,9 @@ public void proxyStream(InputStream input, OutputStream output, Context context)
191196
throws IOException {
192197

193198
try {
194-
if (objectReader == null) {
195-
objectReader = getObjectMapper().readerFor(requestTypeClass);
196-
}
197199
RequestType request = objectReader.readValue(input);
198200
ResponseType resp = proxy(request, context);
199201

200-
if (objectWriter == null) {
201-
objectWriter = getObjectMapper().writerFor(responseTypeClass);
202-
}
203-
204202
objectWriter.writeValue(output, resp);
205203
} catch (JsonParseException e) {
206204
log.error("Error while parsing request object stream", e);

aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsLambdaServletContainerHandler.java

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@ public abstract class AwsLambdaServletContainerHandler<RequestType, ResponseType
5454
//-------------------------------------------------------------
5555
// Variables - Private
5656
//-------------------------------------------------------------
57-
58-
protected ServletContext servletContext;
5957
private Logger log = LoggerFactory.getLogger(AwsLambdaServletContainerHandler.class);
58+
private FilterChainManager<AwsServletContext> filterChainManager;
59+
private boolean startupExecuted;
6060

6161
//-------------------------------------------------------------
6262
// Variables - Protected
6363
//-------------------------------------------------------------
6464
protected StartupHandler startupHandler;
65-
private FilterChainManager<AwsServletContext> filterChainManager;
65+
protected ServletContext servletContext;
6666

6767

6868
//-------------------------------------------------------------
@@ -78,6 +78,8 @@ protected AwsLambdaServletContainerHandler(Class<RequestType> requestTypeClass,
7878
super(requestTypeClass, responseTypeClass, requestReader, responseWriter, securityContextWriter, exceptionHandler);
7979
// set the default log formatter for servlet implementations
8080
setLogFormatter(new ApacheCombinedServletLogFormatter<>());
81+
setServletContext(new AwsServletContext(this));
82+
startupExecuted = false;
8183
}
8284

8385
//-------------------------------------------------------------
@@ -154,17 +156,7 @@ private HttpServletResponse getServletResponse(ContainerResponseType resp) {
154156
*/
155157
public void onStartup(final StartupHandler h) {
156158
startupHandler = h;
157-
}
158-
159-
@Override
160-
protected void handleRequest(ContainerRequestType containerRequest, ContainerResponseType containerResponse, Context lambdaContext)
161-
throws Exception {
162-
// The servlet context should not be linked to a specific request object, only to the Lambda
163-
// context so we only set it once.
164-
// TODO: In the future, if we decide to support multiple servlets/contexts in an instance we only need to modify this method
165-
if (getServletContext() == null) {
166-
setServletContext(new AwsServletContext(this));
167-
}
159+
startupHandler.onStartup(getServletContext());
168160
}
169161

170162

aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/JerseyLambdaContainerHandler.java

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,8 @@ public class JerseyLambdaContainerHandler<RequestType, ResponseType> extends Aws
7979
//-------------------------------------------------------------
8080

8181
private JerseyHandlerFilter jerseyFilter;
82-
83-
// tracker for the first request
8482
private boolean initialized;
8583

86-
8784
//-------------------------------------------------------------
8885
// Methods - Public - Static
8986
//-------------------------------------------------------------
@@ -98,13 +95,15 @@ public class JerseyLambdaContainerHandler<RequestType, ResponseType> extends Aws
9895
* @return A <code>JerseyLambdaContainerHandler</code> object
9996
*/
10097
public static JerseyLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> getAwsProxyHandler(Application jaxRsApplication) {
101-
return new JerseyLambdaContainerHandler<>(AwsProxyRequest.class,
102-
AwsProxyResponse.class,
103-
new AwsProxyHttpServletRequestReader(),
104-
new AwsProxyHttpServletResponseWriter(),
105-
new AwsProxySecurityContextWriter(),
106-
new AwsProxyExceptionHandler(),
107-
jaxRsApplication);
98+
JerseyLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> newHandler = new JerseyLambdaContainerHandler<>(AwsProxyRequest.class,
99+
AwsProxyResponse.class,
100+
new AwsProxyHttpServletRequestReader(),
101+
new AwsProxyHttpServletResponseWriter(),
102+
new AwsProxySecurityContextWriter(),
103+
new AwsProxyExceptionHandler(),
104+
jaxRsApplication);
105+
newHandler.initialize();
106+
return newHandler;
108107
}
109108

110109

@@ -133,8 +132,7 @@ public JerseyLambdaContainerHandler(Class<RequestType> requestTypeClass,
133132

134133
super(requestTypeClass, responseTypeClass, requestReader, responseWriter, securityContextWriter, exceptionHandler);
135134
Timer.start("JERSEY_CONTAINER_CONSTRUCTOR");
136-
this.initialized = false;
137-
135+
initialized = false;
138136
if (jaxRsApplication instanceof ResourceConfig) {
139137
((ResourceConfig)jaxRsApplication).register(new AbstractBinder() {
140138
@Override
@@ -162,29 +160,28 @@ protected AwsHttpServletResponse getContainerResponse(AwsProxyHttpServletRequest
162160
@Override
163161
protected void handleRequest(AwsProxyHttpServletRequest httpServletRequest, AwsHttpServletResponse httpServletResponse, Context lambdaContext)
164162
throws Exception {
165-
166-
Timer.start("JERSEY_HANDLE_REQUEST");
167-
// this method of the AwsLambdaServletContainerHandler sets the request context
168-
super.handleRequest(httpServletRequest, httpServletResponse, lambdaContext);
169-
163+
// we retain the initialized property for backward compatibility
170164
if (!initialized) {
171-
Timer.start("JERSEY_COLD_START_INIT");
172-
// call the onStartup event if set to give developers a chance to set filters in the context
173-
if (startupHandler != null) {
174-
startupHandler.onStartup(getServletContext());
175-
}
176-
177-
// manually add the spark filter to the chain. This should the last one and match all uris
178-
FilterRegistration.Dynamic jerseyFilterReg = getServletContext().addFilter("JerseyFilter", jerseyFilter);
179-
jerseyFilterReg.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
180-
181-
initialized = true;
182-
Timer.stop("JERSEY_COLD_START_INIT");
165+
initialize();
183166
}
167+
Timer.start("JERSEY_HANDLE_REQUEST");
184168

185169
httpServletRequest.setServletContext(getServletContext());
186170

187171
doFilter(httpServletRequest, httpServletResponse, null);
188172
Timer.stop("JERSEY_HANDLE_REQUEST");
189173
}
174+
175+
176+
@Override
177+
public void initialize() {
178+
Timer.start("JERSEY_COLD_START_INIT");
179+
180+
// manually add the spark filter to the chain. This should the last one and match all uris
181+
FilterRegistration.Dynamic jerseyFilterReg = getServletContext().addFilter("JerseyFilter", jerseyFilter);
182+
jerseyFilterReg.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
183+
184+
Timer.stop("JERSEY_COLD_START_INIT");
185+
initialized = true;
186+
}
190187
}

aws-serverless-java-container-spark/src/main/java/com/amazonaws/serverless/proxy/spark/SparkLambdaContainerHandler.java

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,18 @@ public class SparkLambdaContainerHandler<RequestType, ResponseType>
106106
*/
107107
public static SparkLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> getAwsProxyHandler()
108108
throws ContainerInitializationException {
109-
return new SparkLambdaContainerHandler<>(AwsProxyRequest.class,
110-
AwsProxyResponse.class,
111-
new AwsProxyHttpServletRequestReader(),
112-
new AwsProxyHttpServletResponseWriter(),
113-
new AwsProxySecurityContextWriter(),
114-
new AwsProxyExceptionHandler(),
115-
new LambdaEmbeddedServerFactory());
109+
SparkLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> newHandler = new SparkLambdaContainerHandler<>(AwsProxyRequest.class,
110+
AwsProxyResponse.class,
111+
new AwsProxyHttpServletRequestReader(),
112+
new AwsProxyHttpServletResponseWriter(),
113+
new AwsProxySecurityContextWriter(),
114+
new AwsProxyExceptionHandler(),
115+
new LambdaEmbeddedServerFactory());
116+
117+
// For Spark we cannot call intialize here. It needs to be called manually after the routes are set
118+
//newHandler.initialize();
119+
120+
return newHandler;
116121
}
117122

118123
//-------------------------------------------------------------
@@ -180,36 +185,36 @@ protected AwsHttpServletResponse getContainerResponse(AwsProxyHttpServletRequest
180185
protected void handleRequest(AwsProxyHttpServletRequest httpServletRequest, AwsHttpServletResponse httpServletResponse, Context lambdaContext)
181186
throws Exception {
182187
Timer.start("SPARK_HANDLE_REQUEST");
183-
// this method of the AwsLambdaServletContainerHandler sets the request context
184-
super.handleRequest(httpServletRequest, httpServletResponse, lambdaContext);
185188

186189
if (embeddedServer == null) {
187-
Timer.start("SPARK_COLD_START");
188-
log.debug("First request, getting new server instance");
190+
initialize();
191+
}
189192

190-
// trying to call init in case the embedded server had not been initialized.
191-
Spark.init();
193+
httpServletRequest.setServletContext(getServletContext());
192194

193-
// adding this call to make sure that the framework is fully initialized. This should address a race
194-
// condition and solve GitHub issue #71.
195-
Spark.awaitInitialization();
195+
doFilter(httpServletRequest, httpServletResponse, null);
196+
Timer.stop("SPARK_HANDLE_REQUEST");
197+
}
196198

197-
embeddedServer = lambdaServerFactory.getServerInstance();
198199

199-
// call the onStartup event if set to give developers a chance to set filters in the context
200-
if (startupHandler != null) {
201-
startupHandler.onStartup(getServletContext());
202-
}
200+
@Override
201+
public void initialize()
202+
throws ContainerInitializationException {
203+
Timer.start("SPARK_COLD_START");
204+
log.debug("First request, getting new server instance");
203205

204-
// manually add the spark filter to the chain. This should the last one and match all uris
205-
FilterRegistration.Dynamic sparkRegistration = getServletContext().addFilter("SparkFilter", embeddedServer.getSparkFilter());
206-
sparkRegistration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
207-
Timer.stop("SPARK_COLD_START");
208-
}
206+
// trying to call init in case the embedded server had not been initialized.
207+
Spark.init();
209208

210-
httpServletRequest.setServletContext(getServletContext());
209+
// adding this call to make sure that the framework is fully initialized. This should address a race
210+
// condition and solve GitHub issue #71.
211+
Spark.awaitInitialization();
211212

212-
doFilter(httpServletRequest, httpServletResponse, null);
213-
Timer.stop("SPARK_HANDLE_REQUEST");
213+
embeddedServer = lambdaServerFactory.getServerInstance();
214+
215+
// manually add the spark filter to the chain. This should the last one and match all uris
216+
FilterRegistration.Dynamic sparkRegistration = getServletContext().addFilter("SparkFilter", embeddedServer.getSparkFilter());
217+
sparkRegistration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
218+
Timer.stop("SPARK_COLD_START");
214219
}
215220
}

aws-serverless-java-container-spring/src/main/java/com/amazonaws/serverless/proxy/spring/LambdaSpringApplicationInitializer.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import org.springframework.context.ApplicationListener;
2222
import org.springframework.context.event.ContextRefreshedEvent;
2323
import org.springframework.context.event.ContextStoppedEvent;
24+
import org.springframework.context.event.GenericApplicationListenerAdapter;
25+
import org.springframework.context.support.AbstractRefreshableApplicationContext;
2426
import org.springframework.web.WebApplicationInitializer;
2527
import org.springframework.web.context.ConfigurableWebApplicationContext;
2628
import org.springframework.web.context.ContextLoaderListener;
@@ -125,6 +127,13 @@ public List<String> getSpringProfiles() {
125127

126128
public void setSpringProfiles(List<String> springProfiles) {
127129
this.springProfiles = new ArrayList<>(springProfiles);
130+
applicationContext.stop();
131+
applicationContext.close();
132+
applicationContext.getEnvironment().setActiveProfiles(springProfiles.toArray(new String[0]));
133+
//applicationContext.start();
134+
applicationContext.refresh();
135+
136+
//dispatcherServlet.refresh();
128137
}
129138

130139
@Override
@@ -135,20 +144,18 @@ public void onStartup(ServletContext servletContext) throws ServletException {
135144
}
136145
applicationContext.setServletContext(servletContext);
137146

138-
139147
DefaultDispatcherConfig dispatcherConfig = new DefaultDispatcherConfig(servletContext);
140148
applicationContext.setServletConfig(dispatcherConfig);
141149

142150
// Configure the listener for the request handled events. All we do here is release the latch
143-
applicationContext.addApplicationListener(new ApplicationListener<ServletRequestHandledEvent>() {
144-
@Override
145-
public void onApplicationEvent(ServletRequestHandledEvent servletRequestHandledEvent) {
146-
try {
151+
applicationContext.addApplicationListener((ApplicationListener<ServletRequestHandledEvent>) servletRequestHandledEvent -> {
152+
try {
153+
if (currentResponse != null) {
147154
currentResponse.flushBuffer();
148-
} catch (IOException e) {
149-
log.error("Could not flush response buffer", e);
150-
throw new RuntimeException("Could not flush response buffer", e);
151155
}
156+
} catch (IOException e) {
157+
log.error("Could not flush response buffer", e);
158+
throw new RuntimeException("Could not flush response buffer", e);
152159
}
153160
});
154161

0 commit comments

Comments
 (0)