class DMAO::Ingesters::Generic::Ingester

Constants

ENTITY
ENTITY_ERROR
ENTITY_ERROR_MESSAGE
ERROR_HANDLING
INVALID_ENTITY_ERROR

Public Class Methods

entity_name() click to toggle source
# File lib/dmao/ingesters/generic/ingester.rb, line 40
def self.entity_name
  self::ENTITY.to_s.split('::')[-1].gsub(/[A-Z]/, " \\0").downcase.strip
end
new(api_url=nil, api_token=nil, institution_id=nil) click to toggle source
# File lib/dmao/ingesters/generic/ingester.rb, line 19
def initialize(api_url=nil, api_token=nil, institution_id=nil)

  DMAO::API.configure do |config|
    config.base_url = api_url
    config.api_token = api_token
    config.institution_id = institution_id
  end

  if self.class::ENTITY.nil?
    raise "Entity not set"
  end

  add_method_name = "add_#{self.class.entity_name.tr(' ', '_')}"
  update_method_name = "update_#{self.class.entity_name.tr(' ', '_')}"
  ingest_method_name = "ingest_#{self.class.entity_name.tr(' ', '_')}"

  self.class.send(:define_method, add_method_name, Proc.new {|attributes| add_entity(attributes)}) unless self.respond_to?(add_method_name, include_all: true)
  self.class.send(:define_method, update_method_name, Proc.new {|id, attributes| update_entity(id, attributes)}) unless self.respond_to?(update_method_name, include_all: true)
  self.class.send(:define_method, ingest_method_name, Proc.new {|attributes={}| ingest_entity(attributes)}) unless self.respond_to?(ingest_method_name, include_all: true)
end

Private Class Methods

===(other) click to toggle source
# File lib/dmao/ingesters/generic/ingester.rb, line 117
def self.===(other)
  !(other.class.ancestors.map {|a| a.to_s} & @errors.keys).empty?
end

Public Instance Methods

generic_errors() click to toggle source
# File lib/dmao/ingesters/generic/ingester.rb, line 44
def generic_errors
  {
      "DMAO::API::Errors::InstitutionNotFound" => "Institution not found, cannot ingest #{self.class.entity_name} to non-existent institution",
      "DMAO::API::Errors::EntityNotFound" => "#{self.class.entity_name.capitalize} not found, cannot update #{self.class.entity_name} that does not exist"
  }
end
ingest() click to toggle source
# File lib/dmao/ingesters/generic/ingester.rb, line 51
def ingest
  raise DMAO::Ingesters::Errors::GenericIngester.new("Calling ingest on generic ingester is not allowed.")
end
ingest_entity(attributes = {}) click to toggle source
# File lib/dmao/ingesters/generic/ingester.rb, line 55
def ingest_entity attributes = {}

  validate_attributes_present attributes

  begin

    entity = self.class::ENTITY.find_by_system_uuid attributes[:system_uuid]

    current_modified_at = Time.parse(entity.system_modified_at)
    new_modified_at = Time.parse(attributes[:system_modified_at])

    return false if current_modified_at >= new_modified_at

    update_entity entity.id, attributes

  rescue DMAO::API::Errors::EntityNotFound
    add_entity attributes
  rescue DMAO::API::Errors::InvalidResponseLength
    raise self.class::ENTITY_ERROR.new("More than one #{self.class.entity_name} returned for system uuid #{attributes[:system_uuid]}.")
  end

end
parse_unprocessable_errors(errors) click to toggle source
# File lib/dmao/ingesters/generic/ingester.rb, line 78
def parse_unprocessable_errors errors

  error_messages = ""

  errors.each_with_index do |(k, v), index|
    v.each_with_index do |msg, msg_index|
      error_messages += "#{k} - #{msg}"
      error_messages += ", " unless msg_index == v.size - 1
    end
    error_messages += ", " unless index == errors.size - 1
  end

  raise self.class::ENTITY_ERROR.new("#{self.class::ENTITY_ERROR_MESSAGE}, #{error_messages}")

end

Private Instance Methods

add_entity(attributes={}) click to toggle source
# File lib/dmao/ingesters/generic/ingester.rb, line 125
def add_entity attributes={}

  perform_entity_action "create", [attributes]

end
ingest_errors(errors={}) click to toggle source
# File lib/dmao/ingesters/generic/ingester.rb, line 115
def ingest_errors(errors={})
  Class.new do
    def self.===(other)
      !(other.class.ancestors.map {|a| a.to_s} & @errors.keys).empty?
    end
  end.tap do |c|
    c.instance_variable_set(:@errors, errors)
  end
end
perform_entity_action(action, arguments) click to toggle source
# File lib/dmao/ingesters/generic/ingester.rb, line 100
def perform_entity_action action, arguments

  errors_to_handle = self.class::ERROR_HANDLING.nil? ? generic_errors : self.class::ERROR_HANDLING

  begin
    self.class::ENTITY.send(action, *arguments)
  rescue ingest_errors(errors_to_handle) => e
    error_message = errors_to_handle[e.class.to_s].nil? ? errors_to_handle[(e.class.ancestors.map {|a| a.to_s} & errors_to_handle.keys).first] : errors_to_handle[e.class.to_s]
    raise self.class::ENTITY_ERROR.new(error_message)
  rescue self.class::ENTITY::INVALID_ENTITY_CLASS => e
    parse_unprocessable_errors(e.errors)
  end

end
update_entity(entity_id, attributes={}) click to toggle source
# File lib/dmao/ingesters/generic/ingester.rb, line 131
def update_entity entity_id, attributes={}

  perform_entity_action "update", [entity_id, attributes]

end
validate_attributes_present(attributes) click to toggle source
# File lib/dmao/ingesters/generic/ingester.rb, line 96
def validate_attributes_present attributes
  raise DMAO::Ingesters::Errors::EmptyAttributes.new("Cannot ingest #{self.class.entity_name} without attributes.") if attributes.nil? || attributes.empty?
end