Support for isolated class loaders extended to cover more functions

Functions with Flux and Message (as well as POJOs and Flux of POJO
which were already supported) should now work if they are created in
an isolated class loader. Preconditions:

* The class loaders must have the reactor-core (and reactive-streams)
shared between the app and the function. Practically speaking this means
there has to be a parent class loader with just reactive types, and
sibling children for the app and the function. This is not a new
requirement (it was needed for Flux of POJO anyway).

* Message types are handled reflectively, so they don't have to be in a
shared class loader. But they do have to be  on the class path on
both sides (obviously).
This commit is contained in:
Dave Syer
2018-02-16 08:16:55 +00:00
parent ccd3953163
commit 1b624c3531
17 changed files with 615 additions and 33 deletions

View File

@@ -24,6 +24,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.function.context.catalog.FunctionInspector;
import org.springframework.cloud.function.context.message.MessageUtils;
import org.springframework.cloud.function.web.flux.request.FluxRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -72,6 +73,9 @@ public class FunctionController {
flux = flux.log();
}
Flux<?> result = Flux.from(function.apply(flux));
if (inspector.isMessage(function)) {
result = result.map(message -> MessageUtils.unpack(function, message));
}
if (logger.isDebugEnabled()) {
logger.debug("Handled POST with function");
}

View File

@@ -30,13 +30,14 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.function.context.catalog.FunctionInspector;
import org.springframework.cloud.function.context.message.MessageUtils;
import org.springframework.cloud.function.web.flux.constants.WebRequestConstants;
import org.springframework.cloud.function.web.util.HeaderUtils;
import org.springframework.core.MethodParameter;
import org.springframework.core.Ordered;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.messaging.MessageHeaders;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
@@ -106,12 +107,10 @@ public class FluxHandlerMethodArgumentResolver
}
if (message) {
List<Object> messages = new ArrayList<>();
MessageHeaders headers = HeaderUtils.fromHttp(new ServletServerHttpRequest(
webRequest.getNativeRequest(HttpServletRequest.class)).getHeaders());
for (Object payload : body) {
messages.add(MessageBuilder.withPayload(payload)
.copyHeaders(HeaderUtils.fromHttp(new ServletServerHttpRequest(
webRequest.getNativeRequest(HttpServletRequest.class))
.getHeaders()))
.build());
messages.add(MessageUtils.create(handler, payload, headers));
}
body = messages;
}