-
Notifications
You must be signed in to change notification settings - Fork 8
/
trigger.go
153 lines (118 loc) · 3.48 KB
/
trigger.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package lambda
import (
"context"
"encoding/json"
syslog "log"
"github.com/project-flogo/core/data/metadata"
"github.com/project-flogo/core/support/log"
"github.com/project-flogo/core/trigger"
)
var triggerMd = trigger.NewMetadata(&HandlerSettings{}, &Output{}, &Reply{})
var singleton *LambdaTrigger
func init() {
_ = trigger.Register(&LambdaTrigger{}, &LambdaFactory{})
}
// LambdaFactory AWS Lambda Trigger factory
type LambdaFactory struct {
}
//New Creates a new trigger instance for a given id
func (t *LambdaFactory) New(config *trigger.Config) (trigger.Trigger, error) {
if singleton == nil {
singleton = &LambdaTrigger{}
return singleton, nil
}
log.RootLogger().Warn("Only one lambda trigger instance can be instantiated")
return nil, nil
}
// Metadata implements trigger.Trigger.Metadata
func (t *LambdaFactory) Metadata() *trigger.Metadata {
return triggerMd
}
// LambdaTrigger AWS Lambda trigger struct
type LambdaTrigger struct {
id string
log log.Logger
handlers map[string]trigger.Handler
defaultHandler trigger.Handler
}
func (t *LambdaTrigger) Initialize(ctx trigger.InitContext) error {
t.id = "Lambda"
t.log = ctx.Logger()
t.defaultHandler = ctx.GetHandlers()[0]
t.handlers = make(map[string]trigger.Handler)
for _, handler := range ctx.GetHandlers() {
s := &HandlerSettings{}
err := metadata.MapToStruct(handler.Settings(), s, true)
if err != nil {
return err
}
if s.EventType == "" {
if t.defaultHandler == nil {
t.defaultHandler = handler
} else {
log.RootLogger().Warn("Only one default handler will be used")
}
continue
}
if _, exists := t.handlers[s.EventType]; exists {
log.RootLogger().Warnf("Only first handler for eventType '%s' will be used", s.EventType)
break
}
t.handlers[s.EventType] = handler
}
return nil
}
// Invoke starts the trigger and invokes the action registered in the handler
func Invoke(details *RequestDetails) (map[string]interface{}, error) {
syslog.Printf("Received request: %s\n", details.CtxInfo["awsRequestId"])
//todo figure out how to support flogo logging in Lambda
//log.RootLogger().Debugf("Received ctx: '%+v'\n", lambdaCtx)
evtTypeStr := FromEventType(details.EventType)
syslog.Printf("Payload Type: %s\n", evtTypeStr)
syslog.Printf("Payload: '%+v'\n", details.Event)
out := &Output{}
out.Context = details.CtxInfo
out.Event = details.Event
if details.EventType == EtFlogoOnDemand {
// todo add event type to flogo events?
var evt FlogoEvent
if err := json.Unmarshal(details.Payload, &evt); err != nil {
return nil, err
}
out.Event = map[string]interface{}{"payload":evt.Payload, "flogo":evt.Flogo}
}
out.EventType = evtTypeStr
//select handler for the specified eventType
handler := singleton.handlers[evtTypeStr]
if handler == nil {
handler = singleton.defaultHandler
}
results, err := handler.Handle(context.Background(), out)
if err != nil {
log.RootLogger().Debugf("Lambda Trigger Error: %s", err.Error())
syslog.Printf("Lambda Trigger Error: %s", err.Error())
return nil, err
}
reply := Reply{}
err = reply.FromMap(results)
if err != nil {
return nil, err
}
if reply.Data != nil {
if reply.Status == 0 {
reply.Status = 200
}
}
return reply.ToMap(), err
}
func (t *LambdaTrigger) Start() error {
return nil
}
// Stop implements util.Managed.Stop
func (t *LambdaTrigger) Stop() error {
return nil
}
type FlogoEvent struct {
Payload interface{} `json:"payload"`
Flogo json.RawMessage `json:"flogo"`
}