@@ -27,43 +27,13 @@ import (
2727 "time"
2828
2929 "github.com/kelseyhightower/envconfig"
30- "github.com/triggermesh/aws-custom-runtime/pkg/events/apiGateway"
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"
3134)
3235
33- type message struct {
34- id string
35- deadline int64
36- data []byte
37- statusCode int
38- }
39-
40- type responseWrapper struct {
41- http.ResponseWriter
42- StatusCode int
43- Body []byte
44- }
45-
46- // Specification is a set of env variables that can be used to configure runtime API
47- type Specification struct {
48- // Number of bootstrap processes
49- NumberOfinvokers int `envconfig:"invoker_count" default:"4"`
50- // Request body size limit, Mb
51- RequestSizeLimit int64 `envconfig:"request_size_limit" default:"5"`
52- // Funtions deadline, seconds
53- FunctionTTL int64 `envconfig:"function_ttl" default:"10"`
54- // Lambda runtime API port for functions
55- InternalAPIport string `envconfig:"internal_api_port" default:"80"`
56- // Lambda API port to put function requests and get results
57- ExternalAPIport string `envconfig:"external_api_port" default:"8080"`
58- // Either return function result "as is" or consider it as API Gateway JSON
59- EventType string `envconfig:"event_type"`
60- }
61-
6236var (
63- // numberOfinvokers = 4
64- // requestSizeLimit int64 = 5
65- // functionTTL int64 = 10
66-
6737 tasks chan message
6838 results map [string ]chan message
6939
8454 }
8555)
8656
57+ // Specification is a set of env variables that can be used to configure runtime API
58+ type Specification struct {
59+ // Number of bootstrap processes
60+ NumberOfinvokers int `envconfig:"invoker_count" default:"4"`
61+ // Request body size limit, Mb
62+ RequestSizeLimit int64 `envconfig:"request_size_limit" default:"5"`
63+ // Funtions deadline, seconds
64+ FunctionTTL int64 `envconfig:"function_ttl" default:"10"`
65+ // Lambda runtime API port for functions
66+ InternalAPIport string `envconfig:"internal_api_port" default:"80"`
67+ // Lambda API port to put function requests and get results
68+ ExternalAPIport string `envconfig:"external_api_port" default:"8080"`
69+ // Parent Knative Service name
70+ Service string `envconfig:"k_service"`
71+
72+ // Apply response wrapping before sending it back to the client.
73+ // Common case - AWS Lambda functions usually returns data formatted for API Gateway service.
74+ // Set "RESPONSE_WRAPPER: API_GATEWAY" and receive events as if they were processed by API Gateway.
75+ // Opposite scenario - return responses in CloudEvent format: "RESPONSE_WRAPPER: CLOUDEVENTS"
76+ // NOTE: Response wrapper does both encoding and decoding depending on the type. We should consider
77+ // separating wrappers by their function.
78+ ResponseWrapper string `envconfig:"response_wrapper"`
79+ }
80+
81+ type message struct {
82+ id string
83+ deadline int64
84+ data []byte
85+ statusCode int
86+ }
87+
88+ type responseWrapper struct {
89+ http.ResponseWriter
90+ StatusCode int
91+ Body []byte
92+ }
93+
8794func (rw * responseWrapper ) Write (data []byte ) (int , error ) {
8895 rw .Body = data
8996 return len (data ), nil
@@ -227,16 +234,24 @@ func responseHandler(w http.ResponseWriter, r *http.Request) {
227234}
228235
229236func (s * Specification ) mapEvent (h http.Handler ) http.Handler {
237+ var mapper events.Mapper
238+
239+ switch s .ResponseWrapper {
240+ case "API_GATEWAY" :
241+ mapper = apigateway .NewMapper ()
242+ case "CLOUDEVENTS" :
243+ mapper = cloudevents .NewMapper (s .Service )
244+ default :
245+ mapper = passthrough .NewMapper ()
246+ }
247+
230248 return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
231- rw := responseWrapper {w , 200 , []byte {}}
232- switch s .EventType {
233- case "API_GATEWAY" :
234- apiGateway .Request (r )
235- h .ServeHTTP (& rw , r )
236- apiGateway .Response (w , rw .StatusCode , rw .Body )
237- default :
238- h .ServeHTTP (w , r )
249+ rw := responseWrapper {
250+ ResponseWriter : w ,
239251 }
252+ mapper .Request (r )
253+ h .ServeHTTP (& rw , r )
254+ mapper .Response (w , rw .StatusCode , rw .Body )
240255 })
241256}
242257
@@ -266,23 +281,21 @@ func api() error {
266281}
267282
268283func main () {
269- tasks = make (chan message , 100 )
270- results = make (map [string ]chan message )
271- defer close (tasks )
272-
273284 var spec Specification
274-
275- err := envconfig .Process ("" , & spec )
276- if err != nil {
285+ if err := envconfig .Process ("" , & spec ); err != nil {
277286 log .Fatalf ("Cannot process env variables: %v" , err )
278287 }
279288 log .Printf ("%+v\n " , spec )
280289
281- log .Println ("Setup app env" )
290+ log .Println ("Setting up runtime env" )
282291 if err := spec .setupEnv (); err != nil {
283292 log .Fatalf ("Cannot setup runime env: %v" , err )
284293 }
285294
295+ tasks = make (chan message , 100 )
296+ results = make (map [string ]chan message )
297+ defer close (tasks )
298+
286299 log .Println ("Starting API" )
287300 go func () {
288301 if err := api (); err != nil {
@@ -307,7 +320,7 @@ func main() {
307320 taskHandler := http .HandlerFunc (spec .newTask )
308321 taskRouter .Handle ("/" , spec .mapEvent (taskHandler ))
309322 log .Println ("Listening..." )
310- err = http .ListenAndServe (":" + spec .ExternalAPIport , taskRouter )
323+ err : = http .ListenAndServe (":" + spec .ExternalAPIport , taskRouter )
311324 if err != nil && err != http .ErrServerClosed {
312325 log .Fatalf ("Runtime external API error: %v" , err )
313326 }
0 commit comments