diff options
| author | Patrick J Cherry <patrick@bytemark.co.uk> | 2011-07-13 16:02:50 +0100 | 
|---|---|---|
| committer | Patrick J Cherry <patrick@bytemark.co.uk> | 2011-07-13 16:02:50 +0100 | 
| commit | e140af144e987ff7f6d767f2dc48b9cf685803fd (patch) | |
| tree | 4a01971890865b4b3ca837d563bc673cbb787de8 /lib/mauve/notifiers | |
| parent | d28af4ec946c6aa4b645b73cef47d7e0c680bc0d (diff) | |
 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
Diffstat (limited to 'lib/mauve/notifiers')
| -rw-r--r-- | lib/mauve/notifiers/email.rb | 17 | ||||
| -rw-r--r-- | lib/mauve/notifiers/sms_aql.rb | 5 | ||||
| -rw-r--r-- | lib/mauve/notifiers/xmpp-smack.rb | 395 | ||||
| -rw-r--r-- | lib/mauve/notifiers/xmpp.rb | 26 | 
4 files changed, 10 insertions, 433 deletions
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 "<p>" + alert.summary_two_lines.join("<br />") + "</p>" -        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  | 
