materialist 3.2.0 → 3.3.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
  SHA1:
3
- metadata.gz: 8665cde57cae1468db10b2d04ca02ee83baccef5
4
- data.tar.gz: a2fe18fbfdb6e1aa039b3c1dc9a5c7150e67acf0
3
+ metadata.gz: f551f35e47a806f9f5e3b475feb35358f4a034b5
4
+ data.tar.gz: 8134a56b74346d367618b99b09604c0ded38a815
5
5
  SHA512:
6
- metadata.gz: c630af56d05969a23fc7a19149b588eeda385e4d30f494f123ef7cc8f4971f7352fab65b81b6d92cbba919fe3d3e4a68bfa886638854b3997bff05836a224cc8
7
- data.tar.gz: 330d44afc53a5214e4e95a3a5335f0fb83c3559fbdfd79d1ae215a030337269a6db68c48f277f216eb8fda2ce76144b742dda34290a37fd4559b8147765781b5
6
+ metadata.gz: 2a647bde4177b45a090e8a91a1a34b1dde10f1ac38adbe8d1588c161182113cd8f065511edd59f08a82e38721ebaa1260650af9840d4e1f032160a4739561af1
7
+ data.tar.gz: c660872899ce6526370260e7852d886ecd34abf2a4c0cdaf7178b11680c524db318ade68d8640ce00aa2a50630158f4242f20eec20f79b49f496b877c6a0c678
data/README.md CHANGED
@@ -75,8 +75,9 @@ end
75
75
 
76
76
  - `topics` (only when using in `.subscribe`): A string array of topics to be used.
77
77
  If not provided nothing would be materialized.
78
- - `sidekiq_options` (optional, default: `{ retry: 10 }`) -- See [Sidekiq docs](https://github.com/mperham/sidekiq/wiki/Advanced-Options#workers) for list of optiosn
78
+ - `sidekiq_options` (optional, default: `{ retry: 10 }`) -- See [Sidekiq docs](https://github.com/mperham/sidekiq/wiki/Advanced-Options#workers) for list of options
79
79
  - `metrics_client` (optional) -- You can pass your `STATSD` instance
80
+ - `notice_error` (optional) -- You can pass a lambda accepting two parameters (`exception` and `event`) -- Typical use case is to enrich error and send to NewRelic APM
80
81
 
81
82
  ### Routemaster Configuration
82
83
 
@@ -160,8 +161,8 @@ Here is what each part of the DSL mean:
160
161
 
161
162
  #### `sidekiq_options <options>`
162
163
  allows to override options for the Sidekiq job which does the materialization.
163
- Typically it will specify which queue to put the job on or how many times
164
- should the job try to retry. These options override the options specified in
164
+ Typically it will specify which queue to put the job on or how many times
165
+ should the job try to retry. These options override the options specified in
165
166
  `Materialist.configuration.sidekiq_options`.
166
167
 
167
168
  #### `persist_to <model_name>`
@@ -180,6 +181,14 @@ describes mapping a resource key to a database column.
180
181
  #### `capture_link_href <key>, as: <column>`
181
182
  describes mapping a link href (as it appears on the hateous response) to a database column.
182
183
 
184
+ You can optionally provide a block for parsing the url:
185
+
186
+ ```ruby
187
+ capture_link_href :rider, as: :rider_id do |url|
188
+ url.split('/').last
189
+ end
190
+ ```
191
+
183
192
  #### `link <key>, enable_caching: <enable_caching> (default: false)`
184
193
  describes materializing from a relation of the resource. This can be nested to any depth as shown above.
185
194
 
data/RELEASE_NOTES.md CHANGED
@@ -1,8 +1,18 @@
1
+ ## Next
2
+
3
+ _description of next release_
4
+
5
+ ## 3.3.0
6
+
7
+ Features:
8
+ - Add support for parsing url when using `capture_link_href`
9
+ - Add support for providing `notice_error` on configuration.
10
+
1
11
  ## 3.2.0
2
12
 
3
13
  Features:
4
14
  - For linked resources specified by `link` an option to `enable_caching` can now be explicitly set. This
5
- tells Routemaster to use or not use the drain cache.
15
+ tells Routemaster to use or not use the drain cache.
6
16
 
7
17
  ## 3.1.0
8
18
 
@@ -12,8 +22,8 @@ Features:
12
22
 
13
23
  Notes:
14
24
 
15
- Materialist::EventWorker has been moved to Materialist::Workers::Event, but the original has
16
- been left there for backwards compatibility. It will be removed in a later major release.
25
+ Materialist::EventWorker has been moved to Materialist::Workers::Event, but the original has
26
+ been left there for backwards compatibility. It will be removed in a later major release.
17
27
 
18
28
  ## 3.0.0
19
29
 
data/lib/configuration.rb CHANGED
@@ -14,12 +14,13 @@ module Materialist
14
14
  end
15
15
 
16
16
  class Configuration
17
- attr_accessor :topics, :sidekiq_options, :metrics_client
17
+ attr_accessor :topics, :sidekiq_options, :metrics_client, :notice_error
18
18
 
19
19
  def initialize
20
20
  @topics = []
21
21
  @sidekiq_options = {}
22
22
  @metrics_client = NullMetricsClient
23
+ @notice_error = nil
23
24
  end
24
25
 
25
26
  class NullMetricsClient
data/lib/materialist.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require_relative './configuration'
2
2
 
3
3
  module Materialist
4
- VERSION = '3.2.0'
4
+ VERSION = '3.3.0'
5
5
  end
@@ -10,8 +10,12 @@ module Materialist
10
10
  __materialist_dsl_mapping_stack.last << FieldMapping.new(key: key, as: as)
11
11
  end
12
12
 
13
- def capture_link_href(key, as:)
14
- __materialist_dsl_mapping_stack.last << LinkHrefMapping.new(key: key, as: as)
13
+ def capture_link_href(key, as:, &url_parser_block)
14
+ __materialist_dsl_mapping_stack.last << LinkHrefMapping.new(
15
+ key: key,
16
+ as: as,
17
+ url_parser: url_parser_block
18
+ )
15
19
  end
16
20
 
17
21
  def link(key, enable_caching: false)
@@ -7,7 +7,9 @@ module Materialist
7
7
  @as = as
8
8
  end
9
9
 
10
- attr_reader :key, :as
10
+ def map(resource)
11
+ { @as => resource.body[@key] }
12
+ end
11
13
  end
12
14
  end
13
15
  end
@@ -2,12 +2,22 @@ module Materialist
2
2
  module Materializer
3
3
  module Internals
4
4
  class LinkHrefMapping
5
- def initialize(key:, as:)
5
+ def initialize(key:, as:, url_parser: nil)
6
6
  @key = key
7
7
  @as = as
8
+ @url_parser = url_parser
8
9
  end
9
10
 
10
- attr_reader :key, :as
11
+ def map(resource)
12
+ return unless link = resource.body._links[@key]
13
+ { @as => url_parser.call(link.href) }
14
+ end
15
+
16
+ private
17
+
18
+ def url_parser
19
+ @url_parser || ->url { url }
20
+ end
11
21
  end
12
22
  end
13
23
  end
@@ -8,7 +8,22 @@ module Materialist
8
8
  @mapping = []
9
9
  end
10
10
 
11
- attr_reader :key, :enable_caching, :mapping
11
+ def map(resource)
12
+ return unless linked_resource = linked_resource(resource)
13
+ mapping.map{ |m| m.map(linked_resource) }.compact.reduce(&:merge)
14
+ end
15
+
16
+ attr_reader :mapping
17
+
18
+ private
19
+
20
+ def linked_resource(resource)
21
+ return unless resource.body._links.include?(@key)
22
+ return unless sub_resource = resource.send(@key)
23
+ sub_resource.show(enable_caching: @enable_caching)
24
+ rescue Routemaster::Errors::ResourceNotFound
25
+ nil
26
+ end
12
27
  end
13
28
  end
14
29
  end
@@ -75,7 +75,7 @@ module Materialist
75
75
  })
76
76
  end
77
77
 
78
- def mapping
78
+ def mappings
79
79
  options.fetch :mapping
80
80
  end
81
81
 
@@ -112,49 +112,17 @@ module Materialist
112
112
  end
113
113
 
114
114
  def attributes
115
- build_attributes root_resource, mapping
115
+ mappings.map{ |m| m.map(root_resource) }.compact.reduce(&:merge) || {}
116
116
  end
117
117
 
118
118
  def root_resource
119
- @_root_resource ||= resource_at(url)
120
- end
121
-
122
- def build_attributes(resource, mapping)
123
- return {} unless resource
124
-
125
- mapping.inject({}) do |result, m|
126
- case m
127
- when FieldMapping
128
- result.tap { |r| r[m.as] = resource.body[m.key] }
129
- when LinkHrefMapping
130
- result.tap do |r|
131
- if resource.body._links.include?(m.key)
132
- r[m.as] = resource.body._links[m.key].href
133
- end
134
- end
135
- when LinkMapping
136
- resource.body._links.include?(m.key) ?
137
- result.merge(build_attributes(linked_resource(resource, m), m.mapping || [])) :
138
- result
139
- else
140
- result
141
- end
119
+ @_root_resource ||= begin
120
+ api_client.get(url, options: { enable_caching: false })
121
+ rescue Routemaster::Errors::ResourceNotFound
122
+ nil
142
123
  end
143
124
  end
144
125
 
145
- def linked_resource(resource, mapping)
146
- resource_at(resource.send(mapping.key).url, enable_caching: mapping.enable_caching)
147
- end
148
-
149
- def resource_at(url, enable_caching: false)
150
- api_client.get(url, options: { enable_caching: enable_caching })
151
- rescue Routemaster::Errors::ResourceNotFound
152
- # this is due to a race condition between an upsert event
153
- # and a :delete event
154
- # when this happens we should silently ignore the case
155
- nil
156
- end
157
-
158
126
  def api_client
159
127
  @_api_client ||= Routemaster::APIClient.new(
160
128
  response_class: Routemaster::Responses::HateoasResponse
@@ -16,8 +16,9 @@ module Materialist
16
16
 
17
17
  report_latency(topic, timestamp) if timestamp
18
18
  report_stats(topic, action, :success)
19
- rescue
19
+ rescue Exception => exception
20
20
  report_stats(topic, action, :failure)
21
+ notice_error(exception, event)
21
22
  raise
22
23
  end
23
24
 
@@ -38,6 +39,11 @@ module Materialist
38
39
  tags: ["action:#{action}", "topic:#{topic}"]
39
40
  )
40
41
  end
42
+
43
+ def notice_error(exception, event)
44
+ return unless handler = Materialist.configuration.notice_error
45
+ handler.call(exception, event)
46
+ end
41
47
  end
42
48
  end
43
49
  end
@@ -15,6 +15,9 @@ RSpec.describe Materialist::Materializer do
15
15
  capture :name
16
16
  capture :age, as: :how_old
17
17
  capture_link_href :city, as: :city_url
18
+ capture_link_href :city, as: :city_id do |url|
19
+ url.split('/').last.to_i
20
+ end
18
21
  capture_link_href :account, as: :account_url
19
22
 
20
23
  materialize_link :city
@@ -81,6 +84,8 @@ RSpec.describe Materialist::Materializer do
81
84
  expect(inserted.timezone).to eq city_body[:timezone]
82
85
  expect(inserted.country_tld).to eq country_body[:tld]
83
86
  expect(inserted.account_url).to be_nil
87
+ expect(inserted.city_url).to eq city_url
88
+ expect(inserted.city_id).to eq 1
84
89
  end
85
90
 
86
91
  it "materializes linked record separately in db" do
@@ -48,6 +48,20 @@ RSpec.describe Materialist::Workers::Event do
48
48
  )
49
49
  expect{ perform }.to raise_error error
50
50
  end
51
+
52
+ context 'when there is notice_error configured' do
53
+ let(:configuration) { Materialist::Configuration.new.tap{ |c| c.notice_error = func } }
54
+ let(:func) { double }
55
+
56
+ before do
57
+ allow(Materialist).to receive(:configuration).and_return configuration
58
+ end
59
+
60
+ it 'calls the configured notice_error func' do
61
+ expect(func).to receive(:call).with(error, event)
62
+ expect{ perform }.to raise_error error
63
+ end
64
+ end
51
65
  end
52
66
 
53
67
  context 'when event has a timestamp' do
data/spec/schema.rb CHANGED
@@ -9,6 +9,7 @@ ActiveRecord::Schema.define do
9
9
  t.string :timezone
10
10
  t.string :country_tld
11
11
  t.string :city_url
12
+ t.integer :city_id
12
13
  t.string :account_url
13
14
 
14
15
  t.timestamps
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: materialist
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mo Valipour
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-16 00:00:00.000000000 Z
11
+ date: 2018-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sidekiq