lib/flapjack/data/contact.rb in flapjack-0.6.36 vs lib/flapjack/data/contact.rb in flapjack-0.6.37

- old
+ new

@@ -1,78 +1,116 @@ #!/usr/bin/env ruby +# NB: use of redis.keys probably indicates we should maintain a data +# structure to avoid the need for this type of query + module Flapjack module Data class Contact - # takes a check, looks up contacts that are interested in this check (or in the check's entity) - # and returns an array of contact ids - def self.find_all_for_entity_check(entity_check, options = {}) + attr_accessor :first_name, :last_name, :email, :media, :pagerduty_credentials, :id + + def self.all(options = {}) raise "Redis connection not set" unless redis = options[:redis] - logger = options[:logger] - entity = entity_check.entity - check = entity_check.check + contact_keys = redis.keys('contact:*') - if logger - logger.debug("contacts for #{entity.id} (#{entity.name}): " + redis.smembers("contacts_for:#{entity.id}").length.to_s) - logger.debug("contacts for #{check}: " + redis.smembers("contacts_for:#{check}").length.to_s) - end - - union = redis.sunion("contacts_for:#{entity.id}", "contacts_for:#{check}") - logger.debug("contacts for union of #{entity.id} and #{check}: " + union.length.to_s) if logger - union + contact_keys.inject([]) {|ret, k| + k =~ /^contact:(\d+)$/ + id = $1 + contact = self.find_by_id(id, :redis => redis) + ret << contact if contact + ret + } end def self.delete_all(options = {}) raise "Redis connection not set" unless redis = options[:redis] - contacts = redis.keys('contact:*') + redis.del( redis.keys("contact:*") + + redis.keys("contact_media:*") + + redis.keys("contact_pagerduty:*") + + redis.keys('contacts_for:*') ) + end - contacts.each do |c| - c =~ /^contact:(\d+)$/ - id = $1 + def self.find_by_id(id, options = {}) + raise "Redis connection not set" unless redis = options[:redis] + raise "No id value passed" unless id + logger = options[:logger] - redis.del("contact:#{id}") - redis.del("contact_media:#{id}") - redis.del("contact_pagerduty:#{id}") + fn, ln, em = redis.hmget("contact:#{id}", 'first_name', 'last_name', 'email') + me = redis.hgetall("contact_media:#{id}") + + # similar to code in instance method pagerduty_credentials + pc = nil + if service_key = redis.hget("contact_media:#{id}", 'pagerduty') + pc = redis.hgetall("contact_pagerduty:#{id}").merge('service_key' => service_key) end + + self.new(:first_name => fn, :last_name => ln, + :email => em, :id => id, :media => me, :pagerduty_credentials => pc, :redis => redis ) end + # NB: should probably be called in the context of a Redis multi block; not doing so # here as calling classes may well be adding/updating multiple records in the one # operation + # TODO maybe return the instantiated Contact record? def self.add(contact, options = {}) raise "Redis connection not set" unless redis = options[:redis] - redis.del("contact:#{contact['id']}") - redis.del("contact_media:#{contact['id']}") - redis.del("contact_pagerduty:#{contact['id']}") - ['first_name', 'last_name', 'email'].each do |field| - redis.hset("contact:#{contact['id']}", field, contact[field]) - end + redis.del("contact:#{contact['id']}", + "contact_media:#{contact['id']}", + "contact_pagerduty:#{contact['id']}") + + redis.hmset("contact:#{contact['id']}", + *['first_name', 'last_name', 'email'].collect {|f| [f, contact[f]]}) + contact['media'].each_pair {|medium, address| case medium when 'pagerduty' redis.hset("contact_media:#{contact['id']}", medium, address['service_key']) - redis.hset("contact_pagerduty:#{contact['id']}", 'subdomain', address['subdomain']) - redis.hset("contact_pagerduty:#{contact['id']}", 'username', address['username']) - redis.hset("contact_pagerduty:#{contact['id']}", 'password', address['password']) + redis.hmset("contact_pagerduty:#{contact['id']}", + *['subdomain', 'username', 'password'].collect {|f| [f, address[f]]}) else redis.hset("contact_media:#{contact['id']}", medium, address) end } end - def self.pagerduty_credentials_for_contact(contact, options = {}) - raise "Redis connection not set" unless redis = options[:redis] + def pagerduty_credentials + return unless service_key = @redis.hget("contact_media:#{self.id}", 'pagerduty') + @redis.hgetall("contact_pagerduty:#{self.id}"). + merge('service_key' => service_key) + end - return unless service_key = redis.hget("contact_media:#{contact}", 'pagerduty') + def entities + @redis.keys('contacts_for:*').inject([]) {|ret, k| + if @redis.sismember(k, self.id) + k =~ /^contacts_for:(.+)$/ + entity_id = $1 + if entity_name = @redis.hget("entity:#{entity_id}", 'name') + ret << Flapjack::Data::Entity.new(:name => entity_name, + :id => entity_id, :redis => @redis) + end + end + ret + } + end - redis.hgetall("contact_pagerduty:#{contact}"). - merge('service_key' => service_key) + def name + [(self.first_name || ''), (self.last_name || '')].join(" ").strip + end + + private + + def initialize(options = {}) + raise "Redis connection not set" unless @redis = options[:redis] + [:first_name, :last_name, :email, :media, :id].each do |field| + instance_variable_set(:"@#{field.to_s}", options[field]) + end end end end