Exemple #1
0
                print("")
                print("WARNING:")
                print("By typing YES below this will start the upgrade process, after the process")
                print("the upgraded stats keys will be DELETED from the core_device_stats sql tabel.")
                print("This process can not be reversed, it is advised to make a backup of your")
                print("datatabse before starting this process")
                print("")
                conf = ""
                while conf not in ["YES I AM SURE", "no"]:
                    conf = raw_input("Type 'YES I AM SURE' to confirm, 'no' to cancel: ")
                if conf == "YES I AM SURE":
                    print("Starting the upgrade")
                    print ""
                else:
                    print("Upgrade CANCELED")

        else:
            do = False
        # close all
        db.close_session()
        if do:
            db.open_session()
            old_devs = corellateOld(db.upgrade_list_old())

    # - print done
    print("")
    print("Hooray, all old devices have been uprgaded")

    # - Disconnect the db
    del(db)
Exemple #2
0
class XplManager(XplPlugin, MQAsyncSub):
    """ Statistics manager
    """

    def __init__(self):
        """ Initiate DbHelper, Logs and config
        """
        XplPlugin.__init__(self, 'xplgw', log_prefix = "")
        MQAsyncSub.__init__(self, self.zmq, 'xplgw', ['client.conversion', 'client.list'])

        self.log.info(u"XPL manager initialisation...")
        self._db = DbHelper()
        self.pub = MQPub(zmq.Context(), 'xplgw')
        self.stats = None
        self.client_xpl_map = {}
        self.client_conversion_map = {}
        self._load_client_to_xpl_target()
        self._load_conversions()
        self.load()
        self.ready()

    def on_mdp_request(self, msg):
    # XplPlugin handles MQ Req/rep also
        try:
            XplPlugin.on_mdp_request(self, msg)

            if msg.get_action() == "reload":
                self.load()
                msg = MQMessage()
                msg.set_action( 'reload.result' )
                self.reply(msg.get())
            elif msg.get_action() == "cmd.send":
                self._send_xpl_command(msg)
        except:
            self.log.error(traceback.format_exc())

    def on_message(self, msgid, content):
        try:
            if msgid == 'client.conversion':
                self._parse_conversions(content)
            elif msgid == 'client.list':
                self._parse_xpl_target(content)
        except:
            self.log.error(traceback.format_exc())

    def _load_client_to_xpl_target(self):
        cli = MQSyncReq(self.zmq)
        msg = MQMessage()
        msg.set_action('client.list.get')
        response = cli.request('manager', msg.get(), timeout=10)
        if response:
            self._parse_xpl_target(response.get_data())
        else:
            self.log.error(u"Updating client list was not successfull, no response from manager")

    def _parse_xpl_target(self, data):
        tmp = {}
        for cli in data:
            tmp[cli] = data[cli]['xpl_source']
        self.client_xpl_map = tmp
    
    def _load_conversions(self):
        cli = MQSyncReq(self.zmq)
        msg = MQMessage()
        msg.set_action('client.conversion.get')
        response = cli.request('manager', msg.get(), timeout=10)
        if response:
            self._parse_conversions(response.get_data())
        else:
            self.log.error(u"Updating client conversion list was not successfull, no response from manager")

    def _parse_conversions(self, data):
        tmp = {}
        for cli in data:
            tmp[cli] = data[cli]
        self.client_conversion_map = tmp

    def _send_xpl_command(self, data):
        """ Reply to config.get MQ req
            @param data : MQ req message
                Needed info in data:
                - cmdid         => command id to send
                - cmdparams     => key/value pair of all params needed for this command
        """
        with self._db.session_scope():
            self.log.info(u"Received new cmd request: {0}".format(data))
            failed = False
            request = data.get_data()
            if 'cmdid' not in request:
                failed = "cmdid not in message data"
            if 'cmdparams' not in request:
                failed = "cmdparams not in message data"
            if not failed:
                # get the command
                cmd = self._db.get_command(request['cmdid'])
                if cmd is not None:
                    if cmd.xpl_command is not None:
                        xplcmd = cmd.xpl_command
                        xplstat = self._db.get_xpl_stat(xplcmd.stat_id)
                        if xplstat is not None:
                            # get the device from the db
                            dev = self._db.get_device(int(cmd.device_id))
                            msg = XplMessage()
                            if not dev['client_id'] in self.client_xpl_map.keys():
                                self._load_client_to_xpl_target()
                            if not dev['client_id'] in self.client_xpl_map.keys():
                                failed = "Can not fincd xpl source for {0} client_id".format(dev['client_id'])
                            else:
                                msg.set_target(self.client_xpl_map[dev['client_id']])
                            msg.set_source(self.myxpl.get_source())
                            msg.set_type("xpl-cmnd")
                            msg.set_schema( xplcmd.schema)
                            # static params
                            for p in xplcmd.params:
                                msg.add_data({p.key : p.value})
                            # dynamic params
                            for p in cmd.params:
                                if p.key in request['cmdparams']:
                                    value = request['cmdparams'][p.key]
                                    # chieck if we need a conversion
                                    if p.conversion is not None and p.conversion != '':
                                        if dev['client_id'] in self.client_conversion_map:
                                            if p.conversion in self.client_conversion_map[dev['client_id']]:
                                                exec(self.client_conversion_map[dev['client_id']][p.conversion])
                                                value = locals()[p.conversion](value)
                                    msg.add_data({p.key : value})
                                else:
                                    failed = "Parameter ({0}) for device command msg is not provided in the mq message".format(p.key)
                            if not failed:
                                # send out the msg
                                self.log.debug(u"sending xplmessage: {0}".format(msg))
                                self.myxpl.send(msg)
                                ### Wait for answer
                                stat_received = 0
                                if xplstat != None:
                                    # get xpl message from queue
                                    self.log.debug(u"Command : wait for answer...")
                                    sub = MQSyncSub( self.zmq, 'xplgw-command', ['device-stats'] )
                                    stat = sub.wait_for_event()
                                    if stat is not None:
                                        reply = json.loads(stat['content'])
                                        reply_msg = MQMessage()
                                        reply_msg.set_action('cmd.send.result')
                                        reply_msg.add_data('stat', reply)
                                        reply_msg.add_data('status', True)
                                        reply_msg.add_data('reason', None)
                                        self.log.debug(u"mq reply".format(reply_msg.get()))
                                        self.reply(reply_msg.get())
        if failed:
            self.log.error(failed)
            reply_msg = MQMessage()
            reply_msg.set_action('cmd.send.result')
            reply_msg.add_data('status', False)
            reply_msg.add_data('reason', failed)
            self.log.debug(u"mq reply".format(reply_msg.get()))
            self.reply(reply_msg.get())

    def load(self):
        """ (re)load all xml files to (re)create _Stats objects
        """
        self.log.info(u"Rest Stat Manager loading.... ")
        self._db.open_session()
        try:
            # not the first load : clean
            if self.stats != None:
                self.log.info(u"reloading")
                for stat in self.stats:
                    self.myxpl.del_listener(stat.get_listener())

            ### Load stats
            # key1, key2 = device_type_id, schema
            self.stats = []
            created_stats = []
            for stat in self._db.get_all_xpl_stat():
                # xpl-trig
                self.stats.append(self._Stat(self.myxpl, stat, "xpl-trig", \
                                self.log, self.pub, self.client_conversion_map))
                # xpl-stat
                self.stats.append(self._Stat(self.myxpl, stat, "xpl-stat", \
                                self.log, self.pub, self.client_conversion_map))
        except:
            self.log.error(u"%s" % traceback.format_exc())
        self._db.close_session()
        self.log.info(u"Loading finished")

    class _Stat:
        """ This class define a statistic parser and logger instance
        Each instance create a Listener and the associated callbacks
        """

        def __init__(self, xpl, stat, xpl_type, log, pub, conversions):
            """ Initialize a stat instance
            @param xpl : A xpl manager instance
            @param stat : A XplStat reference
            @param xpl-type: what xpl-type to listen for
            """
            ### Rest data
            self._log_stats = log
            self._stat = stat
            self._pub = pub
            self._conv = conversions

            ### build the filter
            params = {'schema': stat.schema, 'xpltype': xpl_type}
            for param in stat.params:
                if param.static:
                    params[param.key] = param.value

            ### start the listener
            self._log_stats.info("creating listener for %s" % (params))
            self._listener = Listener(self._callback, xpl, params)

        def get_listener(self):
            """ getter for lsitener object
            """
            return self._listener

        def _callback(self, message):
            """ Callback for the xpl message
            @param message : the Xpl message received
            """
            self._log_stats.debug( "_callback started for: {0}".format(message) )
            db = DbHelper()
            current_date = calendar.timegm(time.gmtime())
            stored_value = None
            try:
                # find what parameter to store
                for param in self._stat.params:
                    # self._log_stats.debug("Checking param {0}".format(param))
                    if param.sensor_id is not None and param.static is False:
                        if param.key in message.data:
                            with db.session_scope():
                                value = message.data[param.key]
                                # self._log_stats.debug( \
                                #        "Key found {0} with value {1}." \
                                #        .format(param.key, value))
                                store = True
                                if param.ignore_values:
                                    if value in eval(param.ignore_values):
                                        self._log_stats.debug( \
                                                "Value {0} is in the ignore list {0}, so not storing." \
                                                .format(value, param.ignore_values))
                                        store = False
                                if store:
                                    # get the sensor and dev
                                    sen = db.get_sensor(param.sensor_id)
                                    dev = db.get_device(sen.device_id)
                                    # check if we need a conversion
                                    if sen.conversion is not None and sen.conversion != '':
                                        if dev['client_id'] in self._conv:
                                            if sen.conversion in self._conv[dev['client_id']]:
                                                self._log_stats.debug( \
                                                    "Calling conversion {0}".format(sen.conversion))
                                                exec(self._conv[dev['client_id']][sen.conversion])
                                                value = locals()[sen.conversion](value)
                                    self._log_stats.info( \
                                            "Storing stat for device '{0}' ({1}) and sensor'{2}' ({3}): key '{4}' with value '{5}' after conversion." \
                                            .format(dev['name'], dev['id'], sen.name, sen.id, param.key, value))
                                    # do the store
                                    stored_value = value
                                    try:
                                        db.add_sensor_history(\
                                                param.sensor_id, \
                                                value, \
                                                current_date)
                                    except:
                                        self._log_stats.error("Error when adding sensor history : {0}".format(traceback.format_exc()))
                                else:
                                    self._log_stats.debug("Don't need to store this value")
                                # publish the result
                                self._pub.send_event('device-stats', \
                                          {"timestamp" : current_date, \
                                          "device_id" : dev['id'], \
                                          "sensor_id" : sen.id, \
                                          "stored_value" : stored_value})
                        #else:
                        #    self._log_stats.debug("Key not found in message data")
                    #else:
                    #    self._log_stats.debug("No sensor attached")
            except:
                self._log_stats.error(traceback.format_exc())
                )
                print(
                    "This process can not be reversed, it is advised to make a backup of your"
                )
                print("datatabse before starting this process")
                print("")
                conf = ""
                while conf not in ["YES I AM SURE", "no"]:
                    conf = raw_input(
                        "Type 'YES I AM SURE' to confirm, 'no' to cancel: ")
                if conf == "YES I AM SURE":
                    print("Starting the upgrade")
                    print ""
                else:
                    print("Upgrade CANCELED")

        else:
            do = False
        # close all
        db.close_session()
        if do:
            db.open_session()
            old_devs = corellateOld(db.upgrade_list_old())

    # - print done
    print("")
    print("Hooray, all old devices have been uprgaded")

    # - Disconnect the db
    del (db)