Exemplo n.º 1
0
    def __init__(self, **kwargs):

        """
        Default factory, used for TCP servers, implements IDefaultFactory
        :param kwargs:

        """

        self.__logger = Logger()

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

        if self.config is None:

            self.__logger.warning('Config for IDefaultFactory is not provided, failback to defaults...')

            tcp = TCP()

            self.config = {
                'port': 8484,
                'tcp_back_log': 50,
                'service_name': 'Default TCP Server'
            }

            self.config = tcp.to_object(self.config)

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

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

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

        self.belong_to = kwargs.get('belong_to', False)
Exemplo n.º 2
0
    def __init__(self, **kwargs):

        """

        Default factory, used for TCP servers, implements IDefaultFactory
        :param kwargs:

        """
        self.__logger = Logger()

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

        if self.config is None:

            web = WEB()

            self.__logger.warning('Config for IDefaultWebFactory is not provided, failback to defaults...')

            self.config = {
                'port': 8000,
                'www_root': '',
                'service_name': 'Default WEB Server',
                'http_methods': ['GET']
            }

            self.config = web.to_object(self.config)

        self.name = kwargs.get('name', self.config.service_name)
        self.port = kwargs.get('port', self.config.port)
        self.methods = kwargs.get('http_methods', self.config.http_methods)
        self.belong_to = kwargs.get('belong_to', False)
Exemplo n.º 3
0
    def __init__(self, factory):
        """
        Just settings
        :param factory:
        :return: void
        """

        self.__logger = Logger()
        self.factory = factory
Exemplo n.º 4
0
class DefaultWSFactory(object):
    """
    A class that represent a default WS Factory
    """
    def __init__(self, **kwargs):
        """
        Default factory, used for TCP servers, implements IDefaultFactory
        :param kwargs:

        :return:
        """
        self.__logger = Logger()

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

        if self.config is None:

            ws = WS()

            self.__logger.warning(
                'Config for IDefaultFactory is not provided, failback to defaults...'
            )

            self.config = {
                'url': 'ws://localhost:8585',
                'port': 8585,
                'hostname': 'localhost',
                'protocol': 'ws'
            }

            self.config = ws.to_object(self.config)

        self.ws_protocol = self.config.protocol

        self.name = kwargs.get('name', 'DefaultWSFactory')

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

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

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

        self.ws_server_factory = DefaultWSFactoryRunner

        if self.ws_protocol == 'wss':

            key = self.config.keys.key
            crt = self.config.keys.crt

            if key is None or crt is None:
                raise AttributeError(
                    'WS over SSL required attribute a key and a crt')

            self.crt_keys = dict(key=key, crt=crt)

        self.ws_msg_protocol = DefaultWSProtocol
Exemplo n.º 5
0
class DefaultWSFactory(object):

    """
    A class that represent a default WS Factory
    """

    def __init__(self, **kwargs):

        """
        Default factory, used for TCP servers, implements IDefaultFactory
        :param kwargs:

        :return:
        """
        self.__logger = Logger()

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

        if self.config is None:

            ws = WS()

            self.__logger.warning('Config for IDefaultFactory is not provided, failback to defaults...')

            self.config = {
                'url': 'ws://localhost:8585',
                'port': 8585,
                'hostname': 'localhost',
                'protocol': 'ws'
            }

            self.config = ws.to_object(self.config)

        self.ws_protocol = self.config.protocol

        self.name = kwargs.get('name', 'DefaultWSFactory')

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

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

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

        self.ws_server_factory = DefaultWSFactoryRunner

        if self.ws_protocol == 'wss':

            key = self.config.keys.key
            crt = self.config.keys.crt

            if key is None or crt is None:
                raise AttributeError('WS over SSL required attribute a key and a crt')

            self.crt_keys = dict(key=key, crt=crt)

        self.ws_msg_protocol = DefaultWSProtocol
Exemplo n.º 6
0
    def __init__(self, validate_msg):
        """
        Accept message that have to be validated

        :param validate_msg: currently we supporting only a json validators
        """
        super(Validator, self).__init__(validate_msg)

        self.__msg = Message(validate_msg)
        self.__logger = Logger()
Exemplo n.º 7
0
    def __init__(self, comp):
        """
        A RootAPI constructor will init an logger and will initialize a public attribute
        - self.comp which representing an input object as DynamicProtocol

        :param comp:
        :type comp: DynamicProtocol

        :return: void
        """
        self.comp = comp
        self.__logger = Logger()
Exemplo n.º 8
0
def on_connect(self):
    """
    A function that is called when we got connected to a WAMP router.
    This function is attached to our WampDefaultComponent only if protocol is WSS
    :param self:
    :return: void
    """
    cfg = Config().get_wamp()
    log = Logger()

    log.info('Connecting to router...')

    self.join(self.config.realm, [u'wampcra'], cfg.user)
Exemplo n.º 9
0
def on_connect(self):
    """
    A function that is called when we got connected to a WAMP router.
    This function is attached to our WampDefaultComponent only if protocol is WSS
    :param self:
    :return: void
    """
    cfg = Config().get_wamp()
    log = Logger()

    log.info('Connecting to router...')

    self.join(self.config.realm, [u'wampcra'], cfg.user)
Exemplo n.º 10
0
    def __init__(self, comp):
        """
        A NonRootAPi constructor will init a logger and a comp property for an object
        that have to be compare with the existing registered protocols

        :param comp:
        :type comp: an input object as DynamicProtocol

        :return: void
        """

        self.comp = comp
        self.__logger = Logger()
Exemplo n.º 11
0
    def __init__(self, validator):
        """
        The constructor will init a logger and will init a public attribute - self.validator
        that is a validated requests, here we have to determinate which protocol and API have
        to process this request

        :param validator:
        :type validator: IValidator

        :return: void
        """

        self.validator = validator
        self.__logger = Logger()
Exemplo n.º 12
0
    def __init__(self, factory):
        """

        :param factory:
        :return: void
        """

        base = BaseWebMethods()
        self.__logger = Logger()

        for meth in factory.config.http_methods:

            try:

                name = 'render_{}'.format(meth)
                web_resource = getattr(base, name)

            except AttributeError as e:

                allow_methods = [
                    render.replace('render_', '') for render in base.__class__.__dict__ if render.startswith('render')
                ]

                print('[ !!!!! Warning: ] Ivalid web methods was provided, available are: {}, error: {}'.format(
                    ', '.join(allow_methods), e
                ))

            else:
                setattr(DefaultWebResource, name, web_resource)

        Resource.__init__(self)
Exemplo n.º 13
0
    def __init__(self, factories_source, file_loader=None, out_filter=None):
        """
        The constructor will init the storage and all objects that are matched from our filters

        :param file_loader:
        :param factories_source:

        :return: void
        """

        super(RegisterFactories, self).__init__()

        self.__gsm = getGlobalSiteManager()

        self.file_loader = file_loader or FileFactoryLoader()

        if not out_filter:
            out_filter = []

        self.default_filter = list(
            set(out_filter + [IUserStorage, IUserFactory]))

        self.__objects = self.file_loader.load(factories_source,
                                               self.default_filter)

        self.__storage = createObject('storageregister')
        self.__logger = Logger()
Exemplo n.º 14
0
    def __init__(self, factory):
        """

        :param factory:
        :type IDefaultFactory

        """

        self.factory = factory

        self.__logger = Logger()

        self.listener = None

        if self.factory.ws_protocol == 'wss':

            self.__ssl_context = ssl.DefaultOpenSSLContextFactory(
                self.factory.crt_keys.get('key'),
                self.factory.crt_keys.get('crt')
            )

        self.setName(self.factory.name)

        if self.factory.belong_to is False:

            self.__application = service.Application(self.factory.name, uid=1000, gid=1000)
            self.service_collection = service.IServiceCollection(self.__application)

        else:

            self.service_collection = self.factory.belong_to
Exemplo n.º 15
0
class Validator(BaseValidator):

    """
    Our main validator will trying to resolve the type of incoming request
    """

    def __init__(self, validate_msg):
        """
        Accept message that have to be validated

        :param validate_msg: currently we supporting only a json validators
        """
        super(Validator, self).__init__(validate_msg)

        self.__msg = Message(validate_msg)
        self.__logger = Logger()

    def validate(self):

        """
        Will walk through all subscribers from IValidator type
        the first one will be returned as valid type. In this way we can supporting a lot of types
        on the same port/service

        :return: matched IValidator subscriber
        """

        for sub in subscribers([self.__msg], IValidator):

            msg = sub.validate()

            self.is_valid = msg.is_valid
            self.message_type = msg.message_type
            self.message = msg.message

            # we want only one correct type of our message so
            # only one validator will response with True

            if self.is_valid is True:

                self.__logger.debug('Matched type is: {}'.format(self.message_type))

                return self

        self.__logger.warning('Main Validator - There are no subscribers from type IValidator')

        return False
Exemplo n.º 16
0
    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')
Exemplo n.º 17
0
class Validator(BaseValidator):
    """
    Our main validator will trying to resolve the type of incoming request
    """
    def __init__(self, validate_msg):
        """
        Accept message that have to be validated

        :param validate_msg: currently we supporting only a json validators
        """
        super(Validator, self).__init__(validate_msg)

        self.__msg = Message(validate_msg)
        self.__logger = Logger()

    def validate(self):
        """
        Will walk through all subscribers from IValidator type
        the first one will be returned as valid type. In this way we can supporting a lot of types
        on the same port/service

        :return: matched IValidator subscriber
        """

        for sub in subscribers([self.__msg], IValidator):

            msg = sub.validate()

            self.is_valid = msg.is_valid
            self.message_type = msg.message_type
            self.message = msg.message

            # we want only one correct type of our message so
            # only one validator will response with True

            if self.is_valid is True:

                self.__logger.debug('Matched type is: {}'.format(
                    self.message_type))

                return self

        self.__logger.warning(
            'Main Validator - There are no subscribers from type IValidator')

        return False
Exemplo n.º 18
0
    def __init__(self, validate_msg):
        """
        :param validate_msg: IMessage
        """

        super(JSONValidator, self).__init__(validate_msg)

        self.__logger = Logger()
Exemplo n.º 19
0
    def __init__(self, factory):

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

        self.__logger = Logger()
        self.factory = factory
Exemplo n.º 20
0
    def __init__(self, validate_msg):
        """
        Accept message that have to be validated

        :param validate_msg: currently we supporting only a json validators
        """
        super(Validator, self).__init__(validate_msg)

        self.__msg = Message(validate_msg)
        self.__logger = Logger()
Exemplo n.º 21
0
def on_challenge(self, challenge):

    """
    A function that is called when we got onChallenge event aka authentication to a WAMP router.
    This function is attached to our WampDefaultComponent only if protocol is WSS

    :param self:
    :param challenge:

    :return: digital signature decode in ascii
    """

    log = Logger()
    log.info('On Challenge...')

    if challenge.method == u"wampcra":

        cfg = Config().get_wamp()

        password = {
            u'%s' % cfg.user: u'%s' % cfg.password
        }

        if u'salt' in challenge.extra:

            key = auth.derive_key(
                password[cfg.user].encode('utf8'),
                challenge.extra['salt'].encode('utf8'),
                challenge.extra.get('iterations', None),
                challenge.extra.get('keylen', None)
            )

        else:

            key = password[cfg.user].encode('utf8')
        
        signature = auth.compute_wcs(key, challenge.extra['challenge'].encode('utf8'))

        return signature.decode('ascii')

    else:

        raise Exception("don't know how to compute challenge for authmethod {}".format(challenge.method))
Exemplo n.º 22
0
class Time(BaseRootAPI):
    def __init__(self, factory):

        super(Time, self).__init__(factory)

        self.factory = factory
        self.logger = Logger()

    def process_factory(self):

        if self.factory.time == 'get':
            self.factory.time = str(datetime.now())

        else:
            self.factory.time = 'service unavailable'

        self.logger.debug('IN TIME API: {}'.format(self.factory.to_dict()))

        return self.factory
Exemplo n.º 23
0
class RootAPI(object):
    """
    An API that implements an IJSONResourceRootAPI
    """
    def __init__(self, comp):

        """
        A RootAPI constructor will init an logger and will initialize a public attribute
        - self.comp which representing an input object as DynamicProtocol

        :param comp:
        :type comp: DynamicProtocol

        :return: void
        """
        self.comp = comp
        self.__logger = Logger()

    def check(self):

        """
        Will trying to get a RootAPI and if match one will fired a process_factory
        of an implementation API

        :return: False if not success otherwise the response from process_factory
        """
        for api in subscribers([self.comp], IJSONResourceRootAPI):

            if api.__class__.__name__.lower() in self.comp.to_dict().keys():

                self.__logger.debug('Candidate API {} for {}'.format(
                    api.__class__.__name__,
                    self.comp.__class__.__name__
                ))

                self.__logger.info('Successful apply API {} for {}'.format(
                    api.__class__.__name__,
                    self.comp.__class__.__name__
                ))

                return api.process_factory()

        return False
Exemplo n.º 24
0
class Clock(BaseRootAPIWampMixin):

    def __init__(self, factory=None):

        super(Clock, self).__init__(factory)

        self.logger = Logger()

    @staticmethod
    def print_result_callback(res, factory):

        factory.clock = res
        return factory

    @staticmethod
    def print_result_callback_error(err):
        print err
        return False

    def process_factory(self):

        self.logger.debug(self.factory.to_dict())

        # we trying to get a wamo session
        session = self.get_session()

        # if exist we will get the time from a rpc with a name 'get_time'
        # registered as wamp component inside components/wamp/rpc
        if session:

            result = session.call('get_time')

            result.addCallback(self.print_result_callback, self.factory)
            result.addErrback(self.print_result_callback_error)

            return result

        else:

            # if does not exist
            self.factory.clock = str(datetime.now())
            return self.factory
Exemplo n.º 25
0
class Time(BaseRootAPI):

    def __init__(self, factory):

        super(Time, self).__init__(factory)

        self.factory = factory
        self.logger = Logger()

    def process_factory(self):
        
        if self.factory.time == 'get':
            self.factory.time = str(datetime.now())

        else:
            self.factory.time = 'service unavailable'

        self.logger.debug('IN TIME API: {}'.format(self.factory.to_dict()))

        return self.factory
Exemplo n.º 26
0
class Clock(BaseRootAPIWampMixin):
    def __init__(self, factory=None):

        super(Clock, self).__init__(factory)

        self.logger = Logger()

    @staticmethod
    def print_result_callback(res, factory):

        factory.clock = res
        return factory

    @staticmethod
    def print_result_callback_error(err):
        print err
        return False

    def process_factory(self):

        self.logger.debug(self.factory.to_dict())

        # we trying to get a wamo session
        session = self.get_session()

        # if exist we will get the time from a rpc with a name 'get_time'
        # registered as wamp component inside components/wamp/rpc
        if session:

            result = session.call('get_time')

            result.addCallback(self.print_result_callback, self.factory)
            result.addErrback(self.print_result_callback_error)

            return result

        else:

            # if does not exist
            self.factory.clock = str(datetime.now())
            return self.factory
Exemplo n.º 27
0
def on_challenge(self, challenge):
    """
    A function that is called when we got onChallenge event aka authentication to a WAMP router.
    This function is attached to our WampDefaultComponent only if protocol is WSS

    :param self:
    :param challenge:

    :return: digital signature decode in ascii
    """

    log = Logger()
    log.info('On Challenge...')

    if challenge.method == u"wampcra":

        cfg = Config().get_wamp()

        password = {u'%s' % cfg.user: u'%s' % cfg.password}

        if u'salt' in challenge.extra:

            key = auth.derive_key(password[cfg.user].encode('utf8'),
                                  challenge.extra['salt'].encode('utf8'),
                                  challenge.extra.get('iterations', None),
                                  challenge.extra.get('keylen', None))

        else:

            key = password[cfg.user].encode('utf8')

        signature = auth.compute_wcs(
            key, challenge.extra['challenge'].encode('utf8'))

        return signature.decode('ascii')

    else:

        raise Exception(
            "don't know how to compute challenge for authmethod {}".format(
                challenge.method))
Exemplo n.º 28
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.º 29
0
    def __init__(self, **kwargs):
        """
        The constructor will init self.cfg self.__gsm and if the protocol is wss,
        will attach on_connect and on_challenge to this object as methods
        :param kwargs: we looking for key 'config'
        :return: void
        """
        config = kwargs.get('config')

        super(WampDefaultComponent, self).__init__(config)

        self.__logger = Logger()
        self.cfg = Config().get_wamp()

        self.__gsm = getGlobalSiteManager()

        if self.cfg.protocol == 'wss':

            self.__logger.info('WAMP is secure, switch to wss...')

            WampDefaultComponent.onConnect = on_connect
            WampDefaultComponent.onChallenge = on_challenge
Exemplo n.º 30
0
    def __init__(self, comp):

        """
        A RootAPI constructor will init an logger and will initialize a public attribute
        - self.comp which representing an input object as DynamicProtocol

        :param comp:
        :type comp: DynamicProtocol

        :return: void
        """
        self.comp = comp
        self.__logger = Logger()
Exemplo n.º 31
0
class NonRootAPI(object):
    """
    An API that will check for a Non Root API's
    """
    def __init__(self, comp):
        """
        A NonRootAPi constructor will init a logger and a comp property for an object
        that have to be compare with the existing registered protocols

        :param comp:
        :type comp: an input object as DynamicProtocol

        :return: void
        """

        self.comp = comp
        self.__logger = Logger()

    def check(self):
        """
        Will trying to match the candidate Non Root API
        check IJSONResourceAPI for more info

        :return: False if not success otherwise the response from matched API.method()
        """

        for api in subscribers([self.comp], IJSONResourceAPI):

            if api.__class__.__name__.lower() in self.comp.to_dict().keys():

                self.__logger.debug('Candidate API {} for {}'.format(
                    api.__class__.__name__, self.comp.__class__.__name__))

                candidate_api_name = self.comp.to_dict().get(
                    api.__class__.__name__.lower())

                try:
                    # execute the candidate API method
                    # and return the result
                    candidate_api_result = getattr(api, candidate_api_name)()

                except AttributeError as e:

                    msg = 'Candidate API {} for {} does not implement method {} error: {}'

                    self.__logger.warning(
                        msg.format(api.__class__.__name__,
                                   self.comp.__class__.__name__,
                                   candidate_api_name, e.message))

                else:

                    self.__logger.info('Successful apply API {} for {}'.format(
                        api.__class__.__name__, self.comp.__class__.__name__))

                    return candidate_api_result

        return False
Exemplo n.º 32
0
    def __init__(self, comp):

        """
        A NonRootAPi constructor will init a logger and a comp property for an object
        that have to be compare with the existing registered protocols

        :param comp:
        :type comp: an input object as DynamicProtocol

        :return: void
        """

        self.comp = comp
        self.__logger = Logger()
Exemplo n.º 33
0
class RootAPI(object):
    """
    An API that implements an IJSONResourceRootAPI
    """
    def __init__(self, comp):
        """
        A RootAPI constructor will init an logger and will initialize a public attribute
        - self.comp which representing an input object as DynamicProtocol

        :param comp:
        :type comp: DynamicProtocol

        :return: void
        """
        self.comp = comp
        self.__logger = Logger()

    def check(self):
        """
        Will trying to get a RootAPI and if match one will fired a process_factory
        of an implementation API

        :return: False if not success otherwise the response from process_factory
        """
        for api in subscribers([self.comp], IJSONResourceRootAPI):

            if api.__class__.__name__.lower() in self.comp.to_dict().keys():

                self.__logger.debug('Candidate API {} for {}'.format(
                    api.__class__.__name__, self.comp.__class__.__name__))

                self.__logger.info('Successful apply API {} for {}'.format(
                    api.__class__.__name__, self.comp.__class__.__name__))

                return api.process_factory()

        return False
Exemplo n.º 34
0
    def __init__(self, validator):

        """
        The constructor will init a logger and will init a public attribute - self.validator
        that is a validated requests, here we have to determinate which protocol and API have
        to process this request

        :param validator:
        :type validator: IValidator

        :return: void
        """

        self.validator = validator
        self.__logger = Logger()
Exemplo n.º 35
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.º 36
0
    def subscriber_dispatcher(self, sub_data):
        """
        Callback function for our global subscriber
        will pass sub_data to GlobalSubscribeMessage and then will trying to
        get wamp component which implements IUserGlobalSubscriber and adapts
        IGlobalSubscribeMessage

        :param sub_data:
        """

        log = Logger()

        try:

            result = IDispatcher(Validator(sub_data)).dispatch()

        # NETODO what exception can happen here?
        except Exception as e:

            import traceback
            print traceback.format_exc()

            log.warning('subscriber_dispatcher exception: {}'.format(
                e.message))

        else:

            if IValidator.providedBy(result):
                log.warning('WAMP Message is invalid: {}'.format(
                    result.message))

            if result is not False and IJSONResource.providedBy(result):

                fac = None

                for sub in subscribers([result], IUserGlobalSubscriber):

                    sub.subscribe(self)
                    fac = True

                    break

                if not fac:
                    log.warning(
                        'There are no user definition for IUserGlobalSubscriber, message was skipped'
                    )
Exemplo n.º 37
0
    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')
Exemplo n.º 38
0
    def subscriber_dispatcher(self, sub_data):

        """
        Callback function for our global subscriber
        will pass sub_data to GlobalSubscribeMessage and then will trying to
        get wamp component which implements IUserGlobalSubscriber and adapts
        IGlobalSubscribeMessage

        :param sub_data:
        """

        log = Logger()

        try:

            result = IDispatcher(Validator(sub_data)).dispatch()

        # NETODO what exception can happen here?
        except Exception as e:

            import traceback
            print traceback.format_exc()

            log.warning('subscriber_dispatcher exception: {}'.format(
                e.message
            ))

        else:

            if IValidator.providedBy(result):
                log.warning('WAMP Message is invalid: {}'.format(result.message))

            if result is not False and IJSONResource.providedBy(result):

                fac = None

                for sub in subscribers([result], IUserGlobalSubscriber):

                    sub.subscribe(self)
                    fac = True

                    break

                if not fac:
                    log.warning('There are no user definition for IUserGlobalSubscriber, message was skipped')
Exemplo n.º 39
0
    def __init__(self, **kwargs):
        """
        The constructor will init self.cfg self.__gsm and if the protocol is wss,
        will attach on_connect and on_challenge to this object as methods
        :param kwargs: we looking for key 'config'
        :return: void
        """
        config = kwargs.get('config')

        super(WampDefaultComponent, self).__init__(config)

        self.__logger = Logger()
        self.cfg = Config().get_wamp()

        self.__gsm = getGlobalSiteManager()

        if self.cfg.protocol == 'wss':

            self.__logger.info('WAMP is secure, switch to wss...')

            WampDefaultComponent.onConnect = on_connect
            WampDefaultComponent.onChallenge = on_challenge
Exemplo n.º 40
0
class DefaultLineReceiver(LineReceiver):
    """
    A default implementation of Twisted LineReceiver protocol
    """
    def __init__(self):
        """
        A constructor will init the logger only
        :return: void
        """
        self.__logger = Logger()

    def connectionMade(self):
        """
        A callback method that is fired when connection is made
        :return: void
        """
        self.__logger.info('Connections made')

    def connectionLost(self, reason='unexpected'):
        """
        A callback method that is fired when connection is lost
        :param reason:
        :return: void
        """
        self.__logger.info('Connection was closesd: {}'.format(reason))

    def lineReceived(self, line):
        """
        A callback method that is fired when live is received.
        Will validate, dispatch and choose the right API on the fly
        :param line: user input
        :type line: JSON
        :return: void
        """
        self.__logger.info('Received line: {}'.format(line))

        result = IDispatcher(Validator(line)).dispatch()
        result_helper = DispathcherResultHelper(result)

        result_helper.result_validation(
            self.sendLine,
            self.transport.loseConnection,
            'TCP'
        )
Exemplo n.º 41
0
class DefaultLineReceiver(LineReceiver):
    """
    A default implementation of Twisted LineReceiver protocol
    """
    def __init__(self):
        """
        A constructor will init the logger only
        :return: void
        """
        self.__logger = Logger()

    def connectionMade(self):
        """
        A callback method that is fired when connection is made
        :return: void
        """
        self.__logger.info('Connections made')

    def connectionLost(self, reason='unexpected'):
        """
        A callback method that is fired when connection is lost
        :param reason:
        :return: void
        """
        self.__logger.info('Connection was closesd: {}'.format(reason))

    def lineReceived(self, line):
        """
        A callback method that is fired when live is received.
        Will validate, dispatch and choose the right API on the fly
        :param line: user input
        :type line: JSON
        :return: void
        """
        self.__logger.info('Received line: {}'.format(line))

        result = IDispatcher(Validator(line)).dispatch()
        result_helper = DispathcherResultHelper(result)

        result_helper.result_validation(self.sendLine,
                                        self.transport.loseConnection, 'TCP')
Exemplo n.º 42
0
    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)
Exemplo n.º 43
0
    def __init__(self, factory=None):

        super(Clock, self).__init__(factory)

        self.logger = Logger()
Exemplo n.º 44
0
"""
A Default implementation of WS protocol
"""

from zope.interface import implementer
from autobahn.twisted.websocket import WebSocketServerProtocol

from NetCatKS.NetCAT.api.interfaces import IWSProtocol
from NetCatKS.Dispatcher import IDispatcher, DispathcherResultHelper
from NetCatKS.Validators import Validator
from NetCatKS.Logger import Logger

__author__ = 'dimd'

logger = Logger()


@implementer(IWSProtocol)
class DefaultWSProtocol(WebSocketServerProtocol):
    """
    A class that implements a Default WS Protocol
    """
    def onConnect(self, request):
        """
        A callback that fired when connect occur
        :param request:

        :return:
        """
        logger.info("Client connecting: {0}".format(request.peer))
Exemplo n.º 45
0
class Dispatcher(object):

    """
    Our Main dispatcher, Will trying to dispatch the request to API which provides functionality for it.
    The Dispatcher also adapts IValidator
    """

    adapts(IValidator)

    def __init__(self, validator):

        """
        The constructor will init a logger and will init a public attribute - self.validator
        that is a validated requests, here we have to determinate which protocol and API have
        to process this request

        :param validator:
        :type validator: IValidator

        :return: void
        """

        self.validator = validator
        self.__logger = Logger()

    def __api_processor(self, valid_dispatch, valid_response, isubscriber):

        """

        Will loop through a valid response objects and will compare it to a registered
        protocol subscribers

        :param valid_dispatch:
        :param valid_response:
        :param isubscriber:

        :return: The chosen API or False
        """
        for sub in subscribers([valid_response], isubscriber):

            self.__logger.debug('Matched request subscribers: {}'.format(sub.__class__.__name__))

            try:

                verifyObject(isubscriber, sub)

            except DoesNotImplement as e:

                self.__logger.warning('Incorrect implementation: {}'.format(e))

            else:

                comp = sub.compare()

                if comp is not False and IJSONResource.providedBy(comp):

                    self.__logger.debug('Signature compare to {}'.format(comp.__class__.__name__))

                    # trying to resolve API that will deal with these request

                    if len(comp.to_dict().keys()) > 1:
                        # process request without root element
                        return NonRootAPI(comp).check()

                    else:
                        # root element
                        return RootAPI(comp).check()

        # if there are no one subsciber from IJSONResource

        self.__logger.warning('The request {} from type {} was not recognized as a structure or an API'.format(
            valid_response.response,
            valid_dispatch.message_type
        ))

        return False

    def dispatch(self):

        """
        When request is happening first will be validated,
        if valid_dispatch is False means we do not support this data type. You have to write your custom
        validator(s) inside components/validators

        :return: The response or False
        """

        # validate for supporting types

        try:
            valid_dispatch = self.validator.validate()

        except Exception as e:

            self.__logger.debug('validate error: {}'.format(e.message))
            return self.validator

        else:

            if valid_dispatch is False:
                return self.validator

            valid_response = ValidatorResponse(valid_dispatch.message)

            if valid_dispatch.message_type == 'JSON':

                return self.__api_processor(
                    valid_dispatch,
                    valid_response,
                    IJSONResourceSubscriber
                )
Exemplo n.º 46
0
class NonRootAPI(object):

    """
    An API that will check for a Non Root API's
    """

    def __init__(self, comp):

        """
        A NonRootAPi constructor will init a logger and a comp property for an object
        that have to be compare with the existing registered protocols

        :param comp:
        :type comp: an input object as DynamicProtocol

        :return: void
        """

        self.comp = comp
        self.__logger = Logger()

    def check(self):

        """
        Will trying to match the candidate Non Root API
        check IJSONResourceAPI for more info

        :return: False if not success otherwise the response from matched API.method()
        """

        for api in subscribers([self.comp], IJSONResourceAPI):

            if api.__class__.__name__.lower() in self.comp.to_dict().keys():

                self.__logger.debug('Candidate API {} for {}'.format(
                    api.__class__.__name__,
                    self.comp.__class__.__name__
                ))

                candidate_api_name = self.comp.to_dict().get(api.__class__.__name__.lower())

                try:
                    # execute the candidate API method
                    # and return the result
                    candidate_api_result = getattr(api, candidate_api_name)()

                except AttributeError as e:

                    msg = 'Candidate API {} for {} does not implement method {} error: {}'

                    self.__logger.warning(msg.format(
                        api.__class__.__name__,
                        self.comp.__class__.__name__,
                        candidate_api_name,
                        e.message
                    ))

                else:

                    self.__logger.info('Successful apply API {} for {}'.format(
                        api.__class__.__name__,
                        self.comp.__class__.__name__
                    ))

                    return candidate_api_result

        return False
Exemplo n.º 47
0
    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)
Exemplo n.º 48
0
 def __init__(self):
     """
     A constructor will init the logger only
     :return: void
     """
     self.__logger = Logger()
Exemplo n.º 49
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.º 50
0
    def __init__(self, factory):

        super(Time, self).__init__(factory)

        self.factory = factory
        self.logger = Logger()
Exemplo n.º 51
0
class WampDefaultComponent(ApplicationSession):
    """
    Class that represent our default WAMP component we inherit from
    autobahn.twisted.wamp.ApplicationSession
    """
    def __init__(self, **kwargs):
        """
        The constructor will init self.cfg self.__gsm and if the protocol is wss,
        will attach on_connect and on_challenge to this object as methods
        :param kwargs: we looking for key 'config'
        :return: void
        """
        config = kwargs.get('config')

        super(WampDefaultComponent, self).__init__(config)

        self.__logger = Logger()
        self.cfg = Config().get_wamp()

        self.__gsm = getGlobalSiteManager()

        if self.cfg.protocol == 'wss':

            self.__logger.info('WAMP is secure, switch to wss...')

            WampDefaultComponent.onConnect = on_connect
            WampDefaultComponent.onChallenge = on_challenge

    def subscriber_dispatcher(self, sub_data):
        """
        Callback function for our global subscriber
        will pass sub_data to GlobalSubscribeMessage and then will trying to
        get wamp component which implements IUserGlobalSubscriber and adapts
        IGlobalSubscribeMessage

        :param sub_data:
        """

        log = Logger()

        try:

            result = IDispatcher(Validator(sub_data)).dispatch()

        # NETODO what exception can happen here?
        except Exception as e:

            import traceback
            print traceback.format_exc()

            log.warning('subscriber_dispatcher exception: {}'.format(
                e.message))

        else:

            if IValidator.providedBy(result):
                log.warning('WAMP Message is invalid: {}'.format(
                    result.message))

            if result is not False and IJSONResource.providedBy(result):

                fac = None

                for sub in subscribers([result], IUserGlobalSubscriber):

                    sub.subscribe(self)
                    fac = True

                    break

                if not fac:
                    log.warning(
                        'There are no user definition for IUserGlobalSubscriber, message was skipped'
                    )

    @inlineCallbacks
    def onJoin(self, details):
        """
        Autobahn callback function that fired when onJoin happens (we join to our realm)

        Here all components recognized as WAMP we will registering on the fly.

        The global subscriber will be started too, its name is formed by
        netcatks_global_subscriber_ + WAMP Service name.

        Also inside our Storage register will be saved the current WAMP session object
        in __wamp_session__ namespace.

        If there an API which providing a IWAMPLoadOnRunTime implementation will be started on
        run time

        :param details:
        :return:
        """
        self.__logger.info('WAMP Session is ready')

        sub_topic = 'netcatks_global_subscriber_{}'.format(
            self.cfg.service_name.lower().replace(' ', '_'))

        yield self.subscribe(self.subscriber_dispatcher, sub_topic)
        self.__logger.info('Starting global subscriber: {}'.format(sub_topic))

        # registration of all classes which ends with Wamp into shared wamp session
        for x in list(self.__gsm.registeredSubscriptionAdapters()):

            # storing wamp session inside storage
            sr = createObject('storageregister').components
            sr['__wamp_session__'] = self

            if IWAMPResource in x.required:

                if x.factory.__name__ != 'BaseWampComponent':

                    f = x.factory()

                    self.__logger.info('Register Wamp Component: {}'.format(
                        f.__class__.__name__))

                    yield self.register(f)

                    # here we provide wamp session to each wamp component,
                    # in this way every component can access methods like publish, call etc,
                    # which are hosted by default inside wamp session.

                    f.set_session(self)

            if x.provided is IWAMPLoadOnRunTime:
                x.factory('init').load()

    def onDisconnect(self):
        """
        Will be fired when we go a disconnecting from a WAMP router
        :return:
        """
        self.__logger.warning('Disconnected...')

        try:

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

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

        # NETODO what exception trow here?
        except Exception as e:
            self.__logger.warning('disconnect warn: {}'.format(e.message))
Exemplo n.º 52
0
    def __init__(self, factory):

        super(Time, self).__init__(factory)

        self.factory = factory
        self.logger = Logger()
Exemplo n.º 53
0
 def __init__(self):
     """
     A constructor will init the logger only
     :return: void
     """
     self.__logger = Logger()
Exemplo n.º 54
0
class WampDefaultComponent(ApplicationSession):

    """
    Class that represent our default WAMP component we inherit from
    autobahn.twisted.wamp.ApplicationSession
    """

    def __init__(self, **kwargs):
        """
        The constructor will init self.cfg self.__gsm and if the protocol is wss,
        will attach on_connect and on_challenge to this object as methods
        :param kwargs: we looking for key 'config'
        :return: void
        """
        config = kwargs.get('config')

        super(WampDefaultComponent, self).__init__(config)

        self.__logger = Logger()
        self.cfg = Config().get_wamp()

        self.__gsm = getGlobalSiteManager()

        if self.cfg.protocol == 'wss':

            self.__logger.info('WAMP is secure, switch to wss...')

            WampDefaultComponent.onConnect = on_connect
            WampDefaultComponent.onChallenge = on_challenge

    def subscriber_dispatcher(self, sub_data):

        """
        Callback function for our global subscriber
        will pass sub_data to GlobalSubscribeMessage and then will trying to
        get wamp component which implements IUserGlobalSubscriber and adapts
        IGlobalSubscribeMessage

        :param sub_data:
        """

        log = Logger()

        try:

            result = IDispatcher(Validator(sub_data)).dispatch()

        # NETODO what exception can happen here?
        except Exception as e:

            import traceback
            print traceback.format_exc()

            log.warning('subscriber_dispatcher exception: {}'.format(
                e.message
            ))

        else:

            if IValidator.providedBy(result):
                log.warning('WAMP Message is invalid: {}'.format(result.message))

            if result is not False and IJSONResource.providedBy(result):

                fac = None

                for sub in subscribers([result], IUserGlobalSubscriber):

                    sub.subscribe(self)
                    fac = True

                    break

                if not fac:
                    log.warning('There are no user definition for IUserGlobalSubscriber, message was skipped')



    @inlineCallbacks
    def onJoin(self, details):
        """
        Autobahn callback function that fired when onJoin happens (we join to our realm)

        Here all components recognized as WAMP we will registering on the fly.

        The global subscriber will be started too, its name is formed by
        netcatks_global_subscriber_ + WAMP Service name.

        Also inside our Storage register will be saved the current WAMP session object
        in __wamp_session__ namespace.

        If there an API which providing a IWAMPLoadOnRunTime implementation will be started on
        run time

        :param details:
        :return:
        """
        self.__logger.info('WAMP Session is ready')

        sub_topic = 'netcatks_global_subscriber_{}'.format(
            self.cfg.service_name.lower().replace(' ', '_')
        )

        yield self.subscribe(self.subscriber_dispatcher, sub_topic)
        self.__logger.info('Starting global subscriber: {}'.format(sub_topic))

        # registration of all classes which ends with Wamp into shared wamp session
        for x in list(self.__gsm.registeredSubscriptionAdapters()):

            # storing wamp session inside storage
            sr = createObject('storageregister').components
            sr['__wamp_session__'] = self

            if IWAMPResource in x.required:

                if x.factory.__name__ != 'BaseWampComponent':

                    f = x.factory()

                    self.__logger.info('Register Wamp Component: {}'.format(f.__class__.__name__))

                    yield self.register(f)

                    # here we provide wamp session to each wamp component,
                    # in this way every component can access methods like publish, call etc,
                    # which are hosted by default inside wamp session.

                    f.set_session(self)

            if x.provided is IWAMPLoadOnRunTime:
                x.factory('init').load()

    def onDisconnect(self):

        """
        Will be fired when we go a disconnecting from a WAMP router
        :return:
        """
        self.__logger.warning('Disconnected...')

        try:

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

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

        # NETODO what exception trow here?
        except Exception as e:
            self.__logger.warning('disconnect warn: {}'.format(e.message))
Exemplo n.º 55
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.º 56
0
    def __init__(self, factory=None):

        super(Clock, self).__init__(factory)

        self.logger = Logger()