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).
User can extend SpringBootApiGatewayRequestHandler instead of the
generic SpringBootRequestHandler. It ties the code to AWS and the
API Gateway, but at least it supports the incoming data fully.
Fixes gh-111, closes gh-136
Use of BeanProcessor to catch a bean before it is used is a bit
agricultural these days. SmartInitializingSingleton is better and
frees application logs from one more annoying INFO log on an
early instantiation
2018-01-04 14:17:05.930 INFO 23472 --- [ Thread-0] trationDelegate$BeanPostProcessorChecker :
Bean 'org.springframework.cloud.function.web.flux.ReactorAutoConfiguration' of type
[org.springframework.cloud.function.web.flux.ReactorAutoConfiguration$$EnhancerBySpringCGLIB$$8d4844e]
is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
With this change there are now 2 choices for web endpoints. The
stream servlet binder is useful for multi-binder use cases
(e.g. HTTP -> message broker).
Fixes: gh-118
When the `BeanDefinition` for `Function` is a `FactoryBean`
(e.g. `GatewayProxyFactoryBean` in Spring Integration) and that
`BeanDefinition` isn't registered as `@Bean` method (e.g.
Spring Integration Java DSL parser), the `ContextFunctionCatalogAutoConfiguration`
doesn't resolve the target `Function` type properly
* Get the target `Function` bean type via `BeanFactory.getType(String)`
* Make fallback to the `Object.class` instead of bean type since we are
expecting here a generic type anyway
When a function is created using an isolated class loader it might
want to use that class loader again for its invocations, and a lot
of tools (Spring etc.) use the context class loader for that kind
of thing if they don't have an explicit default value. So we
set the context class loader before, and unset it after, the
function invocation using a convenience wrapper.
This makes dynamic function registration (after context starts) much
easier. Also frees us from having to employ BeanFactoryPostProcessor
and other tricks to get the functions registered on startup.