Class: ScoutAgent::Assignment::Queue

Inherits:
ScoutAgent::Assignment show all
Defined in:
lib/scout_agent/assignment/queue.rb

Overview

Invoke with:

scout_agent q ID_OR_TYPE <<< '{"fields": "in JSON"}'

or:

ruby -e 'print Marshal.dump(:fields => "in Ruby")' | \
scout_agent q ID_OR_TYPE

This command queues some data from an external source for a plugin. The plugin to receive the message is given by ID in ID_OR_TYPE. That plugin will be able to collect this data during its next run.

Alternately, this command can be used to send a complete report, alert, error, or hint directly to the server (with the next check-in). When using as such, ID_OR_TYPE must be one of those types and the fields must be a Hash (object in JSON terminology) that includes the key “plugin_id” associated with an ID value for the reporting plugin.

If you prefer, you can pass Marshal data from Ruby for the fields instead of JSON.

Constant Summary collapse

ERRORS =

A list of errors that can be sent to the user when attempting to queue a message. The index of the message plus one is also the exit status for that error.

[ [ :missing_db,
"Queue database could not be loaded." ],
                 [ :missing_id,
"You must pass a mission ID or delivery type." ],
                 [ :invalid_id,
"You must pass a mission ID or " +
"'report', 'hint', 'alert', or 'error'." ],
                 [ :missing_fields,
"You must provide fields to queue." ],
                 [ :invalid_fields,
"You must pass valid JSON or Marshal data for the fields." ],
                 [ :invalid_report_fields,
"Field data must be a Hash to pass to the server." ],
                 [ :missing_plugin_id_field,
"A plugin_id field is required by the server." ],
                 [ :invalid_plugin_id_field,
"The plugin_id field must be a positive integer." ],
                 [ :failed_to_queue_message,
"Your message could not be queued at this time." ] ]

Instance Attribute Summary

Attributes inherited from ScoutAgent::Assignment

#group, #other_args, #switches, #user

Instance Method Summary collapse

Methods inherited from ScoutAgent::Assignment

choose_group, choose_user, #initialize, plan, #prepare_and_execute

Methods included from Tracked

#clear_status, #force_status_database_reload, #status, #status_database, #status_log

Constructor Details

This class inherits a constructor from ScoutAgent::Assignment

Instance Method Details

#executeObject

Runs the queue command.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/scout_agent/assignment/queue.rb', line 59

def execute
  # prepare the log
  log = ScoutAgent.prepare_wire_tap(:queue, :skip_stdout)

  # record our status and set removal at_exit()
  status_database(log)
  status("Queuing message", :queue)
  at_my_exit do
    clear_status(:queue)
  end
  
  # load the queue database
  unless db = Database.load(:queue, log)
    abort_with_error(:missing_db)
  end
  
  # ensure id or type is valid
  log.info("Validating message for queuing.")
  unless id = Array(other_args).shift
    abort_with_error(:missing_id)
  end
  unless id =~ /\A(?:report|hint|alert|error|\d*[1-9])\z/
    abort_with_error(:invalid_id)
  end
  
  # read field data and parse JSON
  fields = ARGF.read unless ARGV.empty? and not $stdin.ready?
  if fields.nil? or fields.empty?
    abort_with_error(:missing_fields)
  end
  bytes = fields.size
  begin
    if ["{", "["].include? fields[0, 1]  # it's JSON
      fields = JSON.parse(fields)
    else                                 # it's Marshal
      fields = Marshal.load(fields)
      if fields.is_a? Hash               # Stringify Hash keys
        (fields.keys - fields.keys.grep(String)).each do |key|
          fields[key.to_s] = fields.delete(key)
        end
      end
    end
  rescue Exception
    abort_with_error(:invalid_fields)
  end
  
  # ensure we have a valid plugin_id, if needed
  if %w[report hint alert error].include? id
    unless fields.is_a? Hash
      abort_with_error(:invalid_report_fields)
    end
    unless fields.include? "plugin_id"
      abort_with_error(:missing_plugin_id_field)
    end
    unless fields["plugin_id"].to_s =~ /\A\d*[1-9]\z/
      abort_with_error(:invalid_plugin_id_field)
    end
    log.info("Message is a valid #{id} (#{bytes} bytes).")
  else
    log.info("Message is valid (#{bytes} bytes).")
  end
  
  # queue the message
  log.info("Queuing message.")
  unless db.enqueue(id, fields)
    abort_with_error(:failed_to_queue_message)
  end
  
  # maintain the queue database
  db.maintain
  status_database.maintain
  # clean out old logs
  ScoutAgent.remove_old_log_files(log)
  
  log.info("Messages queued successfully.")
end