mirror of https://github.com/knative/docs.git
84 lines
1.8 KiB
Go
84 lines
1.8 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/cloudevents/sdk-go/v2/binding"
|
|
cecontext "github.com/cloudevents/sdk-go/v2/context"
|
|
"github.com/cloudevents/sdk-go/v2/protocol"
|
|
)
|
|
|
|
type Invoker interface {
|
|
Invoke(context.Context, binding.Message, protocol.ResponseFn) error
|
|
IsReceiver() bool
|
|
IsResponder() bool
|
|
}
|
|
|
|
var _ Invoker = (*receiveInvoker)(nil)
|
|
|
|
func newReceiveInvoker(fn interface{}, fns ...EventDefaulter) (Invoker, error) {
|
|
r := &receiveInvoker{
|
|
eventDefaulterFns: fns,
|
|
}
|
|
|
|
if fn, err := receiver(fn); err != nil {
|
|
return nil, err
|
|
} else {
|
|
r.fn = fn
|
|
}
|
|
|
|
return r, nil
|
|
}
|
|
|
|
type receiveInvoker struct {
|
|
fn *receiverFn
|
|
eventDefaulterFns []EventDefaulter
|
|
}
|
|
|
|
func (r *receiveInvoker) Invoke(ctx context.Context, m binding.Message, respFn protocol.ResponseFn) (err error) {
|
|
defer func() {
|
|
if err2 := m.Finish(err); err2 == nil {
|
|
err = err2
|
|
}
|
|
}()
|
|
|
|
e, err := binding.ToEvent(ctx, m)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if e != nil && r.fn != nil {
|
|
resp, result := r.fn.invoke(ctx, *e)
|
|
|
|
// Apply the defaulter chain to the outgoing event.
|
|
if resp != nil && len(r.eventDefaulterFns) > 0 {
|
|
for _, fn := range r.eventDefaulterFns {
|
|
*resp = fn(ctx, *resp)
|
|
}
|
|
// Validate the event conforms to the CloudEvents Spec.
|
|
if verr := resp.Validate(); verr != nil {
|
|
cecontext.LoggerFrom(ctx).Error(fmt.Errorf("cloudevent validation failed on response event: %v, %w", verr, err))
|
|
}
|
|
}
|
|
if respFn != nil {
|
|
var rm binding.Message
|
|
if resp != nil {
|
|
rm = (*binding.EventMessage)(resp)
|
|
}
|
|
|
|
return respFn(ctx, rm, result) // TODO: there is a chance this never gets called. Is that ok?
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *receiveInvoker) IsReceiver() bool {
|
|
return !r.fn.hasEventOut
|
|
}
|
|
|
|
func (r *receiveInvoker) IsResponder() bool {
|
|
return r.fn.hasEventOut
|
|
}
|