pubsub_tie 0.0.1 → 1.2.0

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: 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: []