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))
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}
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
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