def add_realm_to_router(router_factory, session_factory, realm_name=u'default', realm_options={}): opts = dict(realm_options) opts.update({u'name': realm_name}) # start a realm realm = RouterRealm(None, None, opts) router = router_factory.start_realm(realm) extra = {} session_config = ComponentConfig(realm_name, extra) realm.session = RouterServiceAgent(session_config, router) # allow everything default_permissions = { u'uri': u'', u'match': u'prefix', u'allow': { u'call': True, u'register': True, u'publish': True, u'subscribe': True } } router = router_factory.get(realm_name) router.add_role(RouterRoleStaticAuth(router, 'anonymous', default_permissions=default_permissions)) session_factory.add(realm.session, router, authrole=u'trusted') return router
def add_realm_to_router(router_factory, session_factory, realm_name='default', realm_options={}): opts = dict(realm_options) opts.update({'name': realm_name}) # start a realm realm = RouterRealm(None, None, opts) router = router_factory.start_realm(realm) extra = {} session_config = ComponentConfig(realm_name, extra) realm.session = RouterServiceAgent(session_config, router) # allow everything default_permissions = { 'uri': '', 'match': 'prefix', 'allow': { 'call': True, 'register': True, 'publish': True, 'subscribe': True } } router = router_factory.get(realm_name) router.add_role(RouterRoleStaticAuth(router, 'anonymous', default_permissions=default_permissions)) session_factory.add(realm.session, router, authrole='trusted') return router
def __init__(self, controller, realm_id, config, router=None, session=None): """ :param controller: :param realm_id: The realm ID within the router. :type realm_id: str :param config: The realm configuration. :type config: dict :param router: The router (within the router worker) serving the realm. :type router: :class:`crossbar.edge.worker.router.ExtRouter` :param session: The realm service session. :type session: :class:`crossbar.router.service.RouterServiceAgent` """ RouterRealm.__init__(self, controller, realm_id, config, router=router, session=session) # FIXME self.interfaces = {}
def setUp(self): """ Setup router and router session factories. """ # create a router factory self.router_factory = RouterFactory('node1', 'router1', None) # start a realm self.realm = RouterRealm(None, None, {'name': 'realm1'}) self.router_factory.start_realm(self.realm) # allow everything self.router = self.router_factory.get('realm1') self.router.add_role( RouterRoleStaticAuth(self.router, 'test_role', default_permissions={ 'uri': 'com.example.', 'match': 'prefix', 'allow': { 'call': True, 'register': True, 'publish': True, 'subscribe': True, } })) # create a router session factory self.session_factory = RouterSessionFactory(self.router_factory)
def test_router_session_lifecycle(self): """ We see all 'lifecycle' notifications. """ from crossbar.router.session import RouterApplicationSession def mock_fire(name, *args, **kw): fired.append(name) return defer.succeed(None) fired = [] session = ApplicationSession() session._realm = 'realm' session.fire = mock.Mock(side_effect=mock_fire) router = Router(factory=mock.Mock(), realm=RouterRealm( controller=None, id='realm', config=dict(name='realm'), )) rap = RouterApplicationSession(session, router) # we never fake out the 'Welcome' message, so there will be no # 'ready' notification... rap.send(message.Goodbye('wamp.reason.logout', 'some custom message')) self.assertTrue('connect' in fired) self.assertTrue('join' in fired) self.assertTrue('ready' in fired) self.assertTrue('leave' in fired) self.assertTrue('disconnect' in fired)
def test_router_session_goodbye_fire_disconnect_error(self): """ Reason should be propagated properly from Goodbye message """ from crossbar.router.session import RouterApplicationSession session = ApplicationSession() the_exception = RuntimeError("sad times at ridgemont high") def boom(*args, **kw): if args[0] == 'disconnect': return defer.fail(the_exception) return defer.succeed(None) session.fire = mock.Mock(side_effect=boom) session._realm = 'realm' router = Router(factory=mock.Mock(), realm=RouterRealm( controller=None, id='realm', config=dict(name='realm'), )) rap = RouterApplicationSession(session, router) rap.send(message.Goodbye('wamp.reason.logout', 'some custom message')) errors = self.flushLoggedErrors() self.assertEqual(1, len(errors)) self.assertEqual(the_exception, errors[0].value)
def test_router_session_goodbye_onLeave_error(self): """ Reason should be propagated properly from Goodbye message """ from crossbar.router.session import RouterApplicationSession session = ApplicationSession() the_exception = RuntimeError("onLeave fails") def boom(*args, **kw): raise the_exception session.onLeave = mock.Mock(side_effect=boom) session._realm = 'realm' router = Router(factory=mock.Mock(), realm=RouterRealm( controller=None, id='realm', config=dict(name='realm'), )) rap = RouterApplicationSession(session, router) rap.send(message.Goodbye('wamp.reason.logout', 'some custom message')) errors = self.flushLoggedErrors() self.assertEqual(1, len(errors)) self.assertEqual(the_exception, errors[0].value)
def setUp(self): """ Setup router and router session factories. """ # create a router factory self.router_factory = RouterFactory(None, None) # start a realm self.router_factory.start_realm(RouterRealm(None, {u'name': u'realm1'})) # allow everything default_permissions = { u'uri': u'', u'match': u'prefix', u'allow': { u'call': True, u'register': True, u'publish': True, u'subscribe': True } } self.router = self.router_factory.get(u'realm1') self.router.add_role( RouterRoleStaticAuth(self.router, u'test_role', default_permissions=default_permissions)) self.router.add_role( RouterRoleStaticAuth(self.router, None, default_permissions=default_permissions)) # create a router session factory self.session_factory = RouterSessionFactory(self.router_factory)
def test_router_session_goodbye_custom_message(self): """ Reason should be propagated properly from Goodbye message """ from crossbar.router.session import RouterApplicationSession session = ApplicationSession() session.onLeave = mock.Mock() session._realm = 'realm' router = Router( factory=mock.Mock(), realm=RouterRealm( controller=MockContainer(), id='realm', config=dict(name='realm'), ) ) rap = RouterApplicationSession(session, router) rap.send(message.Goodbye('wamp.reason.logout', 'some custom message')) leaves = session.onLeave.mock_calls self.assertEqual(1, len(leaves)) details = leaves[0][1][0] self.assertEqual('wamp.reason.logout', details.reason) self.assertEqual('some custom message', details.message)
def marshal(self): marshalled = RouterRealm.marshal(self) # FIXME marshalled['interfaces'] = self.interfaces return marshalled
def start(self, node_id=None): """ Starts this node. This will start a node controller and then spawn new worker processes as needed. The node keys (``load_keys``) and configuration (``load_config``) has to be loaded before starting the node. This is the _third_ function being called after the Node has been instantiated. """ self.log.info('Starting {personality} node {method}', personality=self.personality.NAME, method=hltype(Node.start)) # a configuration must have been loaded before if not self._config: raise Exception("No node configuration set") # a node can only be started once for now assert self._shutdown_complete is None assert self._node_id is None # get controller config/options controller_config = self._config.get('controller', {}) controller_options = controller_config.get('options', {}) # the node ID: CLI takes precedence over config over hostname if node_id: self._node_id = node_id _node_id_source = 'explicit run-time argument' elif 'id' in controller_config: self._node_id = controller_config['id'] _node_id_source = 'explicit configuration' else: self._node_id = u'{}'.format(socket.gethostname()).lower() _node_id_source = 'hostname' self.log.info('Node ID {node_id} set from {node_id_source}', node_id=hlid(self._node_id), node_id_source=_node_id_source) # set controller process title try: import setproctitle except ImportError: self.log.warn( "Warning, could not set process title (setproctitle not installed)" ) else: setproctitle.setproctitle( controller_options.get('title', 'crossbar-controller')) # add the node controller singleton component self._controller = self.NODE_CONTROLLER(self) # local node management router self._router_factory = RouterFactory(self._node_id, None) self._router_session_factory = RouterSessionFactory( self._router_factory) rlm_config = {'name': self._realm} rlm = RouterRealm(self._controller, None, rlm_config) router = self._router_factory.start_realm(rlm) # setup global static roles self._add_global_roles() # always add a realm service session cfg = ComponentConfig(self._realm) rlm.session = (self.ROUTER_SERVICE)(cfg, router) self._router_session_factory.add(rlm.session, authrole=u'trusted') self.log.debug('Router service session attached [{router_service}]', router_service=qual(self.ROUTER_SERVICE)) self._router_session_factory.add(self._controller, authrole=u'trusted') self.log.debug('Node controller attached [{node_controller}]', node_controller=qual(self.NODE_CONTROLLER)) # add extra node controller components self._add_extra_controller_components(controller_options) # setup Node shutdown triggers self._set_shutdown_triggers(controller_options) # setup node shutdown Deferred self._shutdown_complete = Deferred() # startup the node personality .. yield self.personality.Node.boot(self) # notify systemd that we are fully up and running try: import sdnotify except ImportError: # do nothing on non-systemd platforms pass else: sdnotify.SystemdNotifier().notify("READY=1") # return a shutdown deferred which we will fire to notify the code that # called start() - which is the main crossbar boot code res = {'shutdown_complete': self._shutdown_complete} returnValue(res)
def start(self, node_id=None): """ Starts this node. This will start a node controller and then spawn new worker processes as needed. """ self.log.info('Starting {personality} node {method}', personality=self.personality.NAME, method=hltype(Node.start)) # a configuration must have been loaded before if not self._config: raise Exception("No node configuration set") # a node can only be started once for now assert self._shutdown_complete is None assert self._node_id is None # get controller config/options controller_config = self._config.get('controller', {}) controller_options = controller_config.get('options', {}) # the node ID: CLI takes precedence over config over hostname if node_id: self._node_id = node_id _node_id_source = 'explicit run-time argument' elif 'id' in controller_config: self._node_id = controller_config['id'] _node_id_source = 'explicit configuration' else: self._node_id = u'{}'.format(socket.gethostname()).lower() _node_id_source = 'hostname' self.log.info('Node ID {node_id} set from {node_id_source}', node_id=hlid(self._node_id), node_id_source=_node_id_source) # set controller process title try: import setproctitle except ImportError: self.log.warn("Warning, could not set process title (setproctitle not installed)") else: setproctitle.setproctitle(controller_options.get('title', 'crossbar-controller')) # local node management router self._router_factory = RouterFactory(self._node_id, None) self._router_session_factory = RouterSessionFactory(self._router_factory) rlm_config = { 'name': self._realm } rlm = RouterRealm(None, rlm_config) router = self._router_factory.start_realm(rlm) # setup global static roles self._add_global_roles() # always add a realm service session cfg = ComponentConfig(self._realm) rlm.session = (self.ROUTER_SERVICE)(cfg, router) self._router_session_factory.add(rlm.session, authrole=u'trusted') self.log.debug('Router service session attached [{router_service}]', router_service=qual(self.ROUTER_SERVICE)) # add the node controller singleton component self._controller = self.NODE_CONTROLLER(self) self._router_session_factory.add(self._controller, authrole=u'trusted') self.log.debug('Node controller attached [{node_controller}]', node_controller=qual(self.NODE_CONTROLLER)) # add extra node controller components self._add_extra_controller_components(controller_options) # setup Node shutdown triggers self._set_shutdown_triggers(controller_options) # setup node shutdown Deferred self._shutdown_complete = Deferred() # startup the node personality .. yield self.personality.Node.boot(self) # notify systemd that we are fully up and running try: import sdnotify except ImportError: # do nothing on non-systemd platforms pass else: sdnotify.SystemdNotifier().notify("READY=1") # return a shutdown deferred which we will fire to notify the code that # called start() - which is the main crossbar boot code res = { 'shutdown_complete': self._shutdown_complete } returnValue(res)