Skip to content

Commit ea7a05c

Browse files
Oblioolegz
authored andcommitted
additional fixes to address null servletContext
Signed-off-by: Oblio <oblio.leitch@vermont.gov> Resolves #1335
1 parent a2ed41c commit ea7a05c

File tree

2 files changed

+38
-16
lines changed
  • spring-cloud-function-adapters
    • spring-cloud-function-adapter-azure-web/src/main/java/org/springframework/cloud/function/adapter/azure/web
    • spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web

2 files changed

+38
-16
lines changed

spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/main/java/org/springframework/cloud/function/adapter/azure/web/AzureWebProxyInvoker.java

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import org.springframework.cloud.function.utils.FunctionClassUtils;
4545
import org.springframework.util.CollectionUtils;
4646
import org.springframework.util.StringUtils;
47+
import org.springframework.web.context.WebApplicationContext;
4748

4849
/**
4950
*
@@ -54,11 +55,11 @@
5455
*/
5556
public class AzureWebProxyInvoker implements FunctionInstanceInjector {
5657

57-
private static Log logger = LogFactory.getLog(AzureWebProxyInvoker.class);
58+
private static final Log LOGGER = LogFactory.getLog(AzureWebProxyInvoker.class);
5859

5960
private static final String AZURE_WEB_ADAPTER_NAME = "AzureWebAdapter";
6061
private static final String AZURE_WEB_ADAPTER_ROUTE = AZURE_WEB_ADAPTER_NAME
61-
+ "/{e?}/{e2?}/{e3?}/{e4?}/{e5?}/{e6?}/{e7?}/{e8?}/{e9?}/{e10?}/{e11?}/{e12?}/{e13?}/{e14?}/{e15?}";
62+
+ "/{e?}/{e2?}/{e3?}/{e4?}/{e5?}/{e6?}/{e7?}/{e8?}/{e9?}/{e10?}/{e11?}/{e12?}/{e13?}/{e14?}/{e15?}";
6263

6364
private ServerlessMVC mvc;
6465

@@ -77,6 +78,7 @@ public <T> T getInstance(Class<T> functionClass) throws Exception {
7778
* Because the getInstance is called by Azure Java Function on every function request we need to cache the Spring
7879
* context initialization on the first function call.
7980
* Double-Checked Locking Optimization was used to avoid unnecessary locking overhead.
81+
*
8082
* @throws ServletException error.
8183
*/
8284
private void initialize() throws ServletException {
@@ -86,6 +88,10 @@ private void initialize() throws ServletException {
8688
if (mvc == null) {
8789
Class<?> startClass = FunctionClassUtils.getStartClass();
8890
this.mvc = ServerlessMVC.INSTANCE(startClass);
91+
this.servletContext = this.mvc.getServletContext();
92+
if (this.servletContext != null && this.servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) == null) {
93+
this.servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.mvc.getApplicationContext());
94+
}
8995
}
9096
}
9197
finally {
@@ -96,18 +102,25 @@ private void initialize() throws ServletException {
96102

97103
private HttpServletRequest prepareRequest(HttpRequestMessage<Optional<String>> request) {
98104

105+
if (this.servletContext == null) {
106+
this.servletContext = this.mvc.getServletContext();
107+
if (this.servletContext != null && this.servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) == null) {
108+
this.servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.mvc.getApplicationContext());
109+
}
110+
}
111+
99112
int pathOffset = request.getUri().getPath().indexOf(AZURE_WEB_ADAPTER_NAME) + AZURE_WEB_ADAPTER_NAME.length();
100113

101114
String path = request.getUri().getPath().substring(pathOffset);
102115

103116
ServerlessHttpServletRequest httpRequest = new ServerlessHttpServletRequest(servletContext,
104-
request.getHttpMethod().toString(), path);
117+
request.getHttpMethod().toString(), path);
105118

106119

107120
request.getBody().ifPresent(body -> {
108121
Charset charsetEncoding = request.getHeaders() != null && request.getHeaders().containsKey("content-encoding")
109-
? Charset.forName(request.getHeaders().get("content-encoding"))
110-
: StandardCharsets.UTF_8;
122+
? Charset.forName(request.getHeaders().get("content-encoding"))
123+
: StandardCharsets.UTF_8;
111124
httpRequest.setContent(body.getBytes(charsetEncoding));
112125
});
113126

@@ -126,14 +139,14 @@ private HttpServletRequest prepareRequest(HttpRequestMessage<Optional<String>> r
126139

127140
@FunctionName(AZURE_WEB_ADAPTER_NAME)
128141
public HttpResponseMessage execute(
129-
@HttpTrigger(name = "req", methods = {
130-
HttpMethod.GET,
131-
HttpMethod.POST,
132-
HttpMethod.PUT,
133-
HttpMethod.DELETE,
134-
HttpMethod.PATCH
135-
}, authLevel = AuthorizationLevel.ANONYMOUS, route = AZURE_WEB_ADAPTER_ROUTE) HttpRequestMessage<Optional<String>> request,
136-
ExecutionContext context) {
142+
@HttpTrigger(name = "req", methods = {
143+
HttpMethod.GET,
144+
HttpMethod.POST,
145+
HttpMethod.PUT,
146+
HttpMethod.DELETE,
147+
HttpMethod.PATCH
148+
}, authLevel = AuthorizationLevel.ANONYMOUS, route = AZURE_WEB_ADAPTER_ROUTE) HttpRequestMessage<Optional<String>> request,
149+
ExecutionContext context) {
137150

138151
context.getLogger().info("Request body is: " + request.getBody().orElse("[empty]"));
139152

@@ -151,8 +164,8 @@ public HttpResponseMessage execute(
151164

152165
String responseString = httpResponse.getContentAsString(StandardCharsets.UTF_8);
153166
if (StringUtils.hasText(responseString)) {
154-
if (logger.isDebugEnabled()) {
155-
logger.debug("Response: " + responseString);
167+
if (LOGGER.isDebugEnabled()) {
168+
LOGGER.debug("Response: " + responseString);
156169
}
157170
responseBuilder.body(responseString);
158171
} // TODO: what to do with bodyless response?

spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessMVC.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import org.springframework.util.ObjectUtils;
5757
import org.springframework.util.StringUtils;
5858
import org.springframework.web.context.ConfigurableWebApplicationContext;
59+
import org.springframework.web.context.WebApplicationContext;
5960
import org.springframework.web.servlet.DispatcherServlet;
6061

6162
/**
@@ -97,6 +98,10 @@ public static ServerlessMVC INSTANCE(ServletWebServerApplicationContext applicat
9798
ServerlessMVC mvc = new ServerlessMVC();
9899
mvc.applicationContext = applicationContext;
99100
mvc.dispatcher = mvc.applicationContext.getBean(DispatcherServlet.class);
101+
ServletContext servletContext = mvc.dispatcher.getServletContext();
102+
if (servletContext != null && servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) == null) {
103+
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, mvc.applicationContext);
104+
}
100105
mvc.contextStartupLatch.countDown();
101106
return mvc;
102107
}
@@ -134,7 +139,11 @@ private void initContext(Class<?>... componentClasses) {
134139
this.dispatcher = this.applicationContext.getBean(DispatcherServlet.class);
135140
}
136141
Assert.state(this.dispatcher != null, "DispatcherServlet bean was not initialized. "
137-
+ "Ensure ServerlessAutoConfiguration is active and selected as the ServletWebServerFactory.");
142+
+ "Ensure ServerlessAutoConfiguration is active and selected as the ServletWebServerFactory.");
143+
ServletContext servletContext = this.dispatcher.getServletContext();
144+
if (servletContext != null && servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) == null) {
145+
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.applicationContext);
146+
}
138147
}
139148

140149
public ConfigurableWebApplicationContext getApplicationContext() {

0 commit comments

Comments
 (0)