From e140af144e987ff7f6d767f2dc48b9cf685803fd Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Wed, 13 Jul 2011 16:02:50 +0100 Subject: Big commit * Added manpages for all binaries * Added log-reopening for mauvealert-server, and logrotate snippet * mauveserver now adds a user on install, and runs as that user * Big logging tidy-up * Alert subjects are only overwritten by the source, when the subject in the databse is empty * Removed various attr_writer methods that were being redifined * Added a notes box to the acknowledge form, but this doesn't work yet --- lib/mauve/notifiers/email.rb | 17 +- lib/mauve/notifiers/sms_aql.rb | 5 - lib/mauve/notifiers/xmpp-smack.rb | 395 -------------------------------------- lib/mauve/notifiers/xmpp.rb | 26 +-- 4 files changed, 10 insertions(+), 433 deletions(-) delete mode 100644 lib/mauve/notifiers/xmpp-smack.rb (limited to 'lib/mauve/notifiers') diff --git a/lib/mauve/notifiers/email.rb b/lib/mauve/notifiers/email.rb index 129afec..77b10f1 100644 --- a/lib/mauve/notifiers/email.rb +++ b/lib/mauve/notifiers/email.rb @@ -7,17 +7,9 @@ module Mauve module Notifiers module Email - - class Default + class Default attr_reader :name - attr :server, true - attr :port, true - attr :username, true - attr :password, true - attr :login_method, true - attr :from, true - attr :subject_prefix, true - attr :email_suffix, true + attr_writer :server, :port, :password, :login_method, :from, :subject_prefix, :email_suffix def username=(username) @login_method ||= :plain @@ -47,20 +39,15 @@ module Mauve message = prepare_message(destination, alert, all_alerts, conditions) args = [@server, @port] args += [@username, @password, @login_method.to_sym] if @login_method - history = Mauve::History.new(:alert => alert, :type => :notification) begin Net::SMTP.start(*args) do |smtp| smtp.send_message(message, @from, destination) end - history.event = "Sent mail to #{destination}." - history.save true rescue StandardError => ex logger.error "SMTP failure: #{ex.to_s}" logger.debug ex.backtrace.join("\n") - history.event = "Failed to send mail to #{destination} due to #{ex.to_s}" - history.save false end end diff --git a/lib/mauve/notifiers/sms_aql.rb b/lib/mauve/notifiers/sms_aql.rb index b295e6c..dbda229 100644 --- a/lib/mauve/notifiers/sms_aql.rb +++ b/lib/mauve/notifiers/sms_aql.rb @@ -41,17 +41,12 @@ module Mauve 'Content-Length' => opts_string.length.to_s }) - history = Mauve::History.new(:alert => alert, :type => :notification) if response.kind_of?(Net::HTTPSuccess) - history.event = "Sent SMS via AQL to #{destination}" - history.save # # Woo -- return true! # true else - history.event = "Failed to send SMS via AQL to #{destination} due to #{response.class.to_s}" - history.save false end end diff --git a/lib/mauve/notifiers/xmpp-smack.rb b/lib/mauve/notifiers/xmpp-smack.rb deleted file mode 100644 index a160a35..0000000 --- a/lib/mauve/notifiers/xmpp-smack.rb +++ /dev/null @@ -1,395 +0,0 @@ -# encoding: utf-8 - -# Ruby. -require 'pp' -require 'log4r' -require 'monitor' - -# Java. Note that paths are mangeled in jmauve_starter. -require 'java' -require 'smack.jar' -require 'smackx.jar' -include_class "org.jivesoftware.smack.XMPPConnection" -include_class "org.jivesoftware.smackx.muc.MultiUserChat" -include_class "org.jivesoftware.smack.RosterListener" - -module Mauve - - module Notifiers - - module Xmpp - - class XMPPSmackException < StandardError - end - - ## Main wrapper to smack java library. - # - # @author Yann Golanski - # @see http://www.igniterealtime.org/builds/smack/docs/3.1.0/javadoc/ - # - # This is a singleton which is not idea but works well for mauve's - # configuration file set up. - # - # In general, this class is meant to be intialized then the method - # create_slave_thread must be called. The latter will spawn a new - # thread that will do the connecting and sending of messages to - # the XMPP server. Once this is done, messages can be send via the - # send_msg() method. Those will be queued and depending on the load, - # should be send quickly enough. This is done so that the main thread - # can not worry about sending messages and can do important work. - # - # @example - # bot = Mauve::Notifiers::Xmpp::XMPPSmack.new() - # bot.run_slave_thread("chat.bytemark.co.uk", 'mauvealert', 'TopSecret') - # msg = "What fresh hell is this? -- Dorothy Parker." - # bot.send_msg("yann@chat.bytemark.co.uk", msg) - # bot.send_msg("muc:test@conference.chat.bytemark.co.uk", msg) - # - # @FIXME This won't quiet work with how mauve is set up. - # - class XMPPSmack - - # Globals are evil. - @@instance = nil - - # Default constructor. - # - # A queue (@queue) is used to pass information between master/slave. - def initialize () - extend(MonitorMixin) - @logger = Log4r::Logger.new "mauve::XMPP_smack<#{Process.pid}>" - @queue = Queue.new - @xmpp = nil - @name = "mauve alert" - @slave_thread = nil - @regexp_muc = Regexp.compile(/^muc\:/) - @regexp_tail = Regexp.compile(/\/.*$/) - @jid_created_chat = Hash.new() - @separator = '<->' - @logger.info("Created XMPPSmack singleton") - end - - # Returns the instance of the XMPPSmack singleton. - # - # @param [String] login The JID as a full address. - # @param [String] pwd The password corresponding to the JID. - # @return [XMPPSmack] The singleton instance. - def self.instance (login, pwd) - if true == @@instance.nil? - @@instance = XMPPSmack.new - jid, tmp = login.split(/@/) - srv, name = tmp.split(/\//) - name = "Mauve Alert Bot" if true == name.nil? - @@instance.run_slave_thread(srv, jid, pwd, name) - sleep 5 # FIXME: This really should be synced... But how? - end - return @@instance - end - - # Create the thread that sends messages to the server. - # - # @param [String] srv The server address. - # @param [String] jid The JID. - # @param [String] pwd The password corresponding to the JID. - # @param [String] name The bot name. - # @return [NULL] nada - def run_slave_thread (srv, jid, pwd, name) - @srv = srv - @jid = jid - @pwd = pwd - @name = name - @logger.info("Creating slave thread on #{@jid}@#{@srv}/#{@name}.") - @slave_thread = Thread.new do - self.create_slave_thread() - end - return nil - end - - # Returns whether instance is connected and authenticated. - # - # @return [Boolean] True or false. - def is_connected_and_authenticated? () - return false if true == @xmpp.nil? - return (@xmpp.isConnected() and @xmpp.isAuthenticated()) - end - - # Creates the thread that does the actual sending to XMPP. - # @return [NULL] nada - def create_slave_thread () - begin - @logger.info("Slave thread is now alive.") - self.open() - loop do - rcp, msg = @queue.deq().split(@separator, 2) - @logger.debug("New message for '#{rcp}' saying '#{msg}'.") - if rcp.match(@regexp_muc) - room = rcp.gsub(@regexp_muc, '').gsub(@regexp_tail, '') - self.send_to_muc(room, msg) - else - self.send_to_jid(rcp, msg) - end - end - rescue XMPPSmackException - @logger.fatal("Something is wrong") - ensure - @logger.info("XMPP bot disconnect.") - @xmpp.disconnect() - end - return nil - end - - # Send a message to the recipient. - # - # @param [String] rcp The recipent MUC or JID. - # @param [String] msg The message. - # @return [NULL] nada - def send_msg(rcp, msg) - #if @slave_thread.nil? or not self.is_connected_and_authenticated?() - # str = "There is either no slave thread running or a disconnect..." - # @logger.warn(str) - # self.reconnect() - #end - @queue.enq(rcp + @separator + msg) - return nil - end - - # Sends a message to a room. - # - # @param [String] room The name of the room. - # @param [String] mgs The message to send. - # @return [NULL] nada - def send_to_muc (room, msg) - if not @jid_created_chat.has_key?(room) - @jid_created_chat[room] = MultiUserChat.new(@xmpp, room) - @jid_created_chat[room].join(@name) - end - @logger.debug("Sending to MUC '#{room}' message '#{msg}'.") - @jid_created_chat[room].sendMessage(msg) - return nil - end - - # Sends a message to a jid. - # - # Do not destroy the chat, we can reuse it when the user log back in again. - # Maybe? - # - # @param [String] jid The JID of the recipient. - # @param [String] mgs The message to send. - # @return [NULL] nada - def send_to_jid (jid, msg) - if true == jid_is_available?(jid) - if not @jid_created_chat.has_key?(jid) - @jid_created_chat[jid] = @xmpp.getChatManager.createChat(jid, nil) - end - @logger.debug("Sending to JID '#{jid}' message '#{msg}'.") - @jid_created_chat[jid].sendMessage(msg) - end - return nil - end - - # Check to see if the jid is available or not. - # - # @param [String] jid The JID of the recipient. - # @return [Boolean] Whether we can send a message or not. - def jid_is_available?(jid) - if true == @xmpp.getRoster().getPresence(jid).isAvailable() - @logger.debug("#{jid} is available. Status is " + - "#{@xmpp.getRoster().getPresence(jid).getStatus()}") - return true - else - @logger.warn("#{jid} is not available. Status is " + - "#{@xmpp.getRoster().getPresence(jid).getStatus()}") - return false - end - end - - # Opens a connection to the xmpp server at given port. - # - # @return [NULL] nada - def open() - @logger.info("XMPP bot is being created.") - self.open_connection() - self.open_authentication() - self.create_roster() - sleep 5 - return nil - end - - # Connect to server. - # - # @return [NULL] nada - def open_connection() - @xmpp = XMPPConnection.new(@srv) - if false == self.connect() - str = "Connection refused" - @logger.error(str) - raise XMPPSmackException.new(str) - end - @logger.debug("XMPP bot connected successfully.") - return nil - end - - # Authenticat connection. - # - # @return [NULL] nada - def open_authentication() - if false == self.login(@jid, @pwd) - str = "Authentication failed" - @logger.error(str) - raise XMPPSmackException.new(str) - end - @logger.debug("XMPP bot authenticated successfully.") - return nil - end - - # Create a new roster and listener. - # - # @return [NULL] nada - def create_roster - @xmpp.getRoster().addRosterListener(RosterListener.new()) - @xmpp.getRoster().reload() - @xmpp.getRoster().getPresence(@xmpp.getUser).setStatus( - "Purple alert! Purple alert!") - @logger.debug("XMPP bot roster aquired successfully.") - return nil - end - - # Connects to the server. - # - # @return [Boolean] true (aka sucess) or false (aka failure). - def connect () - @xmpp.connect() - return @xmpp.isConnected() - end - - # Login onto the server. - # - # @param [String] jid The JID. - # @param [String] pwd The password corresponding to the JID. - # @return [Boolean] true (aka sucess) or false (aka failure). - def login (jid, pwd) - @xmpp.login(jid, pwd, @name) - return @xmpp.isAuthenticated() - end - - # Reconnects in case of errors. - # - # @return [NULL] nada - def reconnect() - @xmpp.disconnect - @slave_thread = Thread.new do - self.create_slave_thread() - end - return nil - end - - def presenceChanged () - end - - end # XMPPSmack - - - ## This is the class that gets called in person.rb. - # - # This class is a wrapper to XMPPSmack which does the hard work. It is - # done this way to conform to the mauve configuration file way of - # defining notifications. - # - # @author Yann Golanski - class Default - - # Name of the class. - attr_reader :name - - # Atrtribute. - attr_accessor :jid - - # Atrtribute. - attr_accessor :password - - # Atrtribute. - attr_accessor :initial_jid - - # Atrtribute. - attr_accessor :initial_messages - - # Default constructor. - # - # @param [String] name The name of the notifier. - def initialize (name) - extend(MonitorMixin) - @name = name - @logger = Log4r::Logger.new "mauve::XMPP_default<#{Process.pid}>" - end - - # Sends a message to the relevant jid or muc. - # - # We have no way to know if a messages was recieved, only that - # we send it. - # - # @param [String] destionation - # @param [Alert] alert A mauve alert class - # @param [Array] all_alerts subset of current alerts - # @param [Hash] conditions Supported conditions, see above. - # @return [Boolean] Whether a message can be send or not. - def send_alert(destination, alert, all_alerts, conditions = nil) - synchronize { - client = XMPPSmack.instance(@jid, @password) - if not destination.match(/^muc:/) - if false == client.jid_is_available?(destination.gsub(/^muc:/, '')) - return false - end - end - client.send_msg(destination, convert_alert_to_message(alert)) - return true - } - end - - # Takes an alert and converts it into a message. - # - # @param [Alert] alert The alert to convert. - # @return [String] The message, either as HTML. - def convert_alert_to_message(alert) - arr = alert.summary_three_lines - str = arr[0] + ": " + arr[1] - str += " -- " + arr[2] if false == arr[2].nil? - str += "." - return str - #return alert.summary_two_lines.join(" -- ") - #return "

" + alert.summary_two_lines.join("
") + "

" - end - - # This is so unit tests can run fine. - include Debug - - end # Default - - end - end -end - -# This is a simple example of usage. Run with: -# ../../../jmauve_starter.rb xmpp-smack.rb -# Clearly, the mauve jabber password is not correct. -# -# /!\ WARNING: DO NOT COMMIT THE REAL PASSWORD TO MERCURIAL!!! -# -def send_msg() - bot = Mauve::Notifiers::Xmpp::XMPPSmack.instance( - "mauvealert@chat.bytemark.co.uk/testing1234", '') - msg = "What fresh hell is this? -- Dorothy Parker." - bot.send_msg("yann@chat.bytemark.co.uk", msg) - bot.send_msg("muc:test@conference.chat.bytemark.co.uk", msg) - sleep 2 -end - -if __FILE__ == './'+$0 - Thread.abort_on_exception = true - logger = Log4r::Logger.new('mauve') - logger.level = Log4r::DEBUG - logger.add Log4r::Outputter.stdout - send_msg() - send_msg() - logger.info("START") - logger.info("END") -end diff --git a/lib/mauve/notifiers/xmpp.rb b/lib/mauve/notifiers/xmpp.rb index c4e1785..8131096 100644 --- a/lib/mauve/notifiers/xmpp.rb +++ b/lib/mauve/notifiers/xmpp.rb @@ -66,10 +66,10 @@ module Mauve include Jabber # Atrtribute. - attr_reader :name + attr_reader :name, :jid # Atrtribute. - attr_accessor :jid, :password + attr_accessor :password def initialize(name) Jabber::logger = self.logger @@ -80,7 +80,7 @@ module Mauve @mucs = {} @roster = nil @closing = false - + @client = nil end def logger @@ -93,7 +93,7 @@ module Mauve end def connect - logger.info "Jabber starting connection to #{@jid}" + logger.debug "Starting connection to #{@jid}" # Make sure we're disconnected. self.close if @client.is_a?(Client) @@ -110,7 +110,6 @@ module Mauve # already @roster.add_subscription_request_callback do |ri, presence| Thread.new do - logger.debug "Known? #{is_known_contact?(presence.from).inspect}" if is_known_contact?(presence.from) logger.info("Accepting subscription request from #{presence.from}") @roster.accept_subscription(presence.from) @@ -127,10 +126,11 @@ module Mauve end @roster.wait_for_roster - logger.debug "Jabber authenticated, setting presence" @client.send(Presence.new(nil, "Woo!").set_type(nil)) + logger.info "Connected as #{@jid}" + @client.on_exception do |ex, stream, where| # # The XMPP4R exception clauses in Stream all close the stream, so @@ -203,17 +203,7 @@ module Mauve alert.to_s end - history = Mauve::History.new(:alert_id => alert.id, :type => :notification) - - if send_message(destination_jid, txt) - history.event = "Sent XMPP message to #{destination_jid}" - history.save - true - else - history.event = "Failed to send XMPP message to #{destination_jid}" - history.save - false - end + send_message(destination_jid, txt) end # Sends a message to the destionation. @@ -297,12 +287,12 @@ module Mauve end if !@mucs[jid.strip].active? - logger.info("Joining #{jid}") # # Make sure we have a resource. # @mucs[jid.strip].join(jid, password) + logger.info("Joined #{jid}") else logger.debug("Already joined #{jid}.") end -- cgit v1.2.1