Ejemplo n.º 1
0
    def connect(self, params={}):
        '''
        \brief Connect to device
        
        \param params Dictionary of connection parameters:
            - 'host' - IP address of Mux (default: '127.0.0.1')
            - 'port' - port of Mux (default: 9900)
            - 'isSendHello' - send Hello message after connection (default True)
        '''

        host = self.DEFAULT_PARAM_HOST
        port = self.DEFAULT_PARAM_PORT
        isSendHello = True
        if self.PARAM_HOST in params and params[self.PARAM_HOST]:
            host = params[self.PARAM_HOST]
        if self.PARAM_PORT in params and params[self.PARAM_PORT]:
            port = int(params[self.PARAM_PORT])
        if self.PARAM_ISSENDHELLO in params:
            isSendHello = params[self.PARAM_ISSENDHELLO]

        if self.inputThread:  # Wait finish disconnect process
            try:
                self.inputThread.join(1.0)
                if self.inputThread.isAlive():
                    raise ApiException.ConnectionError("Already connected")
            except RuntimeError:
                pass  # Ignore join error
            self.inputThread = None

        try:
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.socket.connect((host, port))
            self.socket.setblocking(1)
        except socket.error as ex:
            raise ApiException.ConnectionError(str(ex))

        self.sendSemaphor.acquire(False)  # Clear semaphore
        # Start thread for processing input stream
        self.inputThread = threading.Thread(target=self.inputProcess)
        self.inputThread.name = "IpMgrConnectorMuxInternal"
        self.inputThread.start()
        ApiConnector.ApiConnector.connect(self)
        if isSendHello:
            self.sendHelloCmd()
Ejemplo n.º 2
0
 def connect(self):
     try:
         self.notif_socket = socket.create_connection(
             (self.notif_host, self.notif_port))
         if self.use_ssl:
             self.notif_socket = ssl.wrap_socket(self.notif_socket)
         log.info("Connected to notification channel")
         # send authentication
         log.debug("Sending notif authentication: %s" % self.notif_token)
         self.notif_socket.send(self._build_auth())
         self.connected = True
     except socket.error as e:
         log.error('Exception reading from notification channel: ' + str(e))
         raise ApiException.ConnectionError(str(e))
Ejemplo n.º 3
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))
Ejemplo n.º 4
0
    def _ebHandler_dataToMesh(self, sender, signal, data):

        try:
            self.connector.dn_sendData(
                macAddress=data['mac'],
                priority=data['priority'],
                srcPort=data['srcPort'],
                dstPort=data['dstPort'],
                options=data['options'],
                data=data['data'],
            )
        except TypeError as err:
            log.error(str(err))
            raise ApiException.ConnectionError(str(err))
Ejemplo n.º 5
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}
Ejemplo n.º 6
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
Ejemplo n.º 7
0
 def _execCommandAndDispatch(self,func,params):
     
     try:
         res = func(*params)
     except TypeError as err:
         log.error(str(err))
         raise ApiException.ConnectionError(str(err))
     
     # dispatch
     dispatcher.send(
         signal      =   'managerCmd_{0}'.format(self.netname),
         data        =   res,
     )
     
     return res
Ejemplo n.º 8
0
    def connect(self, resource):
        # set up the connection parameters
        self.connect_params = copy.copy(self.DEFAULT_CONNECT_PARAMS)
        self.connect_params.update(resource)
        # TODO: allow HTTPS
        try:
            self.manager = self._init_xmlrpc(
                self.connect_params['host'], int(self.connect_params['port']),
                bool(self.connect_params['use_ssl']))

            self.login(self.connect_params['user'],
                       self.connect_params['password'])

        except xmlrpclib.Fault as ex:
            log.error(str(ex))
            raise ApiException.ConnectionError(str(ex))
        log.info('Connected to %s' % self.connect_params['host'])
        ApiConnector.connect(self)
Ejemplo n.º 9
0
    def start(self):
        '''
        \brief Start the subscriber _thread.
        '''

        if self._thread:  # Wait finish disconnect process
            try:
                self._thread.join(1.0)
                if self._thread.isAlive():
                    raise ApiException.ConnectionError("Already connected")
            except RuntimeError:
                pass  # Ignore join error
            self._thread = None

        # Clear _callback table
        for i in self._callback:
            self._callback[i][1] = None
            self._callback[i][2] = True
        self._mask = self._unrlblMask = 0
        self._thread = threading.Thread(target=self._process)
        self._thread.name = "IpMgrSubscribe"
        self._thread.start()
        self._isStarted = True
Ejemplo n.º 10
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
Ejemplo n.º 11
0
    def __init__(self, connector, connectParams):
        assert isinstance(connector, ApiConnector.ApiConnector)
        assert isinstance(connectParams, (str, tuple))

        # record parameters
        self.connector = connector
        self.connectParams = connectParams

        # log
        log.info("creating instance")

        # variables
        self.netname = FormatUtils.formatConnectionParams(self.connectParams)
        self.statsLock = threading.Lock()
        self._clearStats()

        # start snapshot thread this manager
        self.snapShotThread = SnapShot.SnapShot(connector, connectParams)

        # subscribe to flows
        try:
            self.subscriber = IpMgrSubscribe.IpMgrSubscribe(self.connector)
            self.subscriber.start()

            self.subscriber.subscribe(
                notifTypes=[
                    IpMgrSubscribe.IpMgrSubscribe.NOTIFDATA,
                ],
                fun=self._subs_notifData,
                isRlbl=False,
            )
            self.subscriber.subscribe(
                notifTypes=[
                    IpMgrSubscribe.IpMgrSubscribe.NOTIFEVENT,
                ],
                fun=self._subs_notifEvent,
                isRlbl=True,
            )
            self.subscriber.subscribe(
                notifTypes=[
                    IpMgrSubscribe.IpMgrSubscribe.NOTIFHEALTHREPORT,
                ],
                fun=self._subs_notifHealthReport,
                isRlbl=True,
            )
            self.subscriber.subscribe(
                notifTypes=[
                    IpMgrSubscribe.IpMgrSubscribe.ERROR,
                    IpMgrSubscribe.IpMgrSubscribe.FINISH,
                ],
                fun=self._subs_errorORfinish,
                isRlbl=True,
            )
        except TypeError as err:
            log.error(str(err))
            raise ApiException.ConnectionError(str(err))

        self.subscriber._thread.name = '{0}_IpMgrSubscribe'.format(
            self.netname)

        # initialize parent class
        EventBusClient.EventBusClient.__init__(
            self,
            'dataToMesh_{0}'.format(self.netname),
            self._ebHandler_dataToMesh,
        )

        # give this thread a name
        self.name = '{0}_GatewayListener'.format(self.netname)