pubsub_tie 0.0.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a07811f6de7eee6628bff537126ed2186da058002ec43d2f5789278869a2b739
4
- data.tar.gz: 5bfe2ac42674e2720d3aaf4cf5262befc892eb62d8959ffed827a90a49aa33a8
3
+ metadata.gz: f673dc8804cbb711aa151d451496056a4417d94769fac0142205e2cfc6f78ec2
4
+ data.tar.gz: 185e12f5bffdf2aa5b7dae0d6b1bc1fe4da289ed35aba4af69058d86cf7e6b7f
5
5
  SHA512:
6
- metadata.gz: e6eb7e15aa40bb9c19ceee94430269d256c5c0e36a4e02d4fe8a0387ea39c99590890e818ff5fc7b15d8fd4453770c9a9ab5e2ca144e992b7e37cd4e60d3cc93
7
- data.tar.gz: 164bdc7080b020257cf852618dcd75540102767cd18bf84d1dd20510d1c626bf4b0f103f20255072b41af972641bff2aa33ef7af804513b8d18eabbc1dffce55
6
+ metadata.gz: 45a3dbb90f68c21a285256a437b813800b99c12f233dace9920b277165840806c139bb2b778ef2661b260c4f697681e8dc5c57acc82af46bef3e29e8de4f6eef
7
+ data.tar.gz: 3f0975364b5c50b81101ec3c30b09d1d0e702c3807e0ada1f26d4e760b2a89e2b3f90dff1ada7cd660356c4520c56ddc5fdcf0bcd2aa62959d2416fa60a1c3a1
data/lib/pubsub_tie.rb CHANGED
@@ -39,6 +39,10 @@ module PubSubTie
39
39
  def publish(topic, data, resource: nil)
40
40
  Publisher.publish(topic, data, resource)
41
41
  end
42
+
43
+ def batch(topic, data, resource: nil)
44
+ Publisher.batch(topic, data, resource)
45
+ end
42
46
  end
43
47
 
44
48
  require 'pubsub_tie/railtie' if defined? Rails::Railtie
@@ -7,25 +7,47 @@ module PubSubTie
7
7
 
8
8
  evs = config['events'].map{|e| e['name']}
9
9
  @events = Hash[evs.map(&:to_sym).zip(config['events'])]
10
+ @events.each do |k, evt|
11
+ fields = (evt['required'] || []) +
12
+ (evt['optional'] || []) +
13
+ (evt['repeated'] || [])
14
+ evt['fields'] = Hash[ fields.map {|f| [f['name'], f['type']]} ]
15
+ end
10
16
  end
11
17
 
12
18
  # Full event name from symbol protecting from typos
13
19
  # Raises KeyError if bad symbol
20
+ def full_name(sym)
21
+ "#{@prefix}-#{name(sym)}"
22
+ end
23
+
14
24
  def name(sym)
15
- "#{@prefix}-#{value(sym, 'name')}"
25
+ value(sym, 'name')
16
26
  end
17
27
 
18
28
  def required(sym)
19
- (value(sym, 'required') || []).map(&:to_sym)
29
+ field_names(sym, 'required')
20
30
  end
21
31
 
22
32
  def optional(sym)
23
- (value(sym, 'optional') || []).map(&:to_sym)
33
+ field_names(sym, 'optional') + repeated(sym)
34
+ end
35
+
36
+ def repeated(sym)
37
+ field_names(sym, 'repeated')
38
+ end
39
+
40
+ def types(sym)
41
+ value(sym, 'fields')
24
42
  end
25
43
 
26
44
  private
27
45
  def value(sym, key)
28
46
  @events.fetch(sym)[key]
29
47
  end
48
+
49
+ def field_names(sym, mode)
50
+ (value(sym, mode) || []).map {|field| field['name'].to_sym}
51
+ end
30
52
  end
31
53
  end
@@ -16,21 +16,44 @@ module PubSubTie
16
16
  credentials: creds)
17
17
  end
18
18
 
19
- def publish(topic_sym, data, resource)
19
+ #
20
+ # Publishes event data asynchronously to topic inferred from event_sym.
21
+ # Data is augmented with event_name and event_time and validated against
22
+ # loaded configuration
23
+ #
24
+ def publish(event_sym, data, resource)
25
+ message = augmented(data, event_sym)
26
+
20
27
  @pubsub.
21
- topic(Events.name topic_sym).
22
- # publish(message(data, resource), publish_time: Time.now.utc)
23
- publish_async(message(validate_data(topic_sym, data), resource),
28
+ topic(Events.full_name event_sym).
29
+ # publish(message(payload, resource), publish_time: Time.now.utc)
30
+ publish_async(payload(validate_data(event_sym, message), resource),
24
31
  publish_time: Time.now.utc) do |result|
25
32
  unless result.succeeded?
26
33
  Rails.logger.error(
27
- "Failed to publish #{data} to #{topic_name} on #{resource} due to #{result.error}")
34
+ "Failed to publish #{message} to #{event_sym} on #{resource} due to #{result.error}")
35
+ end
36
+ end
37
+ end
38
+
39
+ def batch(event_sym, messages, resource)
40
+ topic = @pubsub.
41
+ topic(Events.full_name event_sym)
42
+ messages.each do |data|
43
+ message = augmented(data, event_sym)
44
+ topic.publish_async(payload(validate_data(event_sym, message), resource),
45
+ publish_time: Time.now.utc) do |result|
46
+ unless result.succeeded?
47
+ Rails.logger.error(
48
+ "Failed to publish #{message} to #{event_sym} on #{resource} due to #{result.error}")
28
49
  end
29
50
  end
51
+ end
52
+ topic.async_publisher.stop.wait!
30
53
  end
31
54
 
32
55
  private
33
- def message(data, resource)
56
+ def payload(data, resource)
34
57
  # TODO: embed resource in message
35
58
  data.to_json
36
59
  end
@@ -42,11 +65,51 @@ module PubSubTie
42
65
  "Missing event required args for #{sym}: #{missing}")
43
66
  end
44
67
 
45
- data.slice(*(Events.required(sym) + Events.optional(sym)))
68
+ validate_types(sym,
69
+ data.slice(*(Events.required(sym) + Events.optional(sym))))
46
70
  end
47
71
 
48
72
  def missing_required(sym, data)
49
73
  Events.required(sym) - data.keys
50
74
  end
75
+
76
+ def augmented(data, event_sym)
77
+ {event_name: Events.name(event_sym),
78
+ event_time: Time.current.utc}.merge(data.to_hash.to_options)
79
+ end
80
+
81
+ def validate_types(sym, data)
82
+ data.each do |field, val|
83
+ validate_type(field, val, data, sym)
84
+ end
85
+
86
+ data
87
+ end
88
+
89
+ def validate_type(field, val, data, sym)
90
+ types = Events.types(sym)
91
+
92
+ case val
93
+ when String
94
+ bad_type(field, data) unless types[field.to_s] == "STRING"
95
+ when Integer
96
+ bad_type(field, data) unless ["INT", "FLOAT", "INT64", "SMALLINT", "INTEGER", "BIGINT", "TINYINT", "BYTEINT"].include? types[field.to_s]
97
+ when Numeric
98
+ bad_type(field, data) unless ["DECIMAL", "BIGDECIMAL", "FLOAT", "FLOAT64"].include? types[field.to_s]
99
+ when Time
100
+ bad_type(field, data) unless types[field.to_s] == "TIMESTAMP"
101
+ when DateTime
102
+ bad_type(field, data) unless types[field.to_s] == "DATETIME"
103
+ when Array
104
+ bad_type(field, data) unless Events.repeated(sym).include? field
105
+ val.each {|elem| validate_type(field, elem, data, sym) }
106
+ else
107
+ bad_type(field, data)
108
+ end
109
+ end
110
+
111
+ def bad_type(field, data)
112
+ raise ArgumentError.new("Bad type for field #{field} in event #{data}")
113
+ end
51
114
  end
52
115
  end
@@ -1,3 +1,3 @@
1
1
  module PubSubTie
2
- VERSION = "0.0.1"
2
+ VERSION = "1.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pubsub_tie
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pablo Calderon
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-22 00:00:00.000000000 Z
11
+ date: 2021-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-cloud-pubsub
@@ -24,34 +24,48 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: '10.0'
47
+ version: '13.0'
34
48
  type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: '10.0'
54
+ version: '13.0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: '1.16'
61
+ version: 2.1.4
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: '1.16'
68
+ version: 2.1.4
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rspec
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -82,7 +96,7 @@ homepage: https://github.com/ClipInteractive/pubsub-tie
82
96
  licenses:
83
97
  - MIT
84
98
  metadata: {}
85
- post_install_message:
99
+ post_install_message:
86
100
  rdoc_options: []
87
101
  require_paths:
88
102
  - lib
@@ -97,8 +111,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
111
  - !ruby/object:Gem::Version
98
112
  version: '0'
99
113
  requirements: []
100
- rubygems_version: 3.0.3
101
- signing_key:
114
+ rubygems_version: 3.1.4
115
+ signing_key:
102
116
  specification_version: 4
103
117
  summary: Hook for Google PubSub for publication of events enforcing autoimposed rules
104
118
  test_files: []