roo_on_rails 1.20.0 → 2.1.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.
Files changed (39) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +398 -282
  3. data/.circleci/config.yml.erb +63 -21
  4. data/.codecov.yml +3 -0
  5. data/Appraisals +24 -11
  6. data/CHANGELOG.md +39 -0
  7. data/README.md +20 -31
  8. data/appraise +1 -1
  9. data/exe/roo_on_rails +5 -0
  10. data/gemfiles/rails_4.gemfile +3 -1
  11. data/gemfiles/rails_5.gemfile +2 -1
  12. data/gemfiles/rails_5_1.gemfile +3 -2
  13. data/gemfiles/rails_5_2.gemfile +15 -0
  14. data/gemfiles/{rails_3.gemfile → rails_6.gemfile} +5 -4
  15. data/lib/roo_on_rails.rb +1 -4
  16. data/lib/roo_on_rails/checks/documentation/playbook_template.md +0 -4
  17. data/lib/roo_on_rails/concerns/require_api_key.rb +0 -1
  18. data/lib/roo_on_rails/config.rb +0 -8
  19. data/lib/roo_on_rails/default.env +0 -13
  20. data/lib/roo_on_rails/rack/populate_env_from_jwt.rb +25 -4
  21. data/lib/roo_on_rails/railties/database.rb +11 -10
  22. data/lib/roo_on_rails/railties/env.rb +3 -5
  23. data/lib/roo_on_rails/railties/google_oauth.rb +4 -6
  24. data/lib/roo_on_rails/railties/http.rb +34 -32
  25. data/lib/roo_on_rails/railties/roo_identity.rb +12 -8
  26. data/lib/roo_on_rails/railties/{sidekiq.rb → sidekiq_integration.rb} +18 -18
  27. data/lib/roo_on_rails/version.rb +1 -1
  28. data/roo_on_rails.gemspec +5 -6
  29. metadata +28 -57
  30. data/.travis.yml +0 -34
  31. data/README.routemaster_client.md +0 -103
  32. data/lib/roo_on_rails/railties/logging.rb +0 -25
  33. data/lib/roo_on_rails/railties/new_relic.rb +0 -32
  34. data/lib/roo_on_rails/railties/routemaster.rb +0 -42
  35. data/lib/roo_on_rails/routemaster/lifecycle_events.rb +0 -64
  36. data/lib/roo_on_rails/routemaster/publish_lifecycle_events.rb +0 -13
  37. data/lib/roo_on_rails/routemaster/publisher.rb +0 -74
  38. data/lib/roo_on_rails/routemaster/publishers.rb +0 -27
  39. data/lib/roo_on_rails/tasks/newrelic.rake +0 -25
@@ -1,34 +0,0 @@
1
- sudo: required
2
- language: ruby
3
- rvm:
4
- - 2.2.7
5
- - 2.3.3
6
- - 2.4.1
7
- - ruby-head
8
- gemfile:
9
- - gemfiles/rails_3.gemfile
10
- - gemfiles/rails_4.gemfile
11
- - gemfiles/rails_5.gemfile
12
- - gemfiles/rails_5_1.gemfile
13
- install:
14
- - bundle install --jobs=3 --retry=3 --path=vendor/bundle
15
- cache:
16
- bundler: true
17
- directories:
18
- - vendor/bundle
19
- - vendor/bundle-scaffold
20
- before_script:
21
- - unset RACK_ENV
22
- - unset RAILS_ENV
23
- - mkdir -p $PWD/tmp && sudo mount -t tmpfs -o size=1024m tmpfs $PWD/tmp
24
- - gem install bundler
25
- matrix:
26
- allow_failures:
27
- - rvm: ruby-head
28
- exclude:
29
- - rvm: 2.4.1
30
- gemfile: gemfiles/rails_3.gemfile
31
- - rvm: ruby-head
32
- gemfile: gemfiles/rails_3.gemfile
33
- services:
34
- - redis-server
@@ -1,103 +0,0 @@
1
- ## Using the Routemaster Client feature
2
-
3
- [`routemaster-client`](https://github.com/deliveroo/routemaster-client) comes as a dependency of `roo_on_rails` with a basic implementation of lifecycle event publishers.
4
-
5
- This code example assumes that you are using the latest version of the [`roo_on_rails`](https://github.com/deliveroo/roo_on_rails) gem and that you have set the correct environment variables for Routemaster Client to work on your app, as explained in the main [`README.md`](https://github.com/deliveroo/roo_on_rails#routemaster-client) file.
6
-
7
- It also assumes that your app has an API for the resources you want to publish lifecycle events for, with matching routes and an `API_HOST` environment variable set.
8
-
9
- ### Setup lifecycle events for your models
10
-
11
- You can use publish events on create, update, and destroy by including the `PublishLifecycleEvents` module:
12
-
13
- ```ruby
14
- # app/models/order.rb
15
- require 'roo_on_rails/routemaster/publish_lifecycle_events'
16
-
17
- class Order < ApplicationRecord
18
- include RooOnRails::Routemaster::PublishLifecycleEvents
19
-
20
- # ...
21
- end
22
- ```
23
-
24
- If you need more control over which events are published you can use the base module `LifecycleEvents` and specify them explicitly:
25
-
26
- ```ruby
27
- # app/models/rider.rb
28
- require 'roo_on_rails/routemaster/lifecycle_events'
29
-
30
- class Rider < ApplicationRecord
31
- include RooOnRails::Routemaster::LifecycleEvents
32
-
33
- publish_lifecycle_events :create, :destroy
34
-
35
- # ...
36
- end
37
- ```
38
-
39
- ### Create publishers for lifecycle events
40
-
41
- We have now configured our models to publish lifecycle events to Routemaster, but it won't send anything until you have enabled publishing and created matching publishers. Let's start with creating an `ApplicationPublisher` that we can use as our default.
42
-
43
- ```ruby
44
- # app/publishers/application_publisher.rb
45
- require 'roo_on_rails/routemaster/publisher'
46
-
47
- class ApplicationPublisher < RooOnRails::Routemaster::Publisher
48
- include Rails.application.routes.url_helpers
49
-
50
- def url
51
- url_helper = :"api_#{model.class.name.underscore}_url"
52
- public_send(url_helper, model.id, host: ENV.fetch('API_HOST'), protocol: 'https')
53
- end
54
-
55
- # Add your method overrides here if needed
56
- end
57
- ```
58
-
59
- If different behaviour is needed for specific models then you can override the defaults in their publishers:
60
-
61
- ```ruby
62
- # app/publishers/order_publisher.rb
63
- class OrderPublisher < ApplicationPublisher
64
- def async?
65
- true
66
- end
67
- end
68
- ```
69
-
70
- and
71
-
72
- ```ruby
73
- # app/publishers/rider_publisher.rb
74
- class RiderPublisher < ApplicationPublisher
75
- def topic
76
- 'a_different_rider_topic'
77
- end
78
- end
79
- ```
80
-
81
- `#publish?`, `#topics`, `#async?`, `#data` and `#timestamp` can be overriden; see [the `Publisher` class](lib/roo_on_rails/routemaster/publisher.rb) for the default implementations.
82
-
83
- ### Register the publishers with Routemaster
84
-
85
- The final step is to tell Routemaster that these publishers exist, so that it can listen to their events. We're going to do this in an initialiser:
86
-
87
- ```ruby
88
- # config/initilizers/routemaster.rb
89
- require 'roo_on_rails/routemaster/publishers'
90
-
91
- PUBLISHERS = [
92
- OrderPublisher,
93
- RiderPublisher
94
- ].freeze
95
-
96
- RooOnRails::Routemaster::Publishers.register_default(ApplicationPublisher)
97
- PUBLISHERS.each do |publisher|
98
- model_class = publisher.to_s.gsub("Publisher", "").constantize
99
- RooOnRails::Routemaster::Publishers.register(publisher, model_class: model_class)
100
- end
101
- ```
102
-
103
- We should now be all set for our app to publish lifecycle events for all our models onto the event bus, with special behaviour for `orders` and `riders`, so that other apps can listen to them.
@@ -1,25 +0,0 @@
1
- module RooOnRails
2
- module Railties
3
- class Logging < Rails::Railtie
4
- initializer 'roo_on_rails.logging.before', before: :initialize_logger do
5
- require 'roo_on_rails/logger'
6
- Rails.logger = config.logger = RooOnRails::Logger.new
7
- # It is not possible to set log_level to an invalid value without some
8
- # deliberate gymnastics (the setter will raise an error), and Rails
9
- # defaults this to `debug`, so we don't need to guard against nil /
10
- # invalidity
11
- log_level = Rails.configuration.log_level
12
-
13
- Rails.logger.set_log_level(default: log_level)
14
- Rails.logger.debug 'initializer roo_on_rails.logging.before'
15
- end
16
-
17
- initializer 'roo_on_rails.logging.after', after: :initialize_logger do
18
- log_level = Rails.configuration.log_level
19
-
20
- Rails.logger.set_log_level(default: log_level)
21
- Rails.logger.debug 'initializer roo_on_rails.logging.after'
22
- end
23
- end
24
- end
25
- end
@@ -1,32 +0,0 @@
1
- module RooOnRails
2
- module Railties
3
- class NewRelic < Rails::Railtie
4
- initializer 'roo_on_rails.new_relic' do
5
- Rails.logger.with initializer: 'roo_on_rails.new_relic' do |log|
6
- log.debug 'loading'
7
- license_key = ENV['NEW_RELIC_LICENSE_KEY']
8
-
9
- if %w(test development).exclude?(Rails.env.to_s) && (license_key == 'override-me')
10
- abort 'Aborting: NEW_RELIC_LICENSE_KEY must be set in production environments'
11
- end
12
-
13
- abort 'Aborting: NEW_RELIC_LICENSE_KEY is required' if license_key.nil?
14
-
15
- path = %w(newrelic.yml config/newrelic.yml).map do |p|
16
- Pathname.new(p)
17
- end.find(&:exist?)
18
- if path
19
- abort "Aborting: newrelic.yml detected in '#{path.parent.realpath}', should not exist"
20
- end
21
-
22
- sync_startup = (ENV.fetch('NEW_RELIC_SYNC_STARTUP', 'YES') =~ /\A(YES|TRUE|ON|1)\Z/i)
23
-
24
- require 'newrelic_rpm'
25
- unless Rails.env.test?
26
- ::NewRelic::Control.instance.init_plugin(sync_startup: sync_startup)
27
- end
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,42 +0,0 @@
1
- require 'roo_on_rails/config'
2
-
3
- module RooOnRails
4
- module Railties
5
- class Routemaster < Rails::Railtie
6
- initializer 'roo_on_rails.routemaster' do
7
- Rails.logger.with initializer: 'roo_on_rails.routemaster' do |log|
8
- next unless Config.routemaster_enabled?
9
- log.debug 'loading'
10
-
11
- abort 'Aborting: ROUTEMASTER_URL and ROUTEMASTER_UUID are required' if bus_details_missing?
12
-
13
- require 'routemaster/client'
14
-
15
- ::Routemaster::Client.configure do |config|
16
- config.url = routemaster_url
17
- config.uuid = routemaster_uuid
18
- config.verify_ssl = routemaster_verify_ssl
19
- end
20
- end
21
- end
22
-
23
- private
24
-
25
- def bus_details_missing?
26
- routemaster_url.blank? || routemaster_uuid.blank?
27
- end
28
-
29
- def routemaster_url
30
- ENV.fetch('ROUTEMASTER_URL')
31
- end
32
-
33
- def routemaster_uuid
34
- ENV.fetch('ROUTEMASTER_UUID')
35
- end
36
-
37
- def routemaster_verify_ssl
38
- ENV.fetch('ROUTEMASTER_VERIFY_SSL', 'true') != 'false'
39
- end
40
- end
41
- end
42
- end
@@ -1,64 +0,0 @@
1
- require 'active_support/concern'
2
- require 'new_relic/agent'
3
- require 'roo_on_rails/routemaster/publishers'
4
-
5
- module RooOnRails
6
- module Routemaster
7
- module LifecycleEvents
8
- extend ActiveSupport::Concern
9
-
10
- ACTIVE_RECORD_TO_ROUTEMASTER_EVENT_MAP = {
11
- create: :created,
12
- update: :updated,
13
- destroy: :deleted,
14
- noop: :noop
15
- }.freeze
16
- private_constant :ACTIVE_RECORD_TO_ROUTEMASTER_EVENT_MAP
17
-
18
- def publish_lifecycle_event(event)
19
- publish_event(event, force_publish: false)
20
- end
21
-
22
- def publish_lifecycle_event!(event)
23
- publish_event(event, force_publish: true)
24
- end
25
-
26
- private
27
-
28
- def publish_event(event, force_publish:)
29
- publishers = Routemaster::Publishers.for(self, routemaster_event_type(event))
30
- publishers.each do |publisher|
31
- begin
32
- publisher.publish!(force_publish: force_publish)
33
- rescue => e
34
- NewRelic::Agent.notice_error(e)
35
- end
36
- end
37
- end
38
-
39
- def routemaster_event_type(event)
40
- ACTIVE_RECORD_TO_ROUTEMASTER_EVENT_MAP[event].tap do |type|
41
- raise "invalid lifecycle event '#{event}'" unless type
42
- end
43
- end
44
-
45
- %i(create update destroy noop).each do |event|
46
- define_method("publish_lifecycle_event_on_#{event}") do
47
- publish_lifecycle_event(event)
48
- end
49
- end
50
-
51
- module ClassMethods
52
- def publish_lifecycle_events(*events)
53
- events = events.any? ? events : %i(create update destroy)
54
- events.each do |event|
55
- after_commit(
56
- :"publish_lifecycle_event_on_#{event}",
57
- on: event
58
- )
59
- end
60
- end
61
- end
62
- end
63
- end
64
- end
@@ -1,13 +0,0 @@
1
- require 'active_support/concern'
2
- require 'roo_on_rails/routemaster/lifecycle_events'
3
-
4
- module RooOnRails
5
- module Routemaster
6
- module PublishLifecycleEvents
7
- extend ActiveSupport::Concern
8
- include LifecycleEvents
9
-
10
- included(&:publish_lifecycle_events)
11
- end
12
- end
13
- end
@@ -1,74 +0,0 @@
1
- require 'roo_on_rails/config'
2
- require 'routemaster/client'
3
-
4
- module RooOnRails
5
- module Routemaster
6
- class Publisher
7
- attr_reader :model, :event
8
-
9
- def initialize(model, event, client: ::Routemaster::Client)
10
- @model = model
11
- @event = event
12
- @client = client
13
- end
14
-
15
- def publish?
16
- noop? || @model.new_record? || @model.previous_changes.any?
17
- end
18
-
19
- def will_publish?(force_publish: false)
20
- Config.routemaster_publishing_enabled? && (force_publish || publish?)
21
- end
22
-
23
- def publish!(force_publish: false)
24
- return unless will_publish?(force_publish: force_publish)
25
- @client.send(
26
- @event,
27
- topic,
28
- url,
29
- async: async?,
30
- data: stringify_keys(data),
31
- t: timestamp && (timestamp.to_f * 1000).to_i
32
- )
33
- end
34
-
35
- def topic
36
- @model.class.name.tableize
37
- end
38
-
39
- def url
40
- raise NotImplementedError
41
- end
42
-
43
- def async?
44
- false
45
- end
46
-
47
- def data
48
- nil
49
- end
50
-
51
- def timestamp
52
- return @model.created_at if created? && @model.respond_to?(:created_at)
53
- return @model.updated_at if (updated? || created?) && @model.respond_to?(:updated_at)
54
- nil
55
- end
56
-
57
- %i(created updated deleted noop).each do |event_type|
58
- define_method :"#{event_type}?" do
59
- @event.to_sym == event_type
60
- end
61
- end
62
-
63
- private
64
-
65
- def stringify_keys(hash)
66
- return hash if hash.nil? || hash.empty?
67
-
68
- hash.each_with_object({}) do |(k, v), h|
69
- h[k.to_s] = v.is_a?(Hash) ? stringify_keys(v) : v
70
- end
71
- end
72
- end
73
- end
74
- end
@@ -1,27 +0,0 @@
1
- module RooOnRails
2
- module Routemaster
3
- module Publishers
4
- @default_publishers = []
5
- @publishers = {}
6
-
7
- def self.register_default(publisher_class)
8
- @default_publishers << publisher_class
9
- end
10
-
11
- def self.register(publisher_class, model_class:)
12
- @publishers[model_class.name] ||= Set.new
13
- @publishers[model_class.name] << publisher_class
14
- end
15
-
16
- def self.for(model, event)
17
- publisher_classes = @publishers[model.class.name] || @default_publishers
18
- publisher_classes.map { |c| c.new(model, event) }
19
- end
20
-
21
- def self.clear
22
- @default_publishers = []
23
- @publishers = {}
24
- end
25
- end
26
- end
27
- end
@@ -1,25 +0,0 @@
1
- namespace :newrelic do
2
- desc 'Notifies New Relic that a deployment has occurred'
3
- task notice_deployment: :environment do
4
- begin
5
- require 'newrelic_rpm'
6
- require 'new_relic/cli/command'
7
-
8
- appname = ENV.fetch('NEW_RELIC_APP_NAME')
9
-
10
- Rails.logger.info("Notifying New Relic of deployment to #{appname}")
11
- NewRelic::Cli::Deployments.new(
12
- environment: Rails.env.to_s,
13
- revision: ENV.fetch('SOURCE_VERSION', 'unknown'),
14
- changelog: '',
15
- description: '',
16
- appname: appname,
17
- user: '',
18
- license_key: ENV.fetch('NEW_RELIC_LICENSE_KEY')
19
- ).run
20
- rescue => e
21
- Rails.logger.error("Failed to notify New Relic (#{e.class.name}: #{e.message})")
22
- Rails.logger.info(e.backtrace.take(10).join("\n"))
23
- end
24
- end
25
- end