Beispiel #1
0
    def start_router_component(self, id, config, details=None):
        """
        Start an app component in this router worker.

        :param id: The ID of the component to start.
        :type id: str
        :param config: The component configuration.
        :type config: obj
        """
        self.log.debug("{}.start_router_component".format(self.__class__.__name__),
                       id=id, config=config)

        # prohibit starting a component twice
        #
        if id in self.components:
            emsg = "Could not start component: a component with ID '{}'' is already running (or starting)".format(id)
            self.log.error(emsg)
            raise ApplicationError(u'crossbar.error.already_running', emsg)

        # check configuration
        #
        try:
            checkconfig.check_router_component(config)
        except Exception as e:
            emsg = "Invalid router component configuration: {}".format(e)
            self.log.error(emsg)
            raise ApplicationError(u"crossbar.error.invalid_configuration", emsg)
        else:
            self.log.debug("Starting {type}-component on router.",
                           type=config['type'])

        # resolve references to other entities
        #
        references = {}
        for ref in config.get('references', []):
            ref_type, ref_id = ref.split(':')
            if ref_type == u'connection':
                if ref_id in self._connections:
                    references[ref] = self._connections[ref_id]
                else:
                    emsg = "cannot resolve reference '{}' - no '{}' with ID '{}'".format(ref, ref_type, ref_id)
                    self.log.error(emsg)
                    raise ApplicationError(u"crossbar.error.invalid_configuration", emsg)
            else:
                emsg = "cannot resolve reference '{}' - invalid reference type '{}'".format(ref, ref_type)
                self.log.error(emsg)
                raise ApplicationError(u"crossbar.error.invalid_configuration", emsg)

        # create component config
        #
        realm = config['realm']
        extra = config.get('extra', None)
        component_config = ComponentConfig(realm=realm, extra=extra)
        create_component = _appsession_loader(config)

        # .. and create and add an WAMP application session to
        # run the component next to the router
        #
        try:
            session = create_component(component_config)

            # any exception spilling out from user code in onXXX handlers is fatal!
            def panic(fail, msg):
                self.log.error(
                    "Fatal error in component: {msg} - {log_failure.value}",
                    msg=msg, log_failure=fail
                )
                session.disconnect()
            session._swallow_error = panic
        except Exception:
            self.log.error(
                "Component instantiation failed",
                log_failure=Failure(),
            )
            raise

        self.components[id] = RouterComponent(id, config, session)
        self._router_session_factory.add(session, authrole=config.get('role', u'anonymous'))
        self.log.debug("Added component {id}", id=id)
Beispiel #2
0
    def start_router_component(self, id, config, details=None):
        """
      Dynamically start an application component to run next to the router in "embedded mode".

      :param id: The ID of the component to start.
      :type id: str
      :param config: The component configuration.
      :type config: obj
      """
        if self.debug:
            log.msg(
                "{}.start_router_component".format(self.__class__.__name__),
                id, config)

        ## prohibit starting a component twice
        ##
        if id in self.components:
            emsg = "ERROR: could not start component - a component with ID '{}'' is already running (or starting)".format(
                id)
            log.msg(emsg)
            raise ApplicationError('crossbar.error.already_running', emsg)

        ## check configuration
        ##
        try:
            checkconfig.check_router_component(config)
        except Exception as e:
            emsg = "ERROR: invalid router component configuration ({})".format(
                e)
            log.msg(emsg)
            raise ApplicationError("crossbar.error.invalid_configuration",
                                   emsg)
        else:
            if self.debug:
                log.msg("Starting {}-component on router.".format(
                    config['type']))

        realm = config['realm']
        cfg = ComponentConfig(realm=realm, extra=config.get('extra', None))

        if config['type'] == 'class':

            try:
                klassname = config['classname']

                if self.debug:
                    log.msg("Starting class '{}'".format(klassname))

                c = klassname.split('.')
                module_name, klass_name = '.'.join(c[:-1]), c[-1]
                module = importlib.import_module(module_name)
                make = getattr(module, klass_name)

            except Exception as e:
                emsg = "Failed to import class '{}' - {}".format(klassname, e)
                log.msg(emsg)
                raise ApplicationError("crossbar.error.class_import_failed",
                                       emsg)

        elif config['type'] == 'wamplet':

            try:
                dist = config['package']
                name = config['entrypoint']

                if self.debug:
                    log.msg("Starting WAMPlet '{}/{}'".format(dist, name))

                ## make is supposed to make instances of ApplicationSession
                make = pkg_resources.load_entry_point(
                    dist, 'autobahn.twisted.wamplet', name)

            except Exception as e:
                emsg = "Failed to import wamplet '{}/{}' - {}".format(
                    dist, name, e)
                log.msg(emsg)
                raise ApplicationError("crossbar.error.class_import_failed",
                                       emsg)

        else:
            raise ApplicationError(
                "crossbar.error.invalid_configuration",
                "invalid component type '{}'".format(config['type']))

        ## .. and create and add an WAMP application session to
        ## run the component next to the router
        ##
        try:
            session = make(cfg)
        except Exception as e:
            raise ApplicationError("crossbar.error.class_import_failed",
                                   str(e))

        if not isinstance(session, ApplicationSession):
            raise ApplicationError(
                "crossbar.error.class_import_failed",
                "session not derived of ApplicationSession")

        self.components[id] = RouterComponent(id, config, session)
        self.session_factory.add(session,
                                 authrole=config.get('role', 'anonymous'))
Beispiel #3
0
    def start_router_component(self, id, config, details=None):
        """
        Dynamically start an application component to run next to the router in "embedded mode".

        :param id: The ID of the component to start.
        :type id: str
        :param config: The component configuration.
        :type config: obj
        """
        self.log.debug("{}.start_router_component".format(self.__class__.__name__),
                       id=id, config=config)

        # prohibit starting a component twice
        #
        if id in self.components:
            emsg = "Could not start component: a component with ID '{}'' is already running (or starting)".format(id)
            self.log.error(emsg)
            raise ApplicationError(u'crossbar.error.already_running', emsg)

        # check configuration
        #
        try:
            checkconfig.check_router_component(config)
        except Exception as e:
            emsg = "Invalid router component configuration: {}".format(e)
            self.log.error(emsg)
            raise ApplicationError(u"crossbar.error.invalid_configuration", emsg)
        else:
            self.log.debug("Starting {type}-component on router.",
                           type=config['type'])

        # resolve references to other entities
        #
        references = {}
        for ref in config.get('references', []):
            ref_type, ref_id = ref.split(':')
            if ref_type == u'connection':
                if ref_id in self._connections:
                    references[ref] = self._connections[ref_id]
                else:
                    emsg = "cannot resolve reference '{}' - no '{}' with ID '{}'".format(ref, ref_type, ref_id)
                    self.log.error(emsg)
                    raise ApplicationError(u"crossbar.error.invalid_configuration", emsg)
            else:
                emsg = "cannot resolve reference '{}' - invalid reference type '{}'".format(ref, ref_type)
                self.log.error(emsg)
                raise ApplicationError(u"crossbar.error.invalid_configuration", emsg)

        # create component config
        #
        realm = config['realm']
        extra = config.get('extra', None)
        component_config = ComponentConfig(realm=realm, extra=extra)
        create_component = _appsession_loader(config)

        # .. and create and add an WAMP application session to
        # run the component next to the router
        #
        try:
            session = create_component(component_config)

            # any exception spilling out from user code in onXXX handlers is fatal!
            def panic(fail, msg):
                self.log.error("Fatal error in component: {} - {}".format(msg, fail.value))
                session.disconnect()
            session._swallow_error = panic
        except Exception as e:
            msg = "{}".format(e).strip()
            self.log.error("Component instantiation failed:\n\n{err}", err=msg)
            raise

        self.components[id] = RouterComponent(id, config, session)
        self._router_session_factory.add(session, authrole=config.get('role', u'anonymous'))
        self.log.debug("Added component {id}", id=id)
Beispiel #4
0
    def start_router_component(self, id, config, details=None):
        """
        Start an app component in this router worker.

        :param id: The ID of the component to start.
        :type id: str
        :param config: The component configuration.
        :type config: obj
        """
        self.log.debug("{}.start_router_component".format(
            self.__class__.__name__),
                       id=id,
                       config=config)

        # prohibit starting a component twice
        #
        if id in self.components:
            emsg = "Could not start component: a component with ID '{}'' is already running (or starting)".format(
                id)
            self.log.error(emsg)
            raise ApplicationError(u'crossbar.error.already_running', emsg)

        # check configuration
        #
        try:
            checkconfig.check_router_component(config)
        except Exception as e:
            emsg = "Invalid router component configuration: {}".format(e)
            self.log.error(emsg)
            raise ApplicationError(u"crossbar.error.invalid_configuration",
                                   emsg)
        else:
            self.log.debug("Starting {type}-component on router.",
                           type=config['type'])

        # resolve references to other entities
        #
        references = {}
        for ref in config.get('references', []):
            ref_type, ref_id = ref.split(':')
            if ref_type == u'connection':
                if ref_id in self._connections:
                    references[ref] = self._connections[ref_id]
                else:
                    emsg = "cannot resolve reference '{}' - no '{}' with ID '{}'".format(
                        ref, ref_type, ref_id)
                    self.log.error(emsg)
                    raise ApplicationError(
                        u"crossbar.error.invalid_configuration", emsg)
            else:
                emsg = "cannot resolve reference '{}' - invalid reference type '{}'".format(
                    ref, ref_type)
                self.log.error(emsg)
                raise ApplicationError(u"crossbar.error.invalid_configuration",
                                       emsg)

        # create component config
        #
        realm = config['realm']
        extra = config.get('extra', None)
        component_config = ComponentConfig(realm=realm, extra=extra)
        create_component = _appsession_loader(config)

        # .. and create and add an WAMP application session to
        # run the component next to the router
        #
        try:
            session = create_component(component_config)

            # any exception spilling out from user code in onXXX handlers is fatal!
            def panic(fail, msg):
                self.log.error(
                    "Fatal error in component: {msg} - {log_failure.value}",
                    msg=msg,
                    log_failure=fail)
                session.disconnect()

            session._swallow_error = panic
        except Exception:
            self.log.error(
                "Component instantiation failed",
                log_failure=Failure(),
            )
            raise

        def publish_stopped(session, details):
            topic = self._uri_prefix + '.container.on_component_stop'
            event = {u'id': id}
            session.publish(topic,
                            event,
                            options=PublishOptions(exclude=details.caller))
            return event

        def publish_started(session, details):
            topic = self._uri_prefix + '.container.on_component_start'
            event = {u'id': id}
            session.publish(topic,
                            event,
                            options=PublishOptions(exclude=details.caller))
            return event

        session.on('join', publish_started)
        session.on('leave', publish_stopped)

        self.components[id] = RouterComponent(id, config, session)
        self._router_session_factory.add(session,
                                         authrole=config.get(
                                             'role', u'anonymous'))
        self.log.debug("Added component {id}", id=id)
Beispiel #5
0
    def start_router_component(self, id, config, details=None):
        """
        Dynamically start an application component to run next to the router in "embedded mode".

        :param id: The ID of the component to start.
        :type id: str
        :param config: The component configuration.
        :type config: obj
        """
        if self.debug:
            log.msg("{}.start_router_component".format(self.__class__.__name__), id, config)

        # prohibit starting a component twice
        #
        if id in self.components:
            emsg = "ERROR: could not start component - a component with ID '{}'' is already running (or starting)".format(id)
            log.msg(emsg)
            raise ApplicationError('crossbar.error.already_running', emsg)

        # check configuration
        #
        try:
            checkconfig.check_router_component(config)
        except Exception as e:
            emsg = "ERROR: invalid router component configuration ({})".format(e)
            log.msg(emsg)
            raise ApplicationError("crossbar.error.invalid_configuration", emsg)
        else:
            if self.debug:
                log.msg("Starting {}-component on router.".format(config['type']))

        realm = config['realm']
        cfg = ComponentConfig(realm=realm, extra=config.get('extra', None))

        if config['type'] == 'class':

            try:
                klassname = config['classname']

                if self.debug:
                    log.msg("Starting class '{}'".format(klassname))

                c = klassname.split('.')
                module_name, klass_name = '.'.join(c[:-1]), c[-1]
                module = importlib.import_module(module_name)
                make = getattr(module, klass_name)

            except Exception as e:
                emsg = "Failed to import class '{}' - {}".format(klassname, e)
                log.msg(emsg)
                log.msg("PYTHONPATH: {}".format(sys.path))
                raise ApplicationError("crossbar.error.class_import_failed", emsg)

        elif config['type'] == 'wamplet':

            try:
                dist = config['package']
                name = config['entrypoint']

                if self.debug:
                    log.msg("Starting WAMPlet '{}/{}'".format(dist, name))

                # make is supposed to make instances of ApplicationSession
                make = pkg_resources.load_entry_point(dist, 'autobahn.twisted.wamplet', name)

            except Exception as e:
                emsg = "Failed to import wamplet '{}/{}' - {}".format(dist, name, e)
                log.msg(emsg)
                raise ApplicationError("crossbar.error.class_import_failed", emsg)

        else:
            raise ApplicationError("crossbar.error.invalid_configuration", "invalid component type '{}'".format(config['type']))

        # .. and create and add an WAMP application session to
        # run the component next to the router
        #
        try:
            session = make(cfg)
        except Exception as e:
            raise ApplicationError("crossbar.error.class_import_failed", str(e))

        if not isinstance(session, ApplicationSession):
            raise ApplicationError("crossbar.error.class_import_failed", "session not derived of ApplicationSession")

        self.components[id] = RouterComponent(id, config, session)
        self.session_factory.add(session, authrole=config.get('role', u'anonymous'))
Beispiel #6
0
    def start_router_component(self, id, config, details=None):
        """
        Start an app component in this router worker.

        :param id: The ID of the component to start.
        :type id: str
        :param config: The component configuration.
        :type config: obj
        """
        self.log.debug("{}.start_router_component".format(self.__class__.__name__),
                       id=id, config=config)

        # prohibit starting a component twice
        #
        if id in self.components:
            emsg = "Could not start component: a component with ID '{}'' is already running (or starting)".format(id)
            self.log.error(emsg)
            raise ApplicationError(u'crossbar.error.already_running', emsg)

        # check configuration
        #
        try:
            checkconfig.check_router_component(config)
        except Exception as e:
            emsg = "Invalid router component configuration: {}".format(e)
            self.log.error(emsg)
            raise ApplicationError(u"crossbar.error.invalid_configuration", emsg)
        else:
            self.log.debug("Starting {type}-component on router.",
                           type=config['type'])

        # resolve references to other entities
        #
        references = {}
        for ref in config.get('references', []):
            ref_type, ref_id = ref.split(':')
            if ref_type == u'connection':
                if ref_id in self._connections:
                    references[ref] = self._connections[ref_id]
                else:
                    emsg = "cannot resolve reference '{}' - no '{}' with ID '{}'".format(ref, ref_type, ref_id)
                    self.log.error(emsg)
                    raise ApplicationError(u"crossbar.error.invalid_configuration", emsg)
            else:
                emsg = "cannot resolve reference '{}' - invalid reference type '{}'".format(ref, ref_type)
                self.log.error(emsg)
                raise ApplicationError(u"crossbar.error.invalid_configuration", emsg)

        # create component config
        #
        realm = config['realm']
        extra = config.get('extra', None)
        component_config = ComponentConfig(realm=realm, extra=extra)
        create_component = _appsession_loader(config)

        # .. and create and add an WAMP application session to
        # run the component next to the router
        #
        try:
            session = create_component(component_config)

            # any exception spilling out from user code in onXXX handlers is fatal!
            def panic(fail, msg):
                self.log.error(
                    "Fatal error in component: {msg} - {log_failure.value}",
                    msg=msg, log_failure=fail
                )
                session.disconnect()
            session._swallow_error = panic
        except Exception:
            self.log.error(
                "Component instantiation failed",
                log_failure=Failure(),
            )
            raise

        # Note that 'join' is fired to listeners *before* onJoin runs,
        # so if you do 'yield self.leave()' in onJoin we'll still
        # publish "started" before "stopped".

        def publish_stopped(session, stop_details):
            self.log.info(
                "stopped component: {session} id={session_id}",
                session=class_name(session),
                session_id=session._session_id,
            )
            topic = self._uri_prefix + '.container.on_component_stop'
            event = {u'id': id}
            caller = details.caller if details else None
            self.publish(topic, event, options=PublishOptions(exclude=caller))
            return event

        def publish_started(session, start_details):
            self.log.info(
                "started component: {session} id={session_id}",
                session=class_name(session),
                session_id=session._session_id,
            )
            topic = self._uri_prefix + '.container.on_component_start'
            event = {u'id': id}
            caller = details.caller if details else None
            self.publish(topic, event, options=PublishOptions(exclude=caller))
            return event
        session.on('leave', publish_stopped)
        session.on('join', publish_started)

        self.components[id] = RouterComponent(id, config, session)
        self._router_session_factory.add(session, authrole=config.get('role', u'anonymous'))
        self.log.debug(
            "Added component {id} (type '{name}')",
            id=id,
            name=class_name(session),
        )