|
@@ -19,15 +19,28 @@ class Agent < ActiveRecord::Base
|
|
|
|
|
|
load_types_in "Agents"
|
|
|
|
|
|
- SCHEDULES = %w[every_1m every_2m every_5m every_10m every_30m every_1h every_2h every_5h every_12h every_1d every_2d every_7d] +
|
|
|
- %w[midnight 1am 2am 3am 4am 5am 6am 7am 8am 9am 10am 11am noon 1pm 2pm 3pm 4pm 5pm 6pm 7pm 8pm 9pm 10pm 11pm never]
|
|
|
+ SCHEDULES = %w[
|
|
|
+ every_1m every_2m every_5m every_10m every_30m
|
|
|
+ every_1h every_2h every_5h every_12h
|
|
|
+ every_1d every_2d every_7d
|
|
|
+ midnight 1am 2am 3am 4am 5am 6am 7am 8am 9am 10am 11am
|
|
|
+ noon 1pm 2pm 3pm 4pm 5pm 6pm 7pm 8pm 9pm 10pm 11pm
|
|
|
+ never
|
|
|
+ ]
|
|
|
|
|
|
- EVENT_RETENTION_SCHEDULES = [["Forever", 0], ['1 hour', 1.hour], ['6 hours', 6.hours], ["1 day", 1.day], *([2, 3, 4, 5, 7, 14, 21, 30, 45, 90, 180, 365].map {|n| ["#{n} days", n.days] })]
|
|
|
+ EVENT_RETENTION_SCHEDULES = [
|
|
|
+ ["Forever", 0], ['1 hour', 1.hour], ['6 hours', 6.hours], ["1 day", 1.day],
|
|
|
+ *(
|
|
|
+ [2, 3, 4, 5, 7, 14, 21, 30, 45, 90, 180, 365].map { |n|
|
|
|
+ ["#{n} days", n.days]
|
|
|
+ }
|
|
|
+ )
|
|
|
+ ]
|
|
|
|
|
|
json_serialize :options, :memory
|
|
|
|
|
|
validates_presence_of :name, :user
|
|
|
- validates_inclusion_of :keep_events_for, :in => EVENT_RETENTION_SCHEDULES.map(&:last)
|
|
|
+ validates_inclusion_of :keep_events_for, in: EVENT_RETENTION_SCHEDULES.map(&:last)
|
|
|
validates :sources, owned_by: :user_id
|
|
|
validates :receivers, owned_by: :user_id
|
|
|
validates :controllers, owned_by: :user_id
|
|
@@ -43,34 +56,37 @@ class Agent < ActiveRecord::Base
|
|
|
before_create :set_last_checked_event_id
|
|
|
after_save :possibly_update_event_expirations
|
|
|
|
|
|
- belongs_to :user, :inverse_of => :agents
|
|
|
- belongs_to :service, :inverse_of => :agents, optional: true
|
|
|
- has_many :events, -> { order("events.id desc") }, :dependent => :delete_all, :inverse_of => :agent
|
|
|
- has_one :most_recent_event, -> { order("events.id desc") }, :inverse_of => :agent, :class_name => "Event"
|
|
|
- has_many :logs, -> { order("agent_logs.id desc") }, :dependent => :delete_all, :inverse_of => :agent, :class_name => "AgentLog"
|
|
|
- has_many :links_as_source, :dependent => :delete_all, :foreign_key => "source_id", :class_name => "Link", :inverse_of => :source
|
|
|
- has_many :links_as_receiver, :dependent => :delete_all, :foreign_key => "receiver_id", :class_name => "Link", :inverse_of => :receiver
|
|
|
- has_many :sources, :through => :links_as_receiver, :class_name => "Agent", :inverse_of => :receivers
|
|
|
- has_many :received_events, -> { order("events.id desc") }, :through => :sources, :class_name => "Event", :source => :events
|
|
|
- has_many :receivers, :through => :links_as_source, :class_name => "Agent", :inverse_of => :sources
|
|
|
- has_many :control_links_as_controller, dependent: :delete_all, foreign_key: 'controller_id', class_name: 'ControlLink', inverse_of: :controller
|
|
|
- has_many :control_links_as_control_target, dependent: :delete_all, foreign_key: 'control_target_id', class_name: 'ControlLink', inverse_of: :control_target
|
|
|
+ belongs_to :user, inverse_of: :agents
|
|
|
+ belongs_to :service, inverse_of: :agents, optional: true
|
|
|
+ has_many :events, -> { order("events.id desc") }, dependent: :delete_all, inverse_of: :agent
|
|
|
+ has_one :most_recent_event, -> { order("events.id desc") }, inverse_of: :agent, class_name: "Event"
|
|
|
+ has_many :logs, -> { order("agent_logs.id desc") }, dependent: :delete_all, inverse_of: :agent, class_name: "AgentLog"
|
|
|
+ has_many :links_as_source, dependent: :delete_all, foreign_key: "source_id", class_name: "Link",
|
|
|
+ inverse_of: :source
|
|
|
+ has_many :links_as_receiver, dependent: :delete_all, foreign_key: "receiver_id", class_name: "Link",
|
|
|
+ inverse_of: :receiver
|
|
|
+ has_many :sources, through: :links_as_receiver, class_name: "Agent", inverse_of: :receivers
|
|
|
+ has_many :received_events, -> { order("events.id desc") }, through: :sources, class_name: "Event", source: :events
|
|
|
+ has_many :receivers, through: :links_as_source, class_name: "Agent", inverse_of: :sources
|
|
|
+ has_many :control_links_as_controller, dependent: :delete_all, foreign_key: 'controller_id',
|
|
|
+ class_name: 'ControlLink', inverse_of: :controller
|
|
|
+ has_many :control_links_as_control_target, dependent: :delete_all, foreign_key: 'control_target_id',
|
|
|
+ class_name: 'ControlLink', inverse_of: :control_target
|
|
|
has_many :controllers, through: :control_links_as_control_target, class_name: "Agent", inverse_of: :control_targets
|
|
|
has_many :control_targets, through: :control_links_as_controller, class_name: "Agent", inverse_of: :controllers
|
|
|
- has_many :scenario_memberships, :dependent => :destroy, :inverse_of => :agent
|
|
|
- has_many :scenarios, :through => :scenario_memberships, :inverse_of => :agents
|
|
|
+ has_many :scenario_memberships, dependent: :destroy, inverse_of: :agent
|
|
|
+ has_many :scenarios, through: :scenario_memberships, inverse_of: :agents
|
|
|
|
|
|
scope :active, -> { where(disabled: false, deactivated: false) }
|
|
|
- scope :inactive, -> { where(['disabled = ? OR deactivated = ?', true, true]) }
|
|
|
-
|
|
|
- scope :of_type, lambda { |type|
|
|
|
- type = case type
|
|
|
- when Agent
|
|
|
- type.class.to_s
|
|
|
- else
|
|
|
- type.to_s
|
|
|
- end
|
|
|
- where(:type => type)
|
|
|
+ scope :inactive, -> { where(disabled: true).or(where(deactivated: true)) }
|
|
|
+
|
|
|
+ scope :of_type, ->(type) {
|
|
|
+ case type
|
|
|
+ when Agent
|
|
|
+ where(type: type.class.to_s)
|
|
|
+ else
|
|
|
+ where(type: type.to_s)
|
|
|
+ end
|
|
|
}
|
|
|
|
|
|
def short_type
|
|
@@ -131,7 +147,7 @@ class Agent < ActiveRecord::Base
|
|
|
if @credential_cache.has_key?(name)
|
|
|
@credential_cache[name]
|
|
|
else
|
|
|
- @credential_cache[name] = user.user_credentials.where(:credential_name => name).first.try(:credential_value)
|
|
|
+ @credential_cache[name] = user.user_credentials.where(credential_name: name).first.try(:credential_value)
|
|
|
end
|
|
|
end
|
|
|
|
|
@@ -146,7 +162,7 @@ class Agent < ActiveRecord::Base
|
|
|
|
|
|
def update_event_expirations!
|
|
|
if keep_events_for == 0
|
|
|
- events.update_all :expires_at => nil
|
|
|
+ events.update_all expires_at: nil
|
|
|
else
|
|
|
events.update_all "expires_at = " + rdbms_date_add("created_at", "SECOND", keep_events_for.to_i)
|
|
|
end
|
|
@@ -161,11 +177,12 @@ class Agent < ActiveRecord::Base
|
|
|
save!
|
|
|
end
|
|
|
else
|
|
|
- if method(:receive_web_request).arity == 1
|
|
|
- handled_request = receive_web_request(request)
|
|
|
- else
|
|
|
- handled_request = receive_web_request(params, request.method_symbol.to_s, request.format.to_s)
|
|
|
- end
|
|
|
+ handled_request =
|
|
|
+ if method(:receive_web_request).arity == 1
|
|
|
+ receive_web_request(request)
|
|
|
+ else
|
|
|
+ receive_web_request(params, request.method_symbol.to_s, request.format.to_s)
|
|
|
+ end
|
|
|
handled_request.tap do
|
|
|
self.last_web_request_at = Time.now
|
|
|
save!
|
|
@@ -226,7 +243,7 @@ class Agent < ActiveRecord::Base
|
|
|
end
|
|
|
|
|
|
def error(message, options = {})
|
|
|
- log(message, options.merge(:level => 4))
|
|
|
+ log(message, options.merge(level: 4))
|
|
|
end
|
|
|
|
|
|
def delete_logs!
|
|
@@ -261,9 +278,9 @@ class Agent < ActiveRecord::Base
|
|
|
def possibly_update_event_expirations
|
|
|
update_event_expirations! if saved_change_to_keep_events_for?
|
|
|
end
|
|
|
-
|
|
|
- #Validation Methods
|
|
|
-
|
|
|
+
|
|
|
+ # Validation Methods
|
|
|
+
|
|
|
private
|
|
|
|
|
|
attr_accessor :current_event
|
|
@@ -273,7 +290,7 @@ class Agent < ActiveRecord::Base
|
|
|
errors.add(:schedule, "is not a valid schedule") unless SCHEDULES.include?(schedule.to_s)
|
|
|
end
|
|
|
end
|
|
|
-
|
|
|
+
|
|
|
def validate_options
|
|
|
# Implement me in your subclass to test for valid options.
|
|
|
end
|
|
@@ -293,7 +310,7 @@ class Agent < ActiveRecord::Base
|
|
|
|
|
|
def is_positive_integer?(value)
|
|
|
Integer(value) >= 0
|
|
|
- rescue
|
|
|
+ rescue StandardError
|
|
|
false
|
|
|
end
|
|
|
|
|
@@ -301,8 +318,10 @@ class Agent < ActiveRecord::Base
|
|
|
|
|
|
class << self
|
|
|
def build_clone(original)
|
|
|
- new(original.slice(:type, :options, :service_id, :schedule, :controller_ids, :control_target_ids,
|
|
|
- :source_ids, :receiver_ids, :keep_events_for, :propagate_immediately, :scenario_ids)) { |clone|
|
|
|
+ new(original.slice(
|
|
|
+ :type, :options, :service_id, :schedule, :controller_ids, :control_target_ids,
|
|
|
+ :source_ids, :receiver_ids, :keep_events_for, :propagate_immediately, :scenario_ids
|
|
|
+ )) { |clone|
|
|
|
# Give it a unique name
|
|
|
2.step do |i|
|
|
|
name = '%s (%d)' % [original.name, i]
|
|
@@ -379,14 +398,14 @@ class Agent < ActiveRecord::Base
|
|
|
# Find all Agents that have received Events since the last execution of this method. Update those Agents with
|
|
|
# their new `last_checked_event_id` and queue each of the Agents to be called with #receive using `async_receive`.
|
|
|
# This is called by bin/schedule.rb periodically.
|
|
|
- def receive!(options={})
|
|
|
+ def receive!(options = {})
|
|
|
Agent.transaction do
|
|
|
- scope = Agent.
|
|
|
- select("agents.id AS receiver_agent_id, sources.type AS source_agent_type, agents.type AS receiver_agent_type, events.id AS event_id").
|
|
|
- joins("JOIN links ON (links.receiver_id = agents.id)").
|
|
|
- joins("JOIN agents AS sources ON (links.source_id = sources.id)").
|
|
|
- joins("JOIN events ON (events.agent_id = sources.id AND events.id > links.event_id_at_creation)").
|
|
|
- where("NOT agents.disabled AND NOT agents.deactivated AND (agents.last_checked_event_id IS NULL OR events.id > agents.last_checked_event_id)")
|
|
|
+ scope = Agent
|
|
|
+ .select("agents.id AS receiver_agent_id, sources.type AS source_agent_type, agents.type AS receiver_agent_type, events.id AS event_id")
|
|
|
+ .joins("JOIN links ON (links.receiver_id = agents.id)")
|
|
|
+ .joins("JOIN agents AS sources ON (links.source_id = sources.id)")
|
|
|
+ .joins("JOIN events ON (events.agent_id = sources.id AND events.id > links.event_id_at_creation)")
|
|
|
+ .where("NOT agents.disabled AND NOT agents.deactivated AND (agents.last_checked_event_id IS NULL OR events.id > agents.last_checked_event_id)")
|
|
|
if options[:only_receivers].present?
|
|
|
scope = scope.where("agents.id in (?)", options[:only_receivers])
|
|
|
end
|
|
@@ -395,7 +414,6 @@ class Agent < ActiveRecord::Base
|
|
|
|
|
|
agents_to_events = {}
|
|
|
Agent.connection.select_rows(sql).each do |receiver_agent_id, source_agent_type, receiver_agent_type, event_id|
|
|
|
-
|
|
|
begin
|
|
|
Object.const_get(source_agent_type)
|
|
|
Object.const_get(receiver_agent_type)
|
|
@@ -407,7 +425,7 @@ class Agent < ActiveRecord::Base
|
|
|
agents_to_events[receiver_agent_id.to_i] << event_id
|
|
|
end
|
|
|
|
|
|
- Agent.where(:id => agents_to_events.keys).each do |agent|
|
|
|
+ Agent.where(id: agents_to_events.keys).each do |agent|
|
|
|
event_ids = agents_to_events[agent.id].uniq
|
|
|
agent.update_attribute :last_checked_event_id, event_ids.max
|
|
|
|
|
@@ -419,8 +437,8 @@ class Agent < ActiveRecord::Base
|
|
|
end
|
|
|
|
|
|
{
|
|
|
- :agent_count => agents_to_events.keys.length,
|
|
|
- :event_count => agents_to_events.values.flatten.uniq.compact.length
|
|
|
+ agent_count: agents_to_events.keys.length,
|
|
|
+ event_count: agents_to_events.values.flatten.uniq.compact.length
|
|
|
}
|
|
|
end
|
|
|
end
|
|
@@ -435,9 +453,11 @@ class Agent < ActiveRecord::Base
|
|
|
# This is called by bin/schedule.rb for each schedule in `SCHEDULES`.
|
|
|
def run_schedule(schedule)
|
|
|
return if schedule == 'never'
|
|
|
- types = where(:schedule => schedule).group(:type).pluck(:type)
|
|
|
+
|
|
|
+ types = where(schedule: schedule).group(:type).pluck(:type)
|
|
|
types.each do |type|
|
|
|
next unless valid_type?(type)
|
|
|
+
|
|
|
type.constantize.bulk_check(schedule)
|
|
|
end
|
|
|
end
|
|
@@ -446,6 +466,7 @@ class Agent < ActiveRecord::Base
|
|
|
# per type of agent, so you can override this to define custom bulk check behavior for your custom Agent type.
|
|
|
def bulk_check(schedule)
|
|
|
raise "Call #bulk_check on the appropriate subclass of Agent" if self == Agent
|
|
|
+
|
|
|
where("NOT disabled AND NOT deactivated AND schedule = ?", schedule).pluck("agents.id").each do |agent_id|
|
|
|
async_check(agent_id)
|
|
|
end
|