Exemplo n.º 1
0
class Reconnect(object):
    """
    A reconnect class
    """
    def __init__(self, **kwargs):
        """
        A constructor will init our wamp session and a runner.
        A runner is a callable that have to be processed when we lose the connection

        :param kwargs: keys: 'session' and 'runner'
        :return: void
        """

        if 'session' not in kwargs or 'runner' not in kwargs:
            raise Exception('session is not provided')

        self.__session = kwargs['session']
        self.__runner = kwargs['runner']

        self.logger = Logger()
        self.config = kwargs.get('config')

    def start(self):
        """
        Start the reconnection
        :return: void
        """
        try:

            self.logger.info(
                'TRYING TO CONNECT TO {}'.format(
                    self.config
                )
            )

            run = self.__runner(config=self.config)
            run.run(self.__session)

        except Exception as e:
            self.logger.error('RECONNECTING ERROR: {}'.format(e.message))
Exemplo n.º 2
0
class Reconnect(object):
    """
    A reconnect class
    """
    def __init__(self, **kwargs):
        """
        A constructor will init our wamp session and a runner.
        A runner is a callable that have to be processed when we lose the connection

        :param kwargs: keys: 'session' and 'runner'
        :return: void
        """

        if 'session' not in kwargs or 'runner' not in kwargs:
            raise Exception('session is not provided')

        self.__session = kwargs['session']
        self.__runner = kwargs['runner']

        self.logger = Logger()
        self.config = kwargs.get('config')

    def start(self):
        """
        Start the reconnection
        :return: void
        """
        try:

            self.logger.info('TRYING TO CONNECT TO {}'.format(self.config))

            run = self.__runner(config=self.config)
            run.run(self.__session)

        except Exception as e:
            self.logger.error('RECONNECTING ERROR: {}'.format(e.message))
Exemplo n.º 3
0
class AutobahnDefaultFactory(service.Service):
    """
    This class is a convenience tool mainly for development and quick hosting
    of WAMP application components.

    It can host a WAMP application component in a WAMP-over-WebSocket client
    connecting to a WAMP router.
    """

    def __init__(self, **kwargs):
        """

        :param url: The WebSocket URL of the WAMP router to connect to (e.g. `ws://somehost.com:8090/somepath`)
        :type url: unicode
        :param realm: The WAMP realm to join the application session to.
        :type realm: unicode
        :param extra: Optional extra configuration to forward to the application component.
        :type extra: dict
        :param debug: Turn on low-level debugging.
        :type debug: bool
        :param debug_wamp: Turn on WAMP-level debugging.
        :type debug_wamp: bool
        :param debug_app: Turn on app-level debugging.
        :type debug_app: bool

        """

        self.logger = Logger()

        self.config = kwargs.get('config', None)

        if self.config is None:

            self.config = {}
            wamp = WAMP()

            self.logger.warning('Config is not provided failback to defaults')

            self.config.update({
                'protocol': 'wss',
                'hostname': 'localhost',
                'port': 8080, # integer
                'realm': 'realm1',
                'path': 'ws',
                'retry_interval': 2,  # in seconds
                'url': u'ws://localhost:8080/ws',
                'service_name': 'A Default WAMP Service name"'
            })

            self.config = wamp.to_object(self.config)

        self.url = kwargs.get('url', self.config.url)

        self.realm = u'{}'.format(kwargs.get('realm', self.config.realm))

        self.extra = kwargs.get('extra', dict())

        self.debug = kwargs.get('debug', False)

        self.debug_wamp = kwargs.get('debug_wamp', False)

        self.debug_app = kwargs.get('debug_app', False)

        self.belong_to = kwargs.get('belong_to', False)

        self.make = None

        self.protocol = kwargs.get('protocol', self.config.protocol)

        self.name = kwargs.get('name', self.config.service_name)

        self.port = kwargs.get('port', self.config.port)

        self.host = kwargs.get('host', self.config.hostname)

        self.path = kwargs.get('path', self.config.path)

    def run(self, make):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable
        """

        is_secure, host, port, resource, path, params = parse_url(self.url)

        # start logging to console
        if self.debug or self.debug_wamp or self.debug_app:
            pass
            # log.startLogging(sys.stdout)

        # factory for use ApplicationSession
        def create():
            """
            Will trying to create an ApplicationSession object
            :return: ApplicationSession
            """
            cfg = ComponentConfig(self.realm, self.extra)

            try:
                session = make(config=cfg)

            except Exception as e:

                # the app component could not be created .. fatal
                self.logger.critical('CREATE RUNNER EXCEPTION {}'.format(e.message))

            else:

                session.debug_app = self.debug_app
                return session

        # create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(
            create,
            url=self.url
        )

        if is_secure:
            endpoint_descriptor = "ssl:{0}:{1}".format(host, port)

        else:
            endpoint_descriptor = "tcp:{0}:{1}".format(host, port)

        try:
            self.logger.info('Trying to connect to: {}'.format(endpoint_descriptor))
            self.connect(endpoint_descriptor, transport_factory, make)

            return self

        except Exception as e:
            self.logger.error('CLIENT CONNECT ERROR: {}'.format(e.message))

    def connect(self, endpoint, transport, session):
        """
        Will make a connection to a WAMP router based on a Twisted endpoint
        :param endpoint:
        :param transport:
        :param session:
        :return:
        """
        try:

            # start the client from a Twisted endpoint

            client = clientFromString(reactor, endpoint)

            res = client.connect(transport)

            def connect_result(result):
                """
                A callback used as defer result
                :param result:
                :return:
                """
                return result

            def connect_error(result):
                """
                A callback used as defer if error occur
                :param result:
                :return:
                """
                self.logger.error('CONNECTION ERROR: {}'.format(result.getErrorMessage()))

                try:

                    reconnect = Reconnect(
                        session=session,
                        runner=AutobahnDefaultFactory,
                        config=self.config
                    )

                    reactor.callLater(
                        self.config.retry_interval,
                        reconnect.start,
                    )

                except Exception as e:
                    self.logger.error('RECONNECTING ERROR: {}'.format(e.message))

            res.addCallback(connect_result)
            res.addErrback(connect_error)

            return res

        except Exception as e:
            self.logger.error('CONNECTION GLOBAL ERRORS: {}'.format(e.message))

    def startService(self):
        """
        Start a WAMP service
        :return:
        """
        service.Service.startService(self)

    def stopService(self):
        """
        Stop a WAMP service
        :return:
        """
        service.Service.stopService(self)
Exemplo n.º 4
0
class DispathcherResultHelper(object):

    """
    A helper class that care about of the result and the response of the request
    """

    def __init__(self, factory):

        """
        Just settings
        :param factory:
        :return: void
        """

        self.__logger = Logger()
        self.factory = factory

    @staticmethod
    def deferred_response(response, sender):

        """
        Care about global defered response
        :param response: response from defer operation
        :param sender: TBA

        :return: void
        """
        if sender is not None:
            sender(response.to_json())

    def deferred_response_error(self, err):

        """
        fired if global defered response fail
        :param err:

        :return: False
        """
        self.__logger.error('Cannot send message to user: {}'.format(
            err
        ))

        return False

    def result_validation(self, sender=None, drop=None, section='TCP'):

        """
        A Result Helper more info TBA

        :param sender:
        :param drop:
        :param section:

        :return: mixin
        """

        if IValidator.providedBy(self.factory):

            self.__logger.warning('{} Message is invalid: {}'.format(section, self.factory.message))

            if drop is not None:
                drop()

            else:
                return 'message is invalid'

        else:

            if self.factory:

                self.__logger.info('{} Response: {}'.format(section, self.factory))

                if IJSONResource.providedBy(self.factory):

                    if sender is not None:
                        sender(self.factory.to_json())

                    else:
                        return self.factory.to_json()

                elif isinstance(self.factory, Deferred):

                    self.factory.addCallback(self.deferred_response, sender)
                    self.factory.addErrback(self.deferred_response_error)

            else:

                self.__logger.warning('{}: This message was not be dispatched'.format(section))
                drop()
Exemplo n.º 5
0
class AutobahnDefaultFactory(service.Service):
    """
    This class is a convenience tool mainly for development and quick hosting
    of WAMP application components.

    It can host a WAMP application component in a WAMP-over-WebSocket client
    connecting to a WAMP router.
    """
    def __init__(self, **kwargs):
        """

        :param url: The WebSocket URL of the WAMP router to connect to (e.g. `ws://somehost.com:8090/somepath`)
        :type url: unicode
        :param realm: The WAMP realm to join the application session to.
        :type realm: unicode
        :param extra: Optional extra configuration to forward to the application component.
        :type extra: dict
        :param debug: Turn on low-level debugging.
        :type debug: bool
        :param debug_wamp: Turn on WAMP-level debugging.
        :type debug_wamp: bool
        :param debug_app: Turn on app-level debugging.
        :type debug_app: bool

        """

        self.logger = Logger()

        self.config = kwargs.get('config', None)

        if self.config is None:

            self.config = {}
            wamp = WAMP()

            self.logger.warning('Config is not provided failback to defaults')

            self.config.update({
                'protocol': 'wss',
                'hostname': 'localhost',
                'port': 8080,  # integer
                'realm': 'realm1',
                'path': 'ws',
                'retry_interval': 2,  # in seconds
                'url': u'ws://localhost:8080/ws',
                'service_name': 'A Default WAMP Service name"'
            })

            self.config = wamp.to_object(self.config)

        self.url = kwargs.get('url', self.config.url)

        self.realm = u'{}'.format(kwargs.get('realm', self.config.realm))

        self.extra = kwargs.get('extra', dict())

        self.debug = kwargs.get('debug', False)

        self.debug_wamp = kwargs.get('debug_wamp', False)

        self.debug_app = kwargs.get('debug_app', False)

        self.belong_to = kwargs.get('belong_to', False)

        self.make = None

        self.protocol = kwargs.get('protocol', self.config.protocol)

        self.name = kwargs.get('name', self.config.service_name)

        self.port = kwargs.get('port', self.config.port)

        self.host = kwargs.get('host', self.config.hostname)

        self.path = kwargs.get('path', self.config.path)

    def run(self, make):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable
        """

        is_secure, host, port, resource, path, params = parse_url(self.url)

        # start logging to console
        if self.debug or self.debug_wamp or self.debug_app:
            pass
            # log.startLogging(sys.stdout)

        # factory for use ApplicationSession
        def create():
            """
            Will trying to create an ApplicationSession object
            :return: ApplicationSession
            """
            cfg = ComponentConfig(self.realm, self.extra)

            try:
                session = make(config=cfg)

            except Exception as e:

                # the app component could not be created .. fatal
                self.logger.critical('CREATE RUNNER EXCEPTION {}'.format(
                    e.message))

            else:

                session.debug_app = self.debug_app
                return session

        # create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(create, url=self.url)

        if is_secure:
            endpoint_descriptor = "ssl:{0}:{1}".format(host, port)

        else:
            endpoint_descriptor = "tcp:{0}:{1}".format(host, port)

        try:
            self.logger.info(
                'Trying to connect to: {}'.format(endpoint_descriptor))
            self.connect(endpoint_descriptor, transport_factory, make)

            return self

        except Exception as e:
            self.logger.error('CLIENT CONNECT ERROR: {}'.format(e.message))

    def connect(self, endpoint, transport, session):
        """
        Will make a connection to a WAMP router based on a Twisted endpoint
        :param endpoint:
        :param transport:
        :param session:
        :return:
        """
        try:

            # start the client from a Twisted endpoint

            client = clientFromString(reactor, endpoint)

            res = client.connect(transport)

            def connect_result(result):
                """
                A callback used as defer result
                :param result:
                :return:
                """
                return result

            def connect_error(result):
                """
                A callback used as defer if error occur
                :param result:
                :return:
                """
                self.logger.error('CONNECTION ERROR: {}'.format(
                    result.getErrorMessage()))

                try:

                    reconnect = Reconnect(session=session,
                                          runner=AutobahnDefaultFactory,
                                          config=self.config)

                    reactor.callLater(
                        self.config.retry_interval,
                        reconnect.start,
                    )

                except Exception as e:
                    self.logger.error('RECONNECTING ERROR: {}'.format(
                        e.message))

            res.addCallback(connect_result)
            res.addErrback(connect_error)

            return res

        except Exception as e:
            self.logger.error('CONNECTION GLOBAL ERRORS: {}'.format(e.message))

    def startService(self):
        """
        Start a WAMP service
        :return:
        """
        service.Service.startService(self)

    def stopService(self):
        """
        Stop a WAMP service
        :return:
        """
        service.Service.stopService(self)
Exemplo n.º 6
0
class DispathcherResultHelper(object):
    """
    A helper class that care about of the result and the response of the request
    """
    def __init__(self, factory):
        """
        Just settings
        :param factory:
        :return: void
        """

        self.__logger = Logger()
        self.factory = factory

    @staticmethod
    def deferred_response(response, sender):
        """
        Care about global defered response
        :param response: response from defer operation
        :param sender: TBA

        :return: void
        """
        if sender is not None:
            sender(response.to_json())

    def deferred_response_error(self, err):
        """
        fired if global defered response fail
        :param err:

        :return: False
        """
        self.__logger.error('Cannot send message to user: {}'.format(err))

        return False

    def result_validation(self, sender=None, drop=None, section='TCP'):
        """
        A Result Helper more info TBA

        :param sender:
        :param drop:
        :param section:

        :return: mixin
        """

        if IValidator.providedBy(self.factory):

            self.__logger.warning('{} Message is invalid: {}'.format(
                section, self.factory.message))

            if drop is not None:
                drop()

            else:
                return 'message is invalid'

        else:

            if self.factory:

                self.__logger.info('{} Response: {}'.format(
                    section, self.factory))

                if IJSONResource.providedBy(self.factory):

                    if sender is not None:
                        sender(self.factory.to_json())

                    else:
                        return self.factory.to_json()

                elif isinstance(self.factory, Deferred):

                    self.factory.addCallback(self.deferred_response, sender)
                    self.factory.addErrback(self.deferred_response_error)

            else:

                self.__logger.warning(
                    '{}: This message was not be dispatched'.format(section))
                drop()