Commit Graph

83 Commits

Author SHA1 Message Date
Oleg Zhurakousky
8c7c8f9a1c GH-180 added null assertion to FunctionRegistration
Resolves #180
2018-06-12 15:32:22 -04:00
Dave Syer
8599be2255 Make Jackson and Gson beans conditional 2018-05-21 09:05:08 +01:00
Dave Syer
66476559ed Move JsonMapper to spring-cloud-function-context
...in case it is needed elsewhere (see gh-151)
2018-05-21 08:50:35 +01:00
Dave Syer
e34324b5b4 Double check that a Function can return a Mono 2018-05-15 08:43:58 +01:00
Dave Syer
eaea89532c Add documentation for compiler configuration properties 2018-05-02 06:17:28 -04:00
Dave Syer
b59b43ddc5 Only expose Publisher via FunctionCatalog
Flux.from() is cheap and can be used to marshal the inputs everywhere
internally. With this change users ought to be able to register any
function of any Publisher type.
2018-05-01 12:06:34 -04:00
Dave Syer
fb04324ac9 Factor out a new strategy for wrapper type detection
Using this strategy libraries could be developed for supporting
Flux-like libraries (e.g. kstreams) that are not actually
reactive streams implementations.
2018-05-01 12:06:29 -04:00
Dave Syer
59f94c1533 Fix potential issue when Message is not available but not needed
If an isolated function doesn't have Message in its classpath, we
will never actually need to instantiate that class. This change
makes sure we check first.
2018-04-25 07:27:33 +01:00
Dave Syer
57c05970e5 Use concurrent hash map in function catalog 2018-04-24 10:23:22 +01:00
Dave Syer
5aeba1ea96 Convert Consumer<Foo> to Function<Flux<Foo>,Mono<Void>>
This results in a better experience for users because the consumer
that they write is only applied to a Flux that is subscribed to
by the framework once. It gives better control over the flow of
foos, e.g. if some component wants to subscribe on a thread.
2018-03-26 10:06:13 +01:00
Dave Syer
a1b624b28a Inspect bean class if it is available
Avoids instantiating beans if not necessary, and allows user to
provide Function as a @SpringBootApplication (for instance), or
more generally as a source to the application context (as opposed
to being component scanned).
2018-03-21 11:09:57 +00:00
Dave Syer
773dddbe68 Ensure composite wrapper type reflects reality
When a Supplier<Flux<Foo>> is composed with a Function<Foo,Bar>
the resulting handler (supplier) should have Flux as its output
wrapper still (the most general output wrapper type in the chain).
2018-03-16 08:35:21 -04:00
Dave Syer
47f86671ca Allow pipe as well as comma in function composition 2018-03-16 08:05:29 -04:00
Dave Syer
5528659b4b Inspect bean definition more thoroughly for factory arguments
Fixes gh-153
2018-03-02 11:28:33 +00:00
Dave Syer
dc008cc24d Ensure a function is inspectable as itself and its wrapper
Since a function is wrapper in a FluxWrapper (and possibly also
an Isolated), the link is lost between the bean and the type
metadata without this change.
2018-03-01 09:10:14 +00:00
Dave Syer
955e99bfe3 Re-org so that default methods are used everywhere 2018-02-28 14:18:09 +00:00
Dave Syer
33b33adb4b Change FunctionCatalog to key off Class<?>
Makes it possible to support other "function" types in the future.
The user is always taking a risk with the lookup that the object
returned has the generic type desired (but that hasn't changed
with this commit). FunctionCatalog is a lot simpler as a result
and also a lot more flexible.
2018-02-28 14:18:09 +00:00
Dave Syer
616e2825c6 Move FunctionCatalog into context module 2018-02-27 09:05:28 +00:00
Dave Syer
7bc6d7dfee Re-order type discovery and function wrapping
Otherwise the explicit types from the function registration are
not used.
2018-02-26 16:28:50 +00:00
Dave Syer
5203401e00 Use Void as input type for Supplier, etc. 2018-02-26 14:15:54 +00:00
Dave Syer
f9e4546070 Add convenience methods to FunctionType 2018-02-26 11:45:01 +00:00
Dave Syer
d95ab8f173 Migrate type computation logic to FunctionType 2018-02-26 10:57:45 +00:00
Dave Syer
38f6caf4dc Add FunctionType abstraction and test it 2018-02-26 09:56:02 +00:00
Dave Syer
8cd2675986 Add tests for various scenarios of message conversion 2018-02-16 10:31:28 +00:00
Dave Syer
1b624c3531 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).
2018-02-16 08:16:55 +00:00
Dave Syer
ccd3953163 Cache result of isMessage() computation before function is wrapped
Otherwise you get the wrong result when you go back and ask later
(but only if the bean is a singleton with no bean definition).
2018-02-14 16:25:12 +00:00
Dave Syer
c728cd4c01 Support for Function<Publisher<...>,...> 2018-02-14 14:09:28 +00:00
Dave Syer
1af0d451cf Migrate to servlet binder for web features 2018-01-03 15:06:33 +00:00
Artem Bilan
46fdca479b Properly resolve FactoryBean for function
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
2017-12-01 10:31:18 +00:00
Dave Syer
e824fbf6cb Isolate the context class loader if function appears to need it
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.
2017-11-25 05:25:29 +09:00
Dave Syer
f3951cba66 Prefer explicit route to default 2017-11-24 13:21:08 +09:00
Dave Syer
1ee517ab01 Use unique function if there is only one and name not provided
If the user doesn't ask for a specific function, but there is only
one possible choice, we can just use that.
2017-11-24 12:41:10 +09:00
Dave Syer
8459fb4e30 Ensure a concrete type with parametrric subtype is detected
If user defines their own @Beans from conrete types that implement
Function<...> then their type signature is detectable from the
class.
2017-11-20 15:34:06 +00:00
Dave Syer
219d056801 Add FunctionRegistry interface (writable FunctionCatalog)
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.
2017-11-13 14:13:59 +00:00
Dave Syer
41d1dfa6bc Add public registration method to bean post processor
Also simplifies logic of looking up message types
2017-11-13 09:27:36 +00:00
Dave Syer
85ba0b480e Fallback to Object.class not the function type
See gh-118 (partial fix)
2017-11-10 17:38:45 +00:00
Dave Syer
d4b87c1fe7 Initial support for composable functions
There's a test for each of the supported types. No error handling
yet.

Fixes gh-122
2017-11-10 16:45:11 +00:00
Dave Syer
ad0ebd5cfc Add additional logic to function catalog to help with singletons
A registered singleton doesn't have a BeanDefinition, but it might have
a compiled type with enough generic information to pull out the
input and output types.
2017-11-10 12:11:55 +00:00
Dave Syer
a27f1fe4dd Switch on @FunctionScan by default 2017-10-25 08:53:14 +01:00
Dave Syer
3ccb925733 Merge core packages into one 2017-09-15 17:10:00 +01:00
Eric Bottard
aa45ff4b94 Revert visibility of FunctionRegistration to public
Fixes #102
2017-08-24 19:21:29 +02:00
Oleg Zhurakousky
a973b678f1 FunctionUtils polishing
- attempted to make code more functional (eat our own dog food) and concise
- addressed PR comment
- additional cleanup/polishing of FunctionUtils and related classes
- Removed Function/Supplier/ConsumerProxy classes by extending type info on their super interface
- Renamed FunctionUtils to FunctionFactoryUtils
- Added javadoc to FunctionFactoryUtils to explain its design considerations as well as what it can and can not doi

Fixes gh-90
2017-08-22 14:07:42 +01:00
Oleg Zhurakousky
592eef9d52 General polishing
- minor refactoring of FunctionRegistration and some javadoc
 - general cleanup of ContextFunctionCatalogAutoConfiguration (mainly consolidated repeatable code)

Fixes gh-98
2017-08-22 10:34:13 +01:00
Oleg Zhurakousky
182317dbe9 Minor polishing of InMemoryFunctionCatalog
- Removed constructor in InMemoryFunctionCatalog that creates empty maps and no registrations since there is no way to register anything after catalog is created.
- Refactored registration logic a bit more functional/concise in the FunctionRegistration constructor of InMemoryFunctionCatalog
- Added additional assertions in tests

rebased and removed the assertion that was causing certain test failures
2017-07-13 16:07:53 +01:00
Dave Syer
c8646d64d8 Strangle old inspector methods
Fixes gh-81
2017-07-13 13:37:45 +01:00
Dave Syer
d7d49858f6 Add new methods to FunctionInspector 2017-07-13 13:37:06 +01:00
Dave Syer
7e966c73ca Adds routing keys in message headers
If the incoming message has a stream_routekey header, we use that
to route the message to a named function. Also adding the header
to messages coming out of suppliers.

The biggest change here is sort of orthogonal: it fixes a bug where
Spring Integration would subscribe twice to the same input channel
if the FunctionCatalog contains both functions and consumers. Then
when a message comes in it is dispatched to one or the other, but not
both. So the routing key couldn't work without fixing that
problem.
2017-07-13 13:32:32 +01:00
Dave Syer
4b30721d02 Fix naming indirection so that input types are correctly located
Also applies to output types, wrapper types and identifying if
messages can be processed directly.

See gh-81 (the ambiguity is still there, but the indirection bug
is fixed).
2017-07-11 17:39:42 +01:00
Dave Syer
da0c954135 Add get*Names() to FunctionCatalog
We could go wit a separate interface, but it seems sensible to
keep it together really, so that callers don't have to downcast.
2017-06-29 14:43:19 +01:00
Dave Syer
d826884d02 Ensure @Component scanned from jar on classpath can be inspected
And test it using a new POF sample.
2017-06-28 17:52:37 +01:00