class RapidsRivers::River

Understands a filtered stream of JSON messages

Attributes

listening_services[R]
rapids_connection[R]

Public Class Methods

new(rapids_connection, read_count_limit = 9) click to toggle source
# File lib/rapids_rivers/river.rb, line 14
def initialize rapids_connection, read_count_limit = 9
  @rapids_connection, @read_count_limit = rapids_connection, read_count_limit
  @listening_services = []
  @validations = []
  rapids_connection.register(self);
end

Public Instance Methods

forbid(*keys) click to toggle source
# File lib/rapids_rivers/river.rb, line 46
def forbid *keys
  keys.each do |key|
    @validations << lambda do |json_hash, packet, packet_problems|
      validate_missing key, json_hash, packet_problems
      create_accessors key, json_hash, packet
    end
  end
  self
end
interested_in(*keys) click to toggle source
# File lib/rapids_rivers/river.rb, line 66
def interested_in *keys
  keys.each do |key|
    @validations << lambda do |json_hash, packet, packet_problems|
      create_accessors key, json_hash, packet
    end
  end
  self
end
message(send_port, message) click to toggle source
# File lib/rapids_rivers/river.rb, line 21
def message send_port, message
  packet_problems = RapidsRivers::PacketProblems.new message
  packet = validated_packet message, packet_problems
  return if packet && packet.respond_to?(:system_read_count) && packet.system_read_count > @read_count_limit
  @listening_services.each do |ls|
    next ls.packet(send_port, packet.clone_with_name(service_name(ls)), packet_problems) unless packet_problems.errors?
    next unless ls.respond_to? :on_error
    ls.on_error(send_port, packet_problems) if packet_problems.errors?
  end
end
register(service) click to toggle source
# File lib/rapids_rivers/river.rb, line 32
def register service
  @listening_services << service
end
require(*keys) click to toggle source
# File lib/rapids_rivers/river.rb, line 36
def require *keys
  keys.each do |key|
    @validations << lambda do |json_hash, packet, packet_problems|
      validate_required key, json_hash, packet_problems
      create_accessors key, json_hash, packet
    end
  end
  self
end
require_values(key_value_hashes) click to toggle source
# File lib/rapids_rivers/river.rb, line 56
def require_values(key_value_hashes)
  key_value_hashes.each do |key, value|
    @validations << lambda do |json_hash, packet, packet_problems|
      validate_value key, value, json_hash, packet_problems
      create_accessors key, json_hash, packet
    end
  end
  self
end

Protected Instance Methods

service_name(service) click to toggle source
# File lib/rapids_rivers/river.rb, line 77
def service_name(service)
  service.respond_to?(:service_name) ? service.service_name : '<unknown>'
end

Private Instance Methods

create_accessors(key, json_hash, packet) click to toggle source
# File lib/rapids_rivers/river.rb, line 116
def create_accessors key, json_hash, packet
  key = key.to_s
  packet.used_key key
  establish_variable key, json_hash[key], packet
  define_getter key, packet
  define_setter key, packet
end
define_getter(key, packet) click to toggle source
# File lib/rapids_rivers/river.rb, line 129
def define_getter key, packet
  variable = variable(key)
  packet.define_singleton_method(key.to_sym) do
    instance_variable_get variable
  end
end
define_setter(key, packet) click to toggle source
# File lib/rapids_rivers/river.rb, line 136
def define_setter key, packet
  variable = variable(key)
  packet.define_singleton_method((key + '=').to_sym) do |new_value|
    instance_variable_set variable, new_value
  end
end
establish_variable(key, value = nil, packet) click to toggle source
# File lib/rapids_rivers/river.rb, line 124
def establish_variable key, value = nil, packet
  variable = variable(key)
  packet.instance_variable_set variable, value
end
validate_missing(key, json_hash, packet_problems) click to toggle source
# File lib/rapids_rivers/river.rb, line 102
def validate_missing key, json_hash, packet_problems
  key = key.to_s
  return unless json_hash.key? key
  return unless value?(json_hash[key])
  packet_problems.error "Forbidden key '#{key}'' detected"
end
validate_required(key, json_hash, packet_problems) click to toggle source
# File lib/rapids_rivers/river.rb, line 96
def validate_required key, json_hash, packet_problems
  key = key.to_s
  return packet_problems.error "Missing required key '#{key}'" unless json_hash[key]
  return packet_problems.error "Empty required key '#{key}'" unless value?(json_hash[key])
end
validate_value(key, value, json_hash, packet_problems) click to toggle source
# File lib/rapids_rivers/river.rb, line 109
def validate_value key, value, json_hash, packet_problems
  key = key.to_s
  validate_required key, json_hash, packet_problems
  return if json_hash[key] == value
  packet_problems.error "Required value of key '#{key}' is '#{json_hash[key]}', not '#{value}'"
end
validated_packet(message, packet_problems) click to toggle source
# File lib/rapids_rivers/river.rb, line 83
def validated_packet message, packet_problems
  begin
    json_hash = JSON.parse(message)
    packet = Packet.new json_hash
    @validations.each { |v| v.call json_hash, packet, packet_problems }
    packet
  rescue JSON::ParserError
    packet_problems.severe_error("Invalid JSON format. Please check syntax carefully.")
  rescue Exception => e
    packet_problems.severe_error("Packet creation issue:\n\t#{e}")
  end
end
value?(value_under_test) click to toggle source
# File lib/rapids_rivers/river.rb, line 147
def value? value_under_test
  return false if value_under_test.nil?
  return true if value_under_test.kind_of?(Numeric)
  return false if value_under_test == ''
  return false if value_under_test == []
  true
end
variable(key) click to toggle source
# File lib/rapids_rivers/river.rb, line 143
def variable key
  ('@' + key.to_s).to_sym
end