Skip to content

Commit

Permalink
refactor jetpants_collins moving collins_get and collins_set to its o…
Browse files Browse the repository at this point in the history
…wn class
  • Loading branch information
Akshay Suryawanshi committed Jun 6, 2017
1 parent 7cff36f commit c7cea1d
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 97 deletions.
104 changes: 7 additions & 97 deletions plugins/jetpants_collins/jetpants_collins.rb
Original file line number Diff line number Diff line change
Expand Up @@ -188,39 +188,24 @@ def service
end
end


##### INSTANCE (MIX-IN) METHODS ##########################################

# The base class needs to implement this!
def collins_asset
raise "Any class including Plugin::JetCollins must also implement collins_asset instance method!"
end

def collins
Jetpants::Plugin::JetCollinsAsset::Tracker.new(lambda { collins_asset }, lambda { |msg| output msg })
end

# Pass in a symbol, or array of symbols, to obtain from Collins for this
# asset. For example, :status, :pool, :primary_role, :secondary_role.
# If you pass in a single symbol, returns a single value.
# If you pass in an array, returns a hash mapping each of these fields to their values.
# Hash will also contain an extra field called :asset, storing the Collins::Asset object.
def collins_get(*field_names)
asset = collins_asset

if field_names.count > 1 || field_names[0].is_a?(Array)
field_names.flatten!
want_state = !! field_names.delete(:state)
results = Hash[field_names.map {|field| [field, (asset ? asset.send(field) : '')]}]
results[:state] = asset.state.name if want_state
results[:asset] = asset
results
elsif field_names.count == 1
return '' unless asset
if field_names[0] == :state
asset.state.name
else
asset.send field_names[0]
end
else
nil
end
collins.get(*field_names)
end

# Pass in a hash mapping field name symbols to values to set
Expand All @@ -231,82 +216,7 @@ def collins_get(*field_names)
#
# Alternatively, pass in 2 strings (field_name, value) to set just a single Collins attribute (or status)
def collins_set(*args)
attrs = (args.count == 1 ? args[0] : {args[0] => args[1]})
asset = attrs[:asset] || collins_asset

upcase = !attrs[:literal]
attrs.delete(:literal)

# refuse to set Collins values on machines in remote data center unless
# inter_dc_mode is enabled
if asset && asset.type.downcase == 'server_node' && asset.location && asset.location.upcase != Plugin::JetCollins.datacenter
asset = nil unless Jetpants::Plugin::JetCollins.inter_dc_mode?
end

attrs.each do |key, val|
val ||= ''
case key
when :asset
next
when :status
unless asset
output "WARNING: unable to set Collins status to #{val}"
next
end
state_val = attrs[:state]
previous_status = asset.status.capitalize
# Allow setting status:state at once via foo.collins_status = 'allocated:running'
if val.include? ':'
raise "Attempting to set state in two places" if state_val
vals = val.split(':', 2)
val = vals.first.capitalize
state_val = vals.last.upcase
end
if state_val
previous_state = asset.state.name.upcase
next unless previous_state != state_val.to_s.upcase || previous_status != val.to_s.capitalize
success = Jetpants::Plugin::JetCollins.set_status!(asset, val, 'changed through jetpants', state_val)
unless success
# If we failed to set to this state, try creating the state as new
Jetpants::Plugin::JetCollins.state_create!(state_val, state_val, state_val, val)
success = Jetpants::Plugin::JetCollins.set_status!(asset, val, 'changed through jetpants', state_val)
end
raise "#{self}: Unable to set Collins state to #{state_val} and Unable to set Collins status to #{val}" unless success
output "Collins status:state changed from #{previous_status}:#{previous_state} to #{val.capitalize}:#{state_val.upcase}"
elsif previous_status != val.to_s.capitalize
success = Jetpants::Plugin::JetCollins.set_status!(asset, val)
raise "#{self}: Unable to set Collins status to #{val}" unless success
output "Collins status changed from #{previous_status} to #{val}"
end
when :state
unless asset && asset.status && attrs[:status]
raise "#{self}: Unable to set state without settings a status" unless attrs[:status]
output "WARNING: unable to set Collins state to #{val}"
next
end
else
unless asset
output "WARNING: unable to set Collins attribute #{key} to #{val}"
next
end
previous_value = asset.send(key)
val = val.to_s
val = val.upcase if upcase
if previous_value != val
success = Jetpants::Plugin::JetCollins.set_attribute!(asset, key.to_s.upcase, val)
raise "#{self}: Unable to set Collins attribute #{key} to #{val}" unless success
if (val == '' || !val) && (previous_value == '' || !previous_value)
false
elsif val == ''
output "Collins attribute #{key.to_s.upcase} removed (was: #{previous_value})"
elsif !previous_value || previous_value == ''
output "Collins attribute #{key.to_s.upcase} set to #{val}"
else
output "Collins attribute #{key.to_s.upcase} changed from #{previous_value} to #{val}"
end
end
end
end
collins.set(*args)
end

# Returns a single downcased "status:state" string, useful when trying to compare both fields
Expand All @@ -322,4 +232,4 @@ def collins_status_state


# load all the monkeypatches for other Jetpants classes
%w(monkeypatch asset host db pool shard topology shardpool commandsuite).each {|mod| require "jetpants_collins/#{mod}"}
%w(monkeypatch asset host db pool shard topology shardpool commandsuite jetpants_tracker).each {|mod| require "jetpants_collins/#{mod}"}
114 changes: 114 additions & 0 deletions plugins/jetpants_collins/jetpants_tracker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
module Jetpants
module Plugin
module JetCollinsAsset

class Tracker
def initialize(asset, logger)
@asset = asset
@logger = logger
end

def output msg
@logger.call msg
end

def get(*field_names)
asset = @asset.call

if field_names.count > 1 || field_names[0].is_a?(Array)
field_names.flatten!
want_state = !! field_names.delete(:state)
results = Hash[field_names.map {|field| [field, (asset ? asset.send(field) : '')]}]
results[:state] = asset.state.name if want_state
results[:asset] = asset
results
elsif field_names.count == 1
return '' unless asset
if field_names[0] == :state
asset.state.name
else
asset.send field_names[0]
end
else
nil
end
end

def set(*args)
attrs = (args.count == 1 ? args[0] : {args[0] => args[1]})
asset = attrs[:asset] || @asset.call

upcase = !attrs[:literal]
attrs.delete(:literal)

if asset && asset.type.downcase == 'server_node' && asset.location && asset.location.upcase != Plugin::JetCollins.datacenter
asset = nil unless Jetpants::Plugin::JetCollins.inter_dc_mode?
end

attrs.each do |key, val|
val ||= ''
case key
when :asset
next
when :status
unless asset
output "WARNING: unable to set Collins status to #{val}"
next
end
state_val = attrs[:state]
previous_status = asset.status.capitalize
if val.include? ':'
raise "Attempting to set state in two places" if state_val
vals = val.split(':', 2)
val = vals.first.capitalize
state_val = vals.last.upcase
end
if state_val
previous_state = asset.state.name.upcase
next unless previous_state != state_val.to_s.upcase || previous_status != val.to_s.capitalize
success = Jetpants::Plugin::JetCollins.set_status!(asset, val, 'changed through jetpants', state_val)
unless success
Jetpants::Plugin::JetCollins.state_create!(state_val, state_val, state_val, val)
success = Jetpants::Plugin::JetCollins.set_status!(asset, val, 'changed through jetpants', state_val)
end
raise "#{self}: Unable to set Collins state to #{state_val} and Unable to set Collins status to #{val}" unless success
output "Collins status:state changed from #{previous_status}:#{previous_state} to #{val.capitalize}:#{state_val.upcase}"
elsif previous_status != val.to_s.capitalize
success = Jetpants::Plugin::JetCollins.set_status!(asset, val)
raise "#{self}: Unable to set Collins status to #{val}" unless success
output "Collins status changed from #{previous_status} to #{val}"
end
when :state
unless asset && asset.status && attrs[:status]
raise "#{self}: Unable to set state without settings a status" unless attrs[:status]
output "WARNING: unable to set Collins state to #{val}"
next
end
else
unless asset
output "WARNING: unable to set Collins attribute #{key} to #{val}"
next
end
previous_value = asset.send(key)
val = val.to_s
val = val.upcase if upcase
if previous_value != val
success = Jetpants::Plugin::JetCollins.set_attribute!(asset, key.to_s.upcase, val)
raise "#{self}: Unable to set Collins attribute #{key} to #{val}" unless success
if (val == '' || !val) && (previous_value == '' || !previous_value)
false
elsif val == ''
output "Collins attribute #{key.to_s.upcase} removed (was: #{previous_value})"
elsif !previous_value || previous_value == ''
output "Collins attribute #{key.to_s.upcase} set to #{val}"
else
output "Collins attribute #{key.to_s.upcase} changed from #{previous_value} to #{val}"
end
end
end
end
end
end
end # module JetCollinsAsset
end # module Plugin
end # module Jetpants
2 changes: 2 additions & 0 deletions testing/packages/jetpants/jetpants.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,7 @@ plugins:
- mysql_default_cipher
remote_lookup: false
inter_dc_mode: false
retries: 23
max_retry_backoff: 16

online_schema_change:

0 comments on commit c7cea1d

Please sign in to comment.