Exemplo n.º 1
0
 def unsubscribe_override(self, cmd_name, cmd_params):
     'Implement the unsubscribe operation'
     try:
         if self.notif_token:
             log.info('Sending %s: %s' % (cmd_name, self.notif_token))
             resp = self.manager.unsubscribe(self.notif_token)
             log.info('Received response %s: %s' % (cmd_name, resp))
             self.notif_thread.join()
             self.notif_thread = None
             self.notif_token = None
         return {'result': "OK"}
     except xmlrpclib.Fault as ex:
         log.error(str(ex))
         raise ApiException.APIError(cmd_name[0], str(ex))
Exemplo n.º 2
0
    def subscribe_override(self, cmd_name, cmd_params):
        'Implement the subscribe operation'
        # create a new notif session unless a notif session already exists
        token = self.login_token
        if self.notif_token:
            token = self.notif_token
        try:
            notif_filter = cmd_params['filter']
        except KeyError:
            raise ApiException.APIError(
                ApiException.CommandError.TOO_FEW_FIELDS,
                "expected 'filter' parameter")
        # call the Manager API subscribe command
        try:
            log.info('Sending %s: %s' % (cmd_name, [token, notif_filter]))
            (self.notif_token,
             self.notif_port) = self.manager.subscribe(token, notif_filter)
            log.info('Received response %s: %s %s' %
                     (cmd_name, self.notif_token, self.notif_port))

        except xmlrpclib.Fault as ex:
            log.error(str(ex))
            raise ApiException.APIError(cmd_name[0], str(ex))

        # create the notification thread
        if not self.notif_thread:
            self.notif_thread = NotifReader(
                self.connect_params['host'],
                int(self.notif_port),
                self.notif_token,
                use_ssl=self.connect_params['use_ssl'],
                notif_callback=self.handle_notif,
                disconnect_callback=self.handle_notif_disconnect)
            self.notif_thread.connect()
            self.notif_thread.daemon = True
            self.notif_thread.start()
        return {'notif_token': self.notif_token}
Exemplo n.º 3
0
    def send(self, cmd_name, cmd_params):
        # ensure the application is connected
        if not self.login_token:
            raise ApiException.ConnectionError('not connected')

        # handle command overrides - replacement methods for processing a command
        cmd_metadata = self.apidef.getDefinition(self.apidef.COMMAND, cmd_name)
        if 'command_override' in cmd_metadata:
            cmd_override = getattr(self, cmd_metadata['command_override'])
            resp = cmd_override(cmd_name, cmd_params)
            return resp

        # construct the XML-RPC parameter list
        # validation happens automatically as part of serialization
        param_list = self.apidef.serialize(cmd_name, cmd_params)
        log.info('Sending %s: %s' % (cmd_name, param_list))

        # call method by string name, params is a list of the parameters
        params = [self.login_token] + param_list
        cmd_id = self.apidef.nameToId(self.apidef.COMMAND, cmd_name)
        try:
            xmlrpc_resp = getattr(self.manager, cmd_id)(*params)
        except xmlrpclib.Fault as ex:
            log.error(str(ex))
            raise ApiException.APIError(cmd_name[0], str(ex))

        log.info('Received response %s: %s' % (cmd_name, xmlrpc_resp))
        # call deserialize to parse the response into a dict
        resp = self.apidef.deserialize(cmd_name, xmlrpc_resp)

        # call a command-specific post-processor method
        cmd_metadata = self.apidef.getDefinition(self.apidef.COMMAND, cmd_name)
        if 'post_processor' in cmd_metadata:
            post_processor = getattr(self, cmd_metadata['post_processor'])
            post_processor(resp)
        return resp
Exemplo n.º 4
0
    def send(self, cmdNames, params):
        self.sendLock.acquire()
        try:
            if not self.isConnected:
                raise ApiException.ConnectionError("Disconnected")

            # Send data
            ApiConnector.log.debug("IO OUT.    {0} : {1}".format(
                cmdNames, params))
            (cmdId, paramsBinList) = self.apiDef.serialize(cmdNames, params)
            paramsBin = struct.pack('!' + str(len(paramsBinList)) + 'B',
                                    *paramsBinList)
            ApiConnector.logDump(paramsBin,
                                 "RawIO OUT. Command ID: {0}".format(cmdId))
            packet = self.muxMsg.build_message(cmdId, paramsBin)
            self.acknowledgeBuf = None
            self.ackCmdId = -1
            try:
                self.socket.sendall(packet)
            except socket.error, way:
                # Socket error. Disconnect from device. Stop command processing
                reason = "IO output error [{0}] {1}".format(
                    way.args[0], way.args[1])
                self.disconnect(reason)
                raise ApiException.ConnectionError(reason)

            # Waiting acknowledge
            self.sendSemaphor.acquire()
            if not self.isConnected:  # Disconnect happened during waiting ack.
                raise ApiException.ConnectionError(self.disconnectReason)

            # Process acknowledge
            cmdId = self.apiDef.nameToId(self.apiDef.COMMAND, (cmdNames[0], ))
            if self.ackCmdId != cmdId:
                reason = "Unexpected acknowledge {0} for command {1} ({2})".format(
                    self.ackCmdId, cmdId, cmdNames)
                self.disconnect(reason)
                raise ApiException.ConnectionError(reason)

            # Parse acknowledge
            ackList = struct.unpack('!' + str(len(self.acknowledgeBuf)) + 'B',
                                    self.acknowledgeBuf)
            (resCmdName,
             resParams) = self.apiDef.deserialize(self.apiDef.COMMAND,
                                                  self.ackCmdId, ackList)
            ApiConnector.log.debug("IO INP.    {0} : {1}".format(
                resCmdName, resParams))

            if self.apiDef.RC in resParams and resParams[
                    self.apiDef.RC] != self._RC_OK:
                if resParams[self.apiDef.RC] == self._RC_TIMEOUT:
                    raise ApiException.CommandTimeoutError(resCmdName)
                try:
                    desc = '({0})\n{1}'.format(
                        self.apiDef.responseFieldValueToDesc(
                            resCmdName,
                            self.apiDef.RC,
                            resParams[self.apiDef.RC],
                        ),
                        self.apiDef.rcToDescription(
                            resParams[self.apiDef.RC],
                            resCmdName,
                        ),
                    )
                except:
                    desc = None
                raise ApiException.APIError(cmd=resCmdName,
                                            rc=resParams[self.apiDef.RC],
                                            desc=desc)

            self.ackCmdId = -1
            self.acknowledgeBuf = None