Skip to content

Latest commit

 

History

History
106 lines (77 loc) · 4.45 KB

Function-Invokers.adoc

File metadata and controls

106 lines (77 loc) · 4.45 KB

Riff Function Invokers

Creating a Function Invoker

HTTP

A function invoker must listen on port 8080 for request-response style interactions via a HTTP POST. The HTTP headers have a content-type that can be used to decode the request body.

gRPC

A function invoker can also be implemented as a bi-directional stream (as opposed to request-response) in gRPC. The carrier type is a generic function.Message defined in the Function Proto project. There are language-specific bindings to the Message type defined alongside the protobuffer declarations.

Testing a Function Invoker

For HTTP you should be able to just POST some data to localhost:8080 and get a response. It is advisable to include a Content-Type header, but the function invoker is free to ignore it. The function invoker can make all the decisions it likes about content negotiation, and marshalling the request and response bodies. Any kind of sensible response with 200 OK should be fine - the sidecar takes care of headers in a live Riff system, and copies the response body bytes verbatim.

For gRPC the invoker can still make any decision it likes about content negotiation, and even how many messages to send in response. The function invoker can be tested by writing a tiny gRPC client and sending it a stream of function.Message. You would call it a success if you got any kind of messages back, depending on the semantics of the function. If you are supporting request-response, precisely one of the response messages must contain the same correlationId header as the incoming messages.

Running the Gateway Locally

Instead of writing custom gRPC test clients, you can run the gateway locally. You will need Kafka, the riff gateway, a riff sidecar, and your Function Invoker. Then you can POST messages to the gateway and they will flow through to the function invoker and back through Kafka. This can be useful for end-to-end testing, especially with gRPC function invokers, since there is nothing as convenient as curl for ad hoc testing.

One way to run kafka is to use Spring Cloud CLI, or you could use docker. Using docker would look like this

docker run -e ADVERTISED_HOST=localhost -p 9092:9092 -ti spotify/kafka

Then clone and run the gateway. This requires golang 1.9 or later, so check your go env and set GOPATH and GOROOT env vars accordingly. Then do this:

go get github.com/projectriff/riff/
cd $(go env GOPATH)/src/github.com/projectriff/riff/http-gateway
export KAFKA_BROKERS=localhost:9092
go run cmd/http-gateway.go

Then get your function invoker running, and make sure it doesn’t try and listen on port 8080 (where the gateway is already running).

And, once you have the function invoker running, do the same with the sidecar:

go get github.com/projectriff/riff
cd $(go env GOPATH)/src/github.com/projectriff/riff/function-sidecar
go run cmd/function-sidecar.go -brokers=localhost:9092 -inputs=inputs -outputs=replies -group=default -protocol=grpc

yields

2018/02/20 16:33:27 Sidecar for function 'default' (inputs->outputs) using grpc dispatcher starting
2018/02/20 16:33:27 Rebalanced: &{Type:rebalance start Claimed:map[] Released:map[] Current:map[]}
2018/02/20 16:33:27 Rebalanced: &{Type:rebalance OK Claimed:map[inputs:[0]] Released:map[] Current:map[inputs:[0]]}

The name of the "inputs" channel is arbitrary, and will be used below in constructing the URI for addressing the gateway. The "ouputs" has to be "replies" for the request-reply pattern to work.

At this point you can POST messages into the gateway and they will flow through kafka to the sidecar and then into the function invoker and back. There are 2 endpoints on the gateway:

Endpoint

Semantics

POST /requests/{channel}

Request-response.

POST /messages/{channel}

Message stream (bi-directional).

For both endpoints remember to include a Content-Type header. The "channel" name is the name of the "inputs" command line option when you started the sidecar. Example:

curl localhost:8080/requests/inputs -H "Content-Type: text/plain" -d World
Hello World

You will see the messages flowing through the sidecar in logs, e.g.

2018/02/20 16:34:47 <<< Message{Hello World, map[Accept:[*/*] Content-Type:[text/plain] timestamp:[1519144487664] correlationId:[b1a97d11-c2e1-4eb5-8919-92a859dcbf43]]}