cloud_events 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +3 -3
- data/lib/cloud_events/content_type.rb +2 -2
- data/lib/cloud_events/event/field_interpreter.rb +22 -44
- data/lib/cloud_events/event/utils.rb +51 -0
- data/lib/cloud_events/event/v0.rb +9 -4
- data/lib/cloud_events/event/v1.rb +9 -4
- data/lib/cloud_events/http_binding.rb +17 -9
- data/lib/cloud_events/json_format.rb +3 -4
- data/lib/cloud_events/version.rb +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 561f1577a53c99db91573da43e0caa899add4388169a8c4784910dbfb3ae94d7
|
4
|
+
data.tar.gz: eb936cd23fbbd2b2658ec8a5c52ad5857c50b8f81019e15f341bdeb89346d037
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c702c7b33d247b38c9ef8c46dc0d0ef3253d5ffe5d6e8ba7ba6043a0d0f597b748c40514bbe94f0836c150d5f7336e67005f550bbabe6ecfefd73b6f9925ff0
|
7
|
+
data.tar.gz: f765051aec3c216b36eafdd082f771701d8647d7c4cead2489a61370fb598390fb5d7f43b138a7ab0af91a039d4a88e36c9f4897e91d37650220b474260c9d3d
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -17,7 +17,7 @@ Features:
|
|
17
17
|
specifications.
|
18
18
|
* Extensible to additional formats and protocol bindings, and future
|
19
19
|
specification versions.
|
20
|
-
* Compatible with Ruby 2.
|
20
|
+
* Compatible with Ruby 2.5 or later, or JRuby 9.2.x or later. No runtime gem
|
21
21
|
dependencies.
|
22
22
|
|
23
23
|
## Quickstart
|
@@ -35,7 +35,7 @@ A simple [Sinatra](https://sinatrarb.com) app that receives CloudEvents:
|
|
35
35
|
```ruby
|
36
36
|
# examples/server/Gemfile
|
37
37
|
source "https://rubygems.org"
|
38
|
-
gem "cloud_events", "~> 0.
|
38
|
+
gem "cloud_events", "~> 0.2"
|
39
39
|
gem "sinatra", "~> 2.0"
|
40
40
|
```
|
41
41
|
|
@@ -59,7 +59,7 @@ A simple Ruby script that sends a CloudEvent:
|
|
59
59
|
```ruby
|
60
60
|
# examples/client/Gemfile
|
61
61
|
source "https://rubygems.org"
|
62
|
-
gem "cloud_events", "~> 0.
|
62
|
+
gem "cloud_events", "~> 0.2"
|
63
63
|
```
|
64
64
|
|
65
65
|
```ruby
|
@@ -140,7 +140,7 @@ module CloudEvents
|
|
140
140
|
end
|
141
141
|
|
142
142
|
def consume_token str, downcase: false, error_message: nil
|
143
|
-
match = /^([\w
|
143
|
+
match = /^([\w!#$%&'*+.\^`{|}-]+)(.*)$/.match str
|
144
144
|
raise ParseError, error_message || "Expected token" unless match
|
145
145
|
token = match[1]
|
146
146
|
token.downcase! if downcase
|
@@ -203,7 +203,7 @@ module CloudEvents
|
|
203
203
|
end
|
204
204
|
|
205
205
|
def maybe_quote str
|
206
|
-
return str if /^[\w
|
206
|
+
return str if /^[\w!#$%&'*+.\^`{|}-]+$/ =~ str
|
207
207
|
str = str.gsub("\\", "\\\\\\\\").gsub("\"", "\\\\\"")
|
208
208
|
"\"#{str}\""
|
209
209
|
end
|
@@ -1,15 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "cloud_events/event/utils"
|
4
|
+
|
3
5
|
module CloudEvents
|
4
6
|
module Event
|
5
7
|
##
|
6
8
|
# A helper that extracts and interprets event fields from an input hash.
|
7
|
-
#
|
8
9
|
# @private
|
9
10
|
#
|
10
11
|
class FieldInterpreter
|
11
12
|
def initialize args
|
12
|
-
@args = keys_to_strings args
|
13
|
+
@args = Utils.keys_to_strings args
|
13
14
|
@attributes = {}
|
14
15
|
end
|
15
16
|
|
@@ -26,6 +27,7 @@ module CloudEvents
|
|
26
27
|
case value
|
27
28
|
when ::String
|
28
29
|
raise AttributeError, "The #{keys.first} field cannot be empty" if value.empty?
|
30
|
+
value.freeze
|
29
31
|
[value, value]
|
30
32
|
else
|
31
33
|
raise AttributeError, "Illegal type for #{keys.first}:" \
|
@@ -40,12 +42,12 @@ module CloudEvents
|
|
40
42
|
when ::String
|
41
43
|
raise AttributeError, "The #{keys.first} field cannot be empty" if value.empty?
|
42
44
|
begin
|
43
|
-
[::URI.parse(value), value]
|
45
|
+
[Utils.deep_freeze(::URI.parse(value)), value.freeze]
|
44
46
|
rescue ::URI::InvalidURIError => e
|
45
47
|
raise AttributeError, "Illegal format for #{keys.first}: #{e.message}"
|
46
48
|
end
|
47
49
|
when ::URI::Generic
|
48
|
-
[value, value.to_s]
|
50
|
+
[Utils.deep_freeze(value), value.to_s.freeze]
|
49
51
|
else
|
50
52
|
raise AttributeError, "Illegal type for #{keys.first}:" \
|
51
53
|
" String or URI expected but #{value.class} found"
|
@@ -58,15 +60,15 @@ module CloudEvents
|
|
58
60
|
case value
|
59
61
|
when ::String
|
60
62
|
begin
|
61
|
-
[::DateTime.rfc3339(value), value]
|
63
|
+
[Utils.deep_freeze(::DateTime.rfc3339(value)), value.freeze]
|
62
64
|
rescue ::Date::Error => e
|
63
65
|
raise AttributeError, "Illegal format for #{keys.first}: #{e.message}"
|
64
66
|
end
|
65
67
|
when ::DateTime
|
66
|
-
[value, value.rfc3339]
|
68
|
+
[Utils.deep_freeze(value), value.rfc3339.freeze]
|
67
69
|
when ::Time
|
68
70
|
value = value.to_datetime
|
69
|
-
[value, value.rfc3339]
|
71
|
+
[Utils.deep_freeze(value), value.rfc3339.freeze]
|
70
72
|
else
|
71
73
|
raise AttributeError, "Illegal type for #{keys.first}:" \
|
72
74
|
" String, Time, or DateTime expected but #{value.class} found"
|
@@ -79,7 +81,7 @@ module CloudEvents
|
|
79
81
|
case value
|
80
82
|
when ::String
|
81
83
|
raise AttributeError, "The #{keys.first} field cannot be empty" if value.empty?
|
82
|
-
[ContentType.new(value), value]
|
84
|
+
[ContentType.new(value), value.freeze]
|
83
85
|
when ContentType
|
84
86
|
[value, value.to_s]
|
85
87
|
else
|
@@ -94,6 +96,7 @@ module CloudEvents
|
|
94
96
|
case value
|
95
97
|
when ::String
|
96
98
|
raise SpecVersionError, "Unrecognized specversion: #{value}" unless accept =~ value
|
99
|
+
value.freeze
|
97
100
|
[value, value]
|
98
101
|
else
|
99
102
|
raise AttributeError, "Illegal type for #{keys.first}:" \
|
@@ -102,8 +105,17 @@ module CloudEvents
|
|
102
105
|
end
|
103
106
|
end
|
104
107
|
|
108
|
+
def data_object keys, required: false
|
109
|
+
object keys, required: required, allow_nil: true do |value|
|
110
|
+
Utils.deep_freeze value
|
111
|
+
[value, value]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
105
115
|
UNDEFINED = ::Object.new.freeze
|
106
116
|
|
117
|
+
private
|
118
|
+
|
107
119
|
def object keys, required: false, allow_nil: false
|
108
120
|
value = UNDEFINED
|
109
121
|
keys.each do |key|
|
@@ -115,44 +127,10 @@ module CloudEvents
|
|
115
127
|
raise AttributeError, "The #{keys.first} field is required" if required
|
116
128
|
return nil
|
117
129
|
end
|
118
|
-
|
119
|
-
|
120
|
-
deep_freeze converted
|
121
|
-
else
|
122
|
-
converted = raw = value
|
123
|
-
end
|
124
|
-
@attributes[keys.first.freeze] = raw.freeze
|
130
|
+
converted, raw = yield value
|
131
|
+
@attributes[keys.first.freeze] = raw
|
125
132
|
converted
|
126
133
|
end
|
127
|
-
|
128
|
-
private
|
129
|
-
|
130
|
-
def deep_freeze obj
|
131
|
-
case obj
|
132
|
-
when ::Hash
|
133
|
-
obj.each do |key, val|
|
134
|
-
deep_freeze key
|
135
|
-
deep_freeze val
|
136
|
-
end
|
137
|
-
when ::Array
|
138
|
-
obj.each do |val|
|
139
|
-
deep_freeze val
|
140
|
-
end
|
141
|
-
else
|
142
|
-
obj.instance_variables.each do |iv|
|
143
|
-
deep_freeze obj.instance_variable_get iv
|
144
|
-
end
|
145
|
-
end
|
146
|
-
obj.freeze
|
147
|
-
end
|
148
|
-
|
149
|
-
def keys_to_strings hash
|
150
|
-
result = {}
|
151
|
-
hash.each do |key, val|
|
152
|
-
result[key.to_s] = val
|
153
|
-
end
|
154
|
-
result
|
155
|
-
end
|
156
134
|
end
|
157
135
|
end
|
158
136
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CloudEvents
|
4
|
+
module Event
|
5
|
+
##
|
6
|
+
# A variety of helper methods.
|
7
|
+
# @private
|
8
|
+
#
|
9
|
+
module Utils
|
10
|
+
class << self
|
11
|
+
def deep_freeze obj
|
12
|
+
case obj
|
13
|
+
when ::Hash
|
14
|
+
obj.each do |key, val|
|
15
|
+
deep_freeze key
|
16
|
+
deep_freeze val
|
17
|
+
end
|
18
|
+
when ::Array
|
19
|
+
obj.each do |val|
|
20
|
+
deep_freeze val
|
21
|
+
end
|
22
|
+
else
|
23
|
+
obj.instance_variables.each do |iv|
|
24
|
+
deep_freeze obj.instance_variable_get iv
|
25
|
+
end
|
26
|
+
end
|
27
|
+
obj.freeze
|
28
|
+
end
|
29
|
+
|
30
|
+
def deep_dup obj
|
31
|
+
case obj
|
32
|
+
when ::Hash
|
33
|
+
obj.each_with_object({}) { |(key, val), hash| hash[deep_dup key] = deep_dup val }
|
34
|
+
when ::Array
|
35
|
+
obj.map { |val| deep_dup val }
|
36
|
+
else
|
37
|
+
obj.dup
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def keys_to_strings hash
|
42
|
+
result = {}
|
43
|
+
hash.each do |key, val|
|
44
|
+
result[key.to_s] = val
|
45
|
+
end
|
46
|
+
result
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -3,6 +3,9 @@
|
|
3
3
|
require "date"
|
4
4
|
require "uri"
|
5
5
|
|
6
|
+
require "cloud_events/event/field_interpreter"
|
7
|
+
require "cloud_events/event/utils"
|
8
|
+
|
6
9
|
module CloudEvents
|
7
10
|
module Event
|
8
11
|
##
|
@@ -43,7 +46,7 @@ module CloudEvents
|
|
43
46
|
# field.
|
44
47
|
# * **:type** [`String`] - _required_ - The event `type` field.
|
45
48
|
# * **:data** [`Object`] - _optional_ - The data associated with the
|
46
|
-
# event (i.e. the `data` field.
|
49
|
+
# event (i.e. the `data` field).
|
47
50
|
# * **:data_content_encoding** (or **:datacontentencoding**)
|
48
51
|
# [`String`] - _optional_ - The content-encoding for the data (i.e.
|
49
52
|
# the `datacontentencoding` field.)
|
@@ -74,7 +77,7 @@ module CloudEvents
|
|
74
77
|
@id = interpreter.string ["id"], required: true
|
75
78
|
@source = interpreter.uri ["source"], required: true
|
76
79
|
@type = interpreter.string ["type"], required: true
|
77
|
-
@data = interpreter.
|
80
|
+
@data = interpreter.data_object ["data"]
|
78
81
|
@data_content_encoding = interpreter.string ["datacontentencoding", "data_content_encoding"]
|
79
82
|
@data_content_type = interpreter.content_type ["datacontenttype", "data_content_type"]
|
80
83
|
@schema_url = interpreter.uri ["schemaurl", "schema_url"]
|
@@ -112,6 +115,8 @@ module CloudEvents
|
|
112
115
|
# event["time"] # => String rfc3339 representation
|
113
116
|
# event.time # => DateTime object
|
114
117
|
#
|
118
|
+
# Results are also always frozen and cannot be modified in place.
|
119
|
+
#
|
115
120
|
# @param key [String,Symbol] The attribute name.
|
116
121
|
# @return [String,nil]
|
117
122
|
#
|
@@ -121,12 +126,12 @@ module CloudEvents
|
|
121
126
|
|
122
127
|
##
|
123
128
|
# Return a hash representation of this event. The returned hash is an
|
124
|
-
# unfrozen copy. Modifications do not affect the original event.
|
129
|
+
# unfrozen deep copy. Modifications do not affect the original event.
|
125
130
|
#
|
126
131
|
# @return [Hash]
|
127
132
|
#
|
128
133
|
def to_h
|
129
|
-
@attributes
|
134
|
+
Utils.deep_dup @attributes
|
130
135
|
end
|
131
136
|
|
132
137
|
##
|
@@ -3,6 +3,9 @@
|
|
3
3
|
require "date"
|
4
4
|
require "uri"
|
5
5
|
|
6
|
+
require "cloud_events/event/field_interpreter"
|
7
|
+
require "cloud_events/event/utils"
|
8
|
+
|
6
9
|
module CloudEvents
|
7
10
|
module Event
|
8
11
|
##
|
@@ -43,7 +46,7 @@ module CloudEvents
|
|
43
46
|
# field.
|
44
47
|
# * **:type** [`String`] - _required_ - The event `type` field.
|
45
48
|
# * **:data** [`Object`] - _optional_ - The data associated with the
|
46
|
-
# event (i.e. the `data` field.
|
49
|
+
# event (i.e. the `data` field).
|
47
50
|
# * **:data_content_type** (or **:datacontenttype**) [`String`,
|
48
51
|
# {ContentType}] - _optional_ - The content-type for the data, if
|
49
52
|
# the data is a string (i.e. the event `datacontenttype` field.)
|
@@ -71,7 +74,7 @@ module CloudEvents
|
|
71
74
|
@id = interpreter.string ["id"], required: true
|
72
75
|
@source = interpreter.uri ["source"], required: true
|
73
76
|
@type = interpreter.string ["type"], required: true
|
74
|
-
@data = interpreter.
|
77
|
+
@data = interpreter.data_object ["data"]
|
75
78
|
@data_content_type = interpreter.content_type ["datacontenttype", "data_content_type"]
|
76
79
|
@data_schema = interpreter.uri ["dataschema", "data_schema"]
|
77
80
|
@subject = interpreter.string ["subject"]
|
@@ -108,6 +111,8 @@ module CloudEvents
|
|
108
111
|
# event["time"] # => String rfc3339 representation
|
109
112
|
# event.time # => DateTime object
|
110
113
|
#
|
114
|
+
# Results are also always frozen and cannot be modified in place.
|
115
|
+
#
|
111
116
|
# @param key [String,Symbol] The attribute name.
|
112
117
|
# @return [String,nil]
|
113
118
|
#
|
@@ -117,12 +122,12 @@ module CloudEvents
|
|
117
122
|
|
118
123
|
##
|
119
124
|
# Return a hash representation of this event. The returned hash is an
|
120
|
-
# unfrozen copy. Modifications do not affect the original event.
|
125
|
+
# unfrozen deep copy. Modifications do not affect the original event.
|
121
126
|
#
|
122
127
|
# @return [Hash]
|
123
128
|
#
|
124
129
|
def to_h
|
125
|
-
@attributes
|
130
|
+
Utils.deep_dup @attributes
|
126
131
|
end
|
127
132
|
|
128
133
|
##
|
@@ -228,21 +228,19 @@ module CloudEvents
|
|
228
228
|
headers = {}
|
229
229
|
body = nil
|
230
230
|
event.to_h.each do |key, value|
|
231
|
-
|
231
|
+
case key
|
232
|
+
when "data"
|
232
233
|
body = value
|
233
|
-
|
234
|
+
when "datacontenttype"
|
234
235
|
headers["Content-Type"] = value
|
235
236
|
else
|
236
237
|
headers["CE-#{key}"] = percent_encode value
|
237
238
|
end
|
238
239
|
end
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
"text/plain; charset=#{body.encoding.name.downcase}"
|
244
|
-
end
|
245
|
-
elsif body.nil?
|
240
|
+
case body
|
241
|
+
when ::String
|
242
|
+
headers["Content-Type"] ||= string_content_type body
|
243
|
+
when nil
|
246
244
|
headers.delete "Content-Type"
|
247
245
|
else
|
248
246
|
body = ::JSON.dump body
|
@@ -288,5 +286,15 @@ module CloudEvents
|
|
288
286
|
end
|
289
287
|
arr.pack "C*"
|
290
288
|
end
|
289
|
+
|
290
|
+
private
|
291
|
+
|
292
|
+
def string_content_type str
|
293
|
+
if str.encoding == ::Encoding.ASCII_8BIT
|
294
|
+
"application/octet-stream"
|
295
|
+
else
|
296
|
+
"text/plain; charset=#{str.encoding.name.downcase}"
|
297
|
+
end
|
298
|
+
end
|
291
299
|
end
|
292
300
|
end
|
@@ -137,10 +137,9 @@ module CloudEvents
|
|
137
137
|
structure = event.to_h
|
138
138
|
data = event.data
|
139
139
|
content_type = event.data_content_type
|
140
|
-
if data.is_a?(::String) && !content_type.nil?
|
141
|
-
|
142
|
-
|
143
|
-
end
|
140
|
+
if data.is_a?(::String) && !content_type.nil? &&
|
141
|
+
(content_type.subtype == "json" || content_type.subtype_format == "json")
|
142
|
+
structure["data"] = ::JSON.parse data rescue data
|
144
143
|
end
|
145
144
|
structure
|
146
145
|
end
|
data/lib/cloud_events/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloud_events
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Azuma
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-03-02 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: The official Ruby implementation of the CloudEvents Specification. Provides
|
14
14
|
data types for events, and HTTP/JSON bindings for marshalling and unmarshalling
|
@@ -28,6 +28,7 @@ files:
|
|
28
28
|
- lib/cloud_events/errors.rb
|
29
29
|
- lib/cloud_events/event.rb
|
30
30
|
- lib/cloud_events/event/field_interpreter.rb
|
31
|
+
- lib/cloud_events/event/utils.rb
|
31
32
|
- lib/cloud_events/event/v0.rb
|
32
33
|
- lib/cloud_events/event/v1.rb
|
33
34
|
- lib/cloud_events/http_binding.rb
|
@@ -37,10 +38,10 @@ homepage: https://github.com/cloudevents/sdk-ruby
|
|
37
38
|
licenses:
|
38
39
|
- Apache-2.0
|
39
40
|
metadata:
|
40
|
-
changelog_uri: https://cloudevents.github.io/sdk-ruby/v0.
|
41
|
+
changelog_uri: https://cloudevents.github.io/sdk-ruby/v0.3.0/file.CHANGELOG.html
|
41
42
|
source_code_uri: https://github.com/cloudevents/sdk-ruby
|
42
43
|
bug_tracker_uri: https://github.com/cloudevents/sdk-ruby/issues
|
43
|
-
documentation_uri: https://cloudevents.github.io/sdk-ruby/v0.
|
44
|
+
documentation_uri: https://cloudevents.github.io/sdk-ruby/v0.3.0
|
44
45
|
post_install_message:
|
45
46
|
rdoc_options: []
|
46
47
|
require_paths:
|
@@ -49,7 +50,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
49
50
|
requirements:
|
50
51
|
- - ">="
|
51
52
|
- !ruby/object:Gem::Version
|
52
|
-
version: 2.
|
53
|
+
version: '2.5'
|
53
54
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
55
|
requirements:
|
55
56
|
- - ">="
|