class Tengine::Resource::Provider::Synchronizer

Attributes

log_prefix[R]
provider[R]
target_name[R]

Public Class Methods

fetch_known_target_method(method_name = nil) click to toggle source
# File lib/tengine/resource/provider.rb, line 106
def fetch_known_target_method(method_name = nil)
  @fetch_known_target_methods ||= {}
  @fetch_known_target_methods[self] = method_name if method_name
  @fetch_known_target_methods[self]
end
map(attr_name, prop_name = nil, &block) click to toggle source
# File lib/tengine/resource/provider.rb, line 112
def map(attr_name, prop_name = nil, &block)
  property_map[attr_name] = prop_name || block
end
new(provider, target_name) click to toggle source
# File lib/tengine/resource/provider.rb, line 131
def initialize(provider, target_name)
  @provider, @target_name = provider, target_name
  @log_prefix = "#{self.class.name} for #{provider.name}"
end
property_map() click to toggle source
# File lib/tengine/resource/provider.rb, line 116
def property_map
  @property_map ||= {}
  @property_map[self] ||= {}
end

Public Instance Methods

execute() click to toggle source
# File lib/tengine/resource/provider.rb, line 136
def execute
  actual_target_hashs = fetch_actual_target_hashs

  provider.reload
  known_targets = fetch_known_targets

  id_key = property_map[:provided_id].to_s
  updated_target_hashs = []
  destroyed_targets = []

  known_targets.each do |known_target|
    actual_target_hash = actual_target_hashs.detect do |t|
      (t[id_key] || t[id_key.to_sym]) == known_target.provided_id
    end
    if actual_target_hash
      updated_target_hashs << actual_target_hash
    else
      destroyed_targets << known_target
    end
  end
  created_target_hashs = actual_target_hashs - updated_target_hashs

  differential_update(updated_target_hashs)
  create_by_hashs(created_target_hashs)
  destroy_targets(destroyed_targets)
end
fetch_known_target_method() click to toggle source
# File lib/tengine/resource/provider.rb, line 122
def fetch_known_target_method
  self.class.fetch_known_target_method
end
property_map() click to toggle source
# File lib/tengine/resource/provider.rb, line 126
def property_map
  @property_map ||= self.class.property_map
end

Private Instance Methods

attrs_to_create(properties) click to toggle source
# File lib/tengine/resource/provider.rb, line 243
def attrs_to_create(properties)
  mapped_attributes(properties)
end
create_by_hash(hash) { |attrs| ... } click to toggle source
# File lib/tengine/resource/provider.rb, line 226
def create_by_hash(hash)
  properties = hash.dup
  properties.deep_symbolize_keys!
  provided_id = properties[:provided_id]
  Tengine.logger.debug "#{log_prefix} create #{provided_id}"
  attrs = attrs_to_create(properties)
  target = provider.send(target_name).new
  attrs[:properties] = properties if target.respond_to?(:properties)
  yield(attrs) if block_given?
  target.attributes = attrs
  target.save!
  target
rescue => e
  Tengine.logger.error "#{log_prefix} [#{e.class}] #{e.message}: failed to create (#{provided_id}): #{hash.inspect}"
  raise
end
create_by_hashs(hashs) click to toggle source
# File lib/tengine/resource/provider.rb, line 222
def create_by_hashs(hashs)
  hashs.map{|hash| t = create_by_hash(hash); t ? t.id : nil}.compact
end
destroy_targets(targets) click to toggle source
# File lib/tengine/resource/provider.rb, line 258
def destroy_targets(targets)
  targets.each do |target|
    Tengine.logger.debug "#{log_prefix} destroy #{target.provided_id}"
    target.destroy
  end
end
differential_update(hashs) click to toggle source
# File lib/tengine/resource/provider.rb, line 182
def differential_update(hashs)
  hashs.map{|hash| differential_update_by_hash(hash)}
end
differential_update_by_hash(hash, &block) click to toggle source
# File lib/tengine/resource/provider.rb, line 186
def differential_update_by_hash(hash, &block)
  properties = hash.dup
  properties.deep_symbolize_keys!
  provided_id = properties[ property_map[:provided_id] ]
  Tengine.logger.debug "#{log_prefix} update (#{provided_id})"
  target = provider.send(target_name).where(:provided_id => provided_id).first
  unless target
    raise "target #{target_name.to_s.singularize} not found by using #{map[:provided_id]}: #{provided_id.inspect}. properties: #{properties.inspect}"
  end
  attrs = mapped_attributes(properties)
  attrs.each do |attr, value|
    target.send("#{attr}=", value)
  end
  prop_backup = properties.dup
  if target.respond_to?(:properties) && target.properties
    properties.each do |key, val|
      value =  properties.delete(key)
      if (val.to_s != value.to_s) or (value.blank?)
        if target.properties[key.to_sym]
          target.properties[key.to_sym] = value
        else
          target.properties[key.to_s] = value
        end
      end
    end
  end
  if block
    block.call(target, prop_backup)
  else
    target.save! if target.changed?
  end
rescue => e
  Tengine.logger.error "#{log_prefix} [#{e.class}] #{e.message}: failed to update (#{provided_id}): #{hash.inspect}"
  raise
end
fetch_actual_target_hashs() click to toggle source

APIからの実際のターゲット情報を取得する

# File lib/tengine/resource/provider.rb, line 166
def fetch_actual_target_hashs
  Tengine.logger.debug "#{log_prefix} #{fetch_known_target_method} for api (wakame)"
  result = provider.send(fetch_known_target_method)
  Tengine.logger.debug "#{log_prefix} #{result.inspect}"
  result
end
fetch_known_targets() click to toggle source

DBに記録されているターゲット情報を取得する

# File lib/tengine/resource/provider.rb, line 174
def fetch_known_targets
  Tengine.logger.debug "#{log_prefix} #{target_name} on provider (#{provider.name})"
  result = provider.send(target_name)
  Tengine.logger.debug "#{log_prefix} #{result.inspect}"
  result
end
mapped_attributes(properties) click to toggle source
# File lib/tengine/resource/provider.rb, line 247
def mapped_attributes(properties)
  result = {}
  property_map.each do |attr, prop|
    value = prop.is_a?(Proc) ?
    prop.call(properties, provider) : # 引数を一つだけ使うこともあるのlambdaではなくProc.newを使う事を期待しています。
      properties.delete(prop)
    result[attr] = value
  end
  result
end