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.
- checksums.yaml +5 -5
- data/.circleci/config.yml +398 -282
- data/.circleci/config.yml.erb +63 -21
- data/.codecov.yml +3 -0
- data/Appraisals +24 -11
- data/CHANGELOG.md +39 -0
- data/README.md +20 -31
- data/appraise +1 -1
- data/exe/roo_on_rails +5 -0
- data/gemfiles/rails_4.gemfile +3 -1
- data/gemfiles/rails_5.gemfile +2 -1
- data/gemfiles/rails_5_1.gemfile +3 -2
- data/gemfiles/rails_5_2.gemfile +15 -0
- data/gemfiles/{rails_3.gemfile → rails_6.gemfile} +5 -4
- data/lib/roo_on_rails.rb +1 -4
- data/lib/roo_on_rails/checks/documentation/playbook_template.md +0 -4
- data/lib/roo_on_rails/concerns/require_api_key.rb +0 -1
- data/lib/roo_on_rails/config.rb +0 -8
- data/lib/roo_on_rails/default.env +0 -13
- data/lib/roo_on_rails/rack/populate_env_from_jwt.rb +25 -4
- data/lib/roo_on_rails/railties/database.rb +11 -10
- data/lib/roo_on_rails/railties/env.rb +3 -5
- data/lib/roo_on_rails/railties/google_oauth.rb +4 -6
- data/lib/roo_on_rails/railties/http.rb +34 -32
- data/lib/roo_on_rails/railties/roo_identity.rb +12 -8
- data/lib/roo_on_rails/railties/{sidekiq.rb → sidekiq_integration.rb} +18 -18
- data/lib/roo_on_rails/version.rb +1 -1
- data/roo_on_rails.gemspec +5 -6
- metadata +28 -57
- data/.travis.yml +0 -34
- data/README.routemaster_client.md +0 -103
- data/lib/roo_on_rails/railties/logging.rb +0 -25
- data/lib/roo_on_rails/railties/new_relic.rb +0 -32
- data/lib/roo_on_rails/railties/routemaster.rb +0 -42
- data/lib/roo_on_rails/routemaster/lifecycle_events.rb +0 -64
- data/lib/roo_on_rails/routemaster/publish_lifecycle_events.rb +0 -13
- data/lib/roo_on_rails/routemaster/publisher.rb +0 -74
- data/lib/roo_on_rails/routemaster/publishers.rb +0 -27
- data/lib/roo_on_rails/tasks/newrelic.rake +0 -25
data/.travis.yml
DELETED
@@ -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
|