@@ -27,10 +27,7 @@ import (
27
27
"time"
28
28
29
29
"github.com/kelseyhightower/envconfig"
30
- "github.com/triggermesh/aws-custom-runtime/pkg/events"
31
- "github.com/triggermesh/aws-custom-runtime/pkg/events/apigateway"
32
- "github.com/triggermesh/aws-custom-runtime/pkg/events/cloudevents"
33
- "github.com/triggermesh/aws-custom-runtime/pkg/events/passthrough"
30
+ "github.com/triggermesh/aws-custom-runtime/pkg/sender"
34
31
)
35
32
36
33
var (
@@ -67,13 +64,15 @@ type Specification struct {
67
64
// Lambda API port to put function requests and get results
68
65
ExternalAPIport string `envconfig:"external_api_port" default:"8080"`
69
66
70
- // Apply response wrapping before sending it back to the client.
71
- // Common case - AWS Lambda functions usually returns data formatted for API Gateway service.
72
- // Set "RESPONSE_WRAPPER: API_GATEWAY" and receive events as if they were processed by API Gateway.
73
- // Opposite scenario - return responses in CloudEvent format: "RESPONSE_WRAPPER: CLOUDEVENTS"
74
- // NOTE: Response wrapper does both encoding and decoding depending on the type. We should consider
75
- // separating wrappers by their function.
76
- ResponseWrapper string `envconfig:"response_wrapper"`
67
+ Sink string `envconfig:"k_sink"`
68
+ ResponseFormat string `envconfig:"response_format"`
69
+ }
70
+
71
+ type Handler struct {
72
+ * sender.Handler
73
+
74
+ requestSizeLimit int64
75
+ functionTTL int64
77
76
}
78
77
79
78
type message struct {
@@ -98,10 +97,10 @@ func (rw *responseWrapper) WriteHeader(statusCode int) {
98
97
rw .StatusCode = statusCode
99
98
}
100
99
101
- func ( s * Specification ) setupEnv () error {
100
+ func setupEnv (internalAPIport string ) error {
102
101
environment ["_HANDLER" ], _ = os .LookupEnv ("_HANDLER" )
103
102
environment ["LAMBDA_TASK_ROOT" ], _ = os .LookupEnv ("LAMBDA_TASK_ROOT" )
104
- environment ["AWS_LAMBDA_RUNTIME_API" ] += ":" + s . InternalAPIport
103
+ environment ["AWS_LAMBDA_RUNTIME_API" ] += ":" + internalAPIport
105
104
106
105
for k , v := range environment {
107
106
if err := os .Setenv (k , v ); err != nil {
@@ -111,9 +110,9 @@ func (s *Specification) setupEnv() error {
111
110
return nil
112
111
}
113
112
114
- func (s * Specification ) newTask (w http.ResponseWriter , r * http.Request ) {
115
- requestSizeLimitInBytes := s . RequestSizeLimit * 1e+6
116
- functionTTLInNanoSeconds := s . FunctionTTL * 1e+9
113
+ func (h * Handler ) newTask (w http.ResponseWriter , r * http.Request ) {
114
+ requestSizeLimitInBytes := h . requestSizeLimit * 1e+6
115
+ functionTTLInNanoSeconds := h . functionTTL * 1e+9
117
116
body , err := ioutil .ReadAll (http .MaxBytesReader (w , r .Body , requestSizeLimitInBytes ))
118
117
if err != nil {
119
118
http .Error (w , err .Error (), http .StatusInternalServerError )
@@ -140,12 +139,19 @@ func (s *Specification) newTask(w http.ResponseWriter, r *http.Request) {
140
139
select {
141
140
case <- time .After (time .Duration (functionTTLInNanoSeconds )):
142
141
log .Printf ("-> ! %s Deadline is reached\n " , task .id )
143
- w .WriteHeader (http .StatusGone )
144
- w .Write ([]byte (fmt .Sprintf ("Deadline is reached, data %s" , task .data )))
142
+ // w.WriteHeader(http.StatusGone)
143
+ // w.Write([]byte(fmt.Sprintf("Deadline is reached, data %s", task.data)))
144
+ resp := []byte (fmt .Sprintf ("Deadline is reached, data %s" , task .data ))
145
+ if err := h .Send (resp , http .StatusGone , w ); err != nil {
146
+ log .Printf ("! %s %v\n " , task .id , err )
147
+ }
145
148
case result := <- resultsChannel :
146
149
log .Printf ("-> %s %d %s\n " , result .id , result .statusCode , result .data )
147
- w .WriteHeader (result .statusCode )
148
- w .Write (result .data )
150
+ // w.WriteHeader(result.statusCode)
151
+ // w.Write(result.data)
152
+ if err := h .Send (result .data , result .statusCode , w ); err != nil {
153
+ log .Printf ("! %s %v\n " , result .id , err )
154
+ }
149
155
}
150
156
mutex .Lock ()
151
157
delete (results , task .id )
@@ -231,31 +237,6 @@ func responseHandler(w http.ResponseWriter, r *http.Request) {
231
237
return
232
238
}
233
239
234
- func (s * Specification ) mapEvent (h http.Handler ) http.Handler {
235
- var mapper events.Mapper
236
-
237
- switch s .ResponseWrapper {
238
- case "API_GATEWAY" :
239
- mapper = apigateway .NewMapper ()
240
- case "CLOUDEVENTS" :
241
- mapper = cloudevents .NewMapper ()
242
- if err := envconfig .Process ("CE" , mapper ); err != nil {
243
- log .Fatalf ("Cannot process CloudEvents wrapper env variables: %v" , err )
244
- }
245
- default :
246
- mapper = passthrough .NewMapper ()
247
- }
248
-
249
- return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
250
- rw := responseWrapper {
251
- ResponseWriter : w ,
252
- }
253
- mapper .Request (r )
254
- h .ServeHTTP (& rw , r )
255
- mapper .Response (w , rw .StatusCode , rw .Body )
256
- })
257
- }
258
-
259
240
func ping (w http.ResponseWriter , r * http.Request ) {
260
241
w .WriteHeader (http .StatusOK )
261
242
w .Write ([]byte ("pong" ))
@@ -282,28 +263,39 @@ func api() error {
282
263
}
283
264
284
265
func main () {
266
+ // parse env
285
267
var spec Specification
286
268
if err := envconfig .Process ("" , & spec ); err != nil {
287
269
log .Fatalf ("Cannot process env variables: %v" , err )
288
270
}
289
271
log .Printf ("%+v\n " , spec )
290
272
291
273
log .Println ("Setting up runtime env" )
292
- if err := spec . setupEnv (); err != nil {
274
+ if err := setupEnv (spec . InternalAPIport ); err != nil {
293
275
log .Fatalf ("Cannot setup runime env: %v" , err )
294
276
}
295
277
278
+ // create sender
279
+ sender := Handler {
280
+ Handler : sender .New (spec .Sink , "text/plain" ),
281
+ requestSizeLimit : spec .RequestSizeLimit ,
282
+ functionTTL : spec .FunctionTTL ,
283
+ }
284
+
285
+ // setup channels
296
286
tasks = make (chan message , 100 )
297
287
results = make (map [string ]chan message )
298
288
defer close (tasks )
299
289
290
+ // start Lambda API
300
291
log .Println ("Starting API" )
301
292
go func () {
302
293
if err := api (); err != nil {
303
294
log .Fatalf ("Runtime internal API error: %v" , err )
304
295
}
305
296
}()
306
297
298
+ // start invokers
307
299
for i := 0 ; i < spec .NumberOfinvokers ; i ++ {
308
300
log .Println ("Starting bootstrap" , i + 1 )
309
301
go func (i int ) {
@@ -317,9 +309,10 @@ func main() {
317
309
}(i )
318
310
}
319
311
312
+ // start external API
320
313
taskRouter := http .NewServeMux ()
321
- taskHandler := http .HandlerFunc (spec .newTask )
322
- taskRouter .Handle ("/" , spec . mapEvent ( taskHandler ) )
314
+ taskHandler := http .HandlerFunc (sender .newTask )
315
+ taskRouter .Handle ("/" , taskHandler )
323
316
log .Println ("Listening..." )
324
317
err := http .ListenAndServe (":" + spec .ExternalAPIport , taskRouter )
325
318
if err != nil && err != http .ErrServerClosed {
0 commit comments