fdk 0.0.8 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8958c018c5730c72cf314b69f19e7930ba7995fb3b1dddb3b012ebcf66dc6171
4
- data.tar.gz: 915b07e47c9f919333e380d919f46abcc50a624bdae77153c503246f2ef61576
3
+ metadata.gz: aac4d4c8971ca0678bd3e99b95be2c87fc4aea50b9419535aee57bb09d4c0b73
4
+ data.tar.gz: 3fdf4848e9e940facde5a247ffdaf8b418079e65dbb0ac23ae3ed7c622c1f41e
5
5
  SHA512:
6
- metadata.gz: 235b4bcf982c408099fa2f1713a4cc658af7c9ff86b61cf1e21bbd72645a39594a063f12b9d34c8e73a4b61931e6825f3f8411cd92dc0ede3d03406cd1e201d7
7
- data.tar.gz: 5f506adf41f2df8e0d719b96162c438f8fec6dc118ea10bb8e08927cf9cda73b58ed3a9b35cae8ae7ca01f04e365a5ead1df5969b584e25519c600dbedb50e96
6
+ metadata.gz: 021b616d4b4cfd8c49b45f4d6c97d52fc04aaa2dab3756c5d927f76f54dbce304f32cf4a2bdba2ef43462fe0038e3bcab0ddbec53d12a3217fdba7a77c0baaf2
7
+ data.tar.gz: c07e62e577f503dc5ca974be179dc878aac12306fde3603c6623709d68c46fea09811ed3606a949123dc14be2110f653f1682650568c05e85bea00abe4e6253c
data/README.md CHANGED
@@ -13,7 +13,7 @@ require 'fdk`
13
13
  Then create a function with with the following syntax:
14
14
 
15
15
  ```ruby
16
- def myfunc(context, input)
16
+ def myfunc(context, input)
17
17
  # Do some work here
18
18
  return output
19
19
  end
@@ -28,7 +28,7 @@ end
28
28
  Then simply pass that function to the FDK:
29
29
 
30
30
  ```ruby
31
- FDK.call(myfunc)
31
+ FDK.handle(myfunction)
32
32
  ```
33
33
 
34
34
  ## Full Example
@@ -36,22 +36,39 @@ FDK.call(myfunc)
36
36
  ```ruby
37
37
  require 'fdk'
38
38
 
39
- def myhandler(context, input)
39
+ def myfunction(context:, input:)
40
40
  STDERR.puts "request_url: " + context.protocol['request_url']
41
41
  STDERR.puts "call_id: " + context.call_id
42
42
  STDERR.puts "input: " + input.to_s
43
- return {message: "Hello " + input['name'].to_s + "!"}
43
+ { message: "Hello #{input['name']}!" }
44
44
  end
45
45
 
46
- FDK.handle(:myhandler)
46
+ FDK.handle(:myfunction)
47
47
  ```
48
48
 
49
49
  ## Running the example that is in the root directory of this repo
50
50
 
51
51
  ```sh
52
- echo '{"name":"coolio"}' | fn run
52
+ $ echo '{"name":"coolio"}' | fn run
53
+ {"message":"Hello coolio!"}
53
54
  ```
54
55
 
56
+ You can also specify the format (the default is JSON)
57
+
58
+ ```sh
59
+ $ echo '{"name":"coolio"}' | fn run --format json
60
+ {"message":"Hello coolio!"}
61
+ ```
62
+
63
+ If you want to just pass plain text to the function, specify a format of __default__:
64
+
65
+ ```sh
66
+ $ echo 'coolio' | fn run --format default
67
+ {"message":"Hello coolio!"}
68
+ ```
69
+
70
+ Deploy:
71
+
55
72
  ```sh
56
73
  fn deploy --app myapp --local && echo '{"name":"coolio"}' | fn call myapp /fdk-ruby
57
74
  ```
@@ -1,52 +1,56 @@
1
1
  module FDK
2
2
 
3
- # Config looks up values in the env vars
4
- class Config
5
- def [](key)
6
- return ENV[key.upcase]
7
- end
3
+ # Config looks up values in the env vars
4
+ class Config
5
+ def [](key)
6
+ ENV[key.upcase]
8
7
  end
8
+ end
9
9
 
10
- class Context
10
+ class Context
11
11
 
12
- # TODO: Rethink FN_PATH, if it's a reference to the route, maybe it should be FN_ROUTE? eg: if it's a dynamic path, this env var would
13
- # show the route's path (ie: route identifier), eg: /users/:name, not the actual path.
12
+ # TODO: Rethink FN_PATH, if it's a reference to the route, maybe it should be FN_ROUTE? eg: if it's a dynamic path, this env var would
13
+ # show the route's path (ie: route identifier), eg: /users/:name, not the actual path.
14
14
 
15
- # FN_REQUEST_URL - the full URL for the request (parsing example)
16
- # FN_APP_NAME - the name of the application that matched this route, eg: myapp
17
- # FN_PATH - the matched route, eg: /hello
18
- # FN_METHOD - the HTTP method for the request, eg: GET or POST
19
- # FN_CALL_ID - a unique ID for each function execution.
20
- # FN_FORMAT - a string representing one of the function formats, currently either default or http. Default is default.
21
- # FN_MEMORY - a number representing the amount of memory available to the call, in MB
22
- # FN_TYPE - the type for this call, currently 'sync' or 'async'
23
- # FN_HEADER_$X - the HTTP headers that were set for this request. Replace $X with the upper cased name of the header and replace dashes in the header with underscores.
24
- # $X - any configuration values you've set for the Application or the Route. Replace X with the upper cased name of the config variable you set. Ex: minio_secret=secret will be exposed via MINIO_SECRET env var.
25
- # FN_PARAM_$Y
15
+ # FN_REQUEST_URL - the full URL for the request (parsing example)
16
+ # FN_APP_NAME - the name of the application that matched this route, eg: myapp
17
+ # FN_PATH - the matched route, eg: /hello
18
+ # FN_METHOD - the HTTP method for the request, eg: GET or POST
19
+ # FN_CALL_ID - a unique ID for each function execution.
20
+ # FN_FORMAT - a string representing one of the function formats, currently either default or http. Default is default.
21
+ # FN_MEMORY - a number representing the amount of memory available to the call, in MB
22
+ # FN_TYPE - the type for this call, currently 'sync' or 'async'
23
+ # FN_HEADER_$X - the HTTP headers that were set for this request. Replace $X with the upper cased name of the header and replace dashes in the header with underscores.
24
+ # $X - any configuration values you've set for the Application or the Route. Replace X with the upper cased name of the config variable you set. Ex: minio_secret=secret will be exposed via MINIO_SECRET env var.
25
+ # FN_PARAM_$Y
26
26
 
27
- attr_reader :payload, :config
27
+ # CloudEvent format: https://github.com/cloudevents/spec/blob/master/serialization.md#json
28
28
 
29
- def initialize(payload)
30
- @payload = payload
31
- end
29
+ attr_reader :event
32
30
 
33
- def config
34
- return @config if @config
35
- @config = Config.new
36
- return @config
37
- end
31
+ def initialize(event)
32
+ @event = event
33
+ end
34
+
35
+ # If it's a CNCF CloudEvent
36
+ def cloud_event?
37
+ ENV['FN_FORMAT'] == "cloudevent"
38
+ end
38
39
 
39
- def call_id
40
- payload['call_id']
41
- end
40
+ def config
41
+ @config ||= Config.new
42
+ end
42
43
 
43
- def content_type
44
- payload['content_type']
45
- end
44
+ def call_id
45
+ cloud_event? ? event['eventID'] : event['call_id']
46
+ end
46
47
 
47
- def protocol
48
- payload['protocol']
49
- end
48
+ def content_type
49
+ cloud_event? ? event['contentType'] : event['content_type']
50
+ end
50
51
 
52
+ def protocol
53
+ cloud_event? ? event['extensions']['protocol'] : event['protocol']
51
54
  end
55
+ end
52
56
  end
@@ -3,123 +3,74 @@
3
3
  # Responds with output
4
4
 
5
5
  require 'json'
6
+ require 'yajl'
6
7
 
7
8
  module FDK
9
+ def self.handle(func)
10
+ format = ENV['FN_FORMAT']
11
+ if format == 'cloudevent'
12
+ parser = Yajl::Parser.new
8
13
 
9
- def self.handle(func)
10
- # STDERR.puts `env`
11
- format = ENV['FN_FORMAT']
12
- if format == "json"
13
- obs = ""
14
- first_bracket = false
15
- # end_bracket=false
16
- stack_count = 0
17
- STDIN.each_char do |c|
18
- # STDERR.puts "c: #{c}"
19
- if c == '{'
20
- if !first_bracket
21
- # STDERR.puts "setting first_bracket"
22
- first_bracket = true
23
- end
24
- stack_count += 1
25
- elsif c == '}'
26
- stack_count -= 1
27
- end
28
- if first_bracket
29
- # STDERR.puts "in first_bracket stack_count: #{stack_count}"
30
- obs += c
31
- if stack_count == 0 # found last bracket, so close this out
32
- # STDERR.puts "OBJECT: #{obs}"
33
- payload = JSON.parse(obs)
34
- # STDERR.puts "payload: #{payload.inspect}"
35
- ctx = Context.new(payload)
36
- # STDERR.puts "context: " + ctx.inspect
37
- # STDERR.flush
38
- body = payload['body']
39
- if ctx.content_type == 'application/json' && body != ""
40
- body = JSON.parse(body)
41
- end
42
- # TODO: begin/rescue so we can respond with proper error response and code
43
- se = FDK.single_event(func, ctx, body)
44
- response = {
45
- headers: {
46
- 'Content-Type' => 'application/json'
47
- },
48
- 'status_code' => 200,
49
- body: se.to_json,
50
- }
51
- STDOUT.puts response.to_json
52
- STDOUT.puts
53
- STDOUT.flush
54
- first_bracket = false
55
- obs = ""
56
- end
57
- end
58
- end
14
+ parser.on_parse_complete = lambda do |event|
15
+ context = Context.new(event)
16
+ body = event['data']
17
+ # Skipping json parsing of body because it would already be a parsed map according to the format spec defined here: https://github.com/cloudevents/spec/blob/master/serialization.md#json
18
+ se = FDK.single_event(function: func, context: context, input: body)
59
19
 
60
- # STDIN.each do |line|
61
- # STDERR.puts "LINE: --#{line}--"
62
- # STDERR.flush
63
- # ls = line.strip
64
- # STDERR.puts "ls: #{ls}"
65
- # if ls == "}"
66
- # # STDERR.puts "endbracket true"
67
- # endbracket=true
68
- # elsif ls == "" && endbracket
69
- # # TODO: this isn't very robust, probably needs to be better :/
70
- # STDERR.puts "OBJECT: #{obs}"
71
- # payload = JSON.parse(obs)
72
- # STDERR.puts "payload: #{payload.inspect}"
73
- # c = Context.new(payload)
74
- # STDERR.puts "context: " + c.inspect
75
- # STDERR.flush
76
- # body = payload['body']
77
- # if c.content_type == 'application/json'
78
- # body = JSON.parse(body)
79
- # end
80
- # # TODO: begin/rescue so we can respond with proper error response and code
81
- # s = FDK.single_event(func, c, body)
82
- # response = {
83
- # headers: {
84
- # 'Content-Type' => 'application/json'
85
- # },
86
- # 'status_code' => 200,
87
- # body: s.to_json,
88
- # }
89
- # STDOUT.puts response.to_json
90
- # STDOUT.puts
91
- # STDOUT.flush
92
- # obs = ""
93
- # next
94
- # else
95
- # endbracket = false
96
- # end
97
- # obs += line
98
- # end
99
- elsif format == "default"
100
- # TODO: check if content type json, and if so, parse it before passing it in
101
- body = STDIN.read
102
- payload = {}
103
- payload['call_id'] = ENV['FN_CALL_ID']
104
- payload['content_type'] = ENV['FN_HEADER_Content_Type']
105
- payload['protocol'] = {
106
- 'type' => 'http',
107
- 'request_url' => ENV['FN_REQUEST_URL']
108
- }
109
- # STDERR.puts "payload: #{payload}"
110
- c = Context.new(payload)
111
- if c.content_type == "application/json"
112
- # STDERR.puts "parsing json"
113
- body = JSON.parse(body)
114
- end
115
- puts FDK.single_event(func, c, body).to_json
116
- else
117
- raise "Format '#{format}' not supported in Ruby FDK."
20
+ # Respond with modified event
21
+ event['data'] = se
22
+ event['extensions']['protocol'] = {
23
+ headers: {
24
+ 'Content-Type' => ['application/json']
25
+ },
26
+ 'status_code' => 200,
27
+ }
28
+ STDOUT.puts event.to_json
29
+ STDOUT.puts
30
+ STDOUT.flush
31
+ end
32
+
33
+ STDIN.each_line { |line| parser.parse_chunk(line) }
34
+
35
+ elsif format == 'json'
36
+ parser = Yajl::Parser.new
37
+
38
+ parser.on_parse_complete = lambda do |event|
39
+ context = Context.new(event)
40
+ body = event['body']
41
+ if context.content_type == 'application/json' && body != ''
42
+ body = Yajl::Parser.parse(body)
118
43
  end
119
- end
44
+ se = FDK.single_event(function: func, context: context, input: body)
45
+ response = {
46
+ headers: {
47
+ 'Content-Type' => ['application/json']
48
+ },
49
+ 'status_code' => 200,
50
+ body: se.to_json
51
+ }
52
+ STDOUT.puts response.to_json
53
+ STDOUT.puts
54
+ STDOUT.flush
55
+ end
56
+
57
+ STDIN.each_line { |line| parser.parse_chunk(line) }
120
58
 
121
- def self.single_event(func, c, i)
122
- s = send func, c, i
123
- return s
59
+ elsif format == 'default'
60
+ event = {}
61
+ event['call_id'] = ENV['FN_CALL_ID']
62
+ event['protocol'] = {
63
+ 'type' => 'http',
64
+ 'request_url' => ENV['FN_REQUEST_URL']
65
+ }
66
+ c = Context.new(event)
67
+ puts FDK.single_event(function: func, context: c, input: STDIN.read).to_json
68
+ else
69
+ raise "Format '#{format}' not supported in Ruby FDK."
124
70
  end
71
+ end
72
+
73
+ def self.single_event(function:, context:, input:)
74
+ send function, context: context, input: input
75
+ end
125
76
  end
@@ -1,5 +1,3 @@
1
1
  module FDK
2
-
3
- VERSION = "0.0.8"
4
-
5
- end
2
+ VERSION = "0.0.10"
3
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Travis Reeder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-02 00:00:00.000000000 Z
11
+ date: 2018-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json