Closed dsyer closed 6 years ago
I suppose the user might want multiple exports for objects of the same type, so @EnableWiretap(Foo.class)
is not enough for the general case. There's a naming problem anyway (the bean names need to be customizable a bit in general). So maybe @EnableWiretap(@Wiretap(type=Foo.class, name="foos"))
would work better, or as an alternative.
interesting idea - I wonder if we want to support this via properties in a way similar to other currently configurable functions. For example, we currently have compile
, import
, etc:
spring:
cloud:
function:
compile:
uppercase:
lambda: s->s.toUpperCase()
inputType: String
outputType: String
hello:
type: supplier
lambda: ()->"hello"
outputType: String
import:
lowercase:
location: file:///tmp/function-registry/functions/lowercase.fun
scan:
packages: fun1, fun2
inject:
greeter:
greeting: howdy
So perhaps we could add export.<name>
, and we could even use SpEL for the "definition" thereby supporting @bean.whatever()
syntax.
Not sure. I don't see as much value in the properties approach here because you don't need an export/wiretap unless you are going to use it in your code. So you might as well declare it there.
I think I agree.
I'm swinging back the other way, having watched the Azure function demo from Serverless 2017. In Azure you have "function apps" (a lot like a SCFn app with 1-n functions) and you "bind" them to inputs and outputs using JSON. What we have right now is kind of automatic binding based on the classpath, and the input and output are always to the same transport (web, rabbit, etc.). So tweaking that to reflect the user's intentions via the Spring environment seems like a good idea, and keeps the runtime separate from the code. Spring Cloud Stream actually already supports this via something like:
spring.cloud.stream.bindings.input.binder=kafka
spring.cloud.stream.bindings.output.binder=rabbit
So, we could use the exact same idiom (if we add a "web" binder somehow), or we could abstract it into something different, e.g.
spring.cloud.function.bindings.uppercase.input=web
spring.cloud.function.bindings.uppercase.output=rabbit
to accept an incoming HTTP request and relay the processed result to rabbit.
Interestingly, the example above splits the "uppercase" Function
into an "input" Consumer
and an "output" Supplier
, with a wiretap precisely as described in the original feature request. Internally we could implement it that way - the FunctionCatalog
could be virtualized and the split/wiretap could take place generically in that layer.
The "servlet" binder lets you do the thing in the last comment. I think I'll call this closed.
Basic idea: user declares (somehow) an interest in "exporting" items of a given POJO type
Foo
(say), and framework generates 2 beans: one is aConsumer<Foo>
and the other is aSupplier<Flux<Foo>>
. The framework already automatically adds theSupplier
to theFunctionCatalog
, so it can be used to sendFoos
to an external stream or HTTP client. TheConsumer
is implemented in such a way that it pushes eachFoo
into theFlux
stream created by theSupplier
.I implemented it here as
@EnableWiretap
but the name could be changed: https://github.com/dsyer/petflix/blob/master/videos/src/main/java/com/example/VideoApplication.java#L15.