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 start_router_realm(self, realm_id, realm_config, details=None): """ Starts a realm on this router worker. :param realm_id: The ID of the realm to start. :type realm_id: str :param realm_config: The realm configuration. :type realm_config: dict :param details: Call details. :type details: :class:`autobahn.wamp.types.CallDetails` """ self.log.info('Starting router realm {realm_id} {method}', realm_id=hlid(realm_id), method=hltype(RouterController.start_router_realm)) # prohibit starting a realm twice # if realm_id in self.realms: emsg = "Could not start realm: a realm with ID '{}' is already running (or starting)".format( realm_id) self.log.error(emsg) raise ApplicationError(u'crossbar.error.already_running', emsg) # check configuration # try: self.personality.check_router_realm(self.personality, realm_config) except Exception as e: emsg = "Invalid router realm configuration: {}".format(e) self.log.error(emsg) raise ApplicationError(u"crossbar.error.invalid_configuration", emsg) # URI of the realm to start realm = realm_config['name'] # router/realm wide options options = realm_config.get('options', {}) enable_meta_api = options.get('enable_meta_api', True) # expose router/realm service API additionally on local node management router bridge_meta_api = options.get('bridge_meta_api', False) if bridge_meta_api: # FIXME bridge_meta_api_prefix = u'crossbar.worker.{worker_id}.realm.{realm_id}.root.'.format( worker_id=self._worker_id, realm_id=realm_id) else: bridge_meta_api_prefix = None # track realm rlm = self.router_realm_class(realm_id, realm_config) self.realms[realm_id] = rlm self.realm_to_id[realm] = realm_id # create a new router for the realm router = self._router_factory.start_realm(rlm) # add a router/realm service session extra = { # the RouterServiceAgent will fire this when it is ready 'onready': Deferred(), # if True, forward the WAMP meta API (implemented by RouterServiceAgent) # that is normally only exposed on the app router/realm _additionally_ # to the local node management router. 'enable_meta_api': enable_meta_api, 'bridge_meta_api': bridge_meta_api, 'bridge_meta_api_prefix': bridge_meta_api_prefix, # the management session on the local node management router to which # the WAMP meta API is exposed to additionally, when the bridge_meta_api option is set 'management_session': self, } cfg = ComponentConfig(realm, extra) rlm.session = RouterServiceAgent(cfg, router) self._router_session_factory.add(rlm.session, authrole=u'trusted') yield extra['onready'] self.log.info('Realm "{realm_id}" (name="{realm_name}") started', realm_id=realm_id, realm_name=rlm.session._realm) self.publish(u'{}.on_realm_started'.format(self._uri_prefix), realm_id)
def start_router_realm(self, realm_id, realm_config, details=None): """ Starts a realm on this router worker. :param realm_id: The ID of the realm to start. :type realm_id: str :param realm_config: The realm configuration. :type realm_config: dict :param details: Call details. :type details: :class:`autobahn.wamp.types.CallDetails` """ self.log.info('Starting router realm {realm_id} {method}', realm_id=hlid(realm_id), method=hltype(RouterController.start_router_realm)) # prohibit starting a realm twice # if realm_id in self.realms: emsg = "Could not start realm: a realm with ID '{}' is already running (or starting)".format( realm_id) self.log.error(emsg) raise ApplicationError('crossbar.error.already_running', emsg) # check configuration # try: self.personality.check_router_realm(self.personality, realm_config) except Exception as e: emsg = "Invalid router realm configuration: {}".format(e) self.log.error(emsg) raise ApplicationError("crossbar.error.invalid_configuration", emsg) # URI of the realm to start realm_name = realm_config['name'] # router/realm wide options options = realm_config.get('options', {}) enable_meta_api = options.get('enable_meta_api', True) # expose router/realm service API additionally on local node management router bridge_meta_api = options.get('bridge_meta_api', False) if bridge_meta_api: # FIXME bridge_meta_api_prefix = 'crossbar.worker.{worker_id}.realm.{realm_id}.root.'.format( worker_id=self._worker_id, realm_id=realm_id) else: bridge_meta_api_prefix = None # track realm rlm = self.router_realm_class(self, realm_id, realm_config) self.realms[realm_id] = rlm self.realm_to_id[realm_name] = realm_id # create a new router for the realm rlm.router = self._router_factory.start_realm(rlm) if rlm.router._store and hasattr(rlm.router._store, 'start'): yield rlm.router._store.start() # add a router/realm service session extra = { # the RouterServiceAgent will fire this when it is ready 'onready': Deferred(), # if True, forward the WAMP meta API (implemented by RouterServiceAgent) # that is normally only exposed on the app router/realm _additionally_ # to the local node management router. 'enable_meta_api': enable_meta_api, 'bridge_meta_api': bridge_meta_api, 'bridge_meta_api_prefix': bridge_meta_api_prefix, # the management session on the local node management router to which # the WAMP meta API is exposed to additionally, when the bridge_meta_api option is set 'management_session': self, } cfg = ComponentConfig(realm_name, extra) # each worker is run under its own dedicated WAMP auth role # svc_authrole = 'crossbar.worker.{}'.format(self._worker_id) # wamp meta api only allowed for "trusted" sessions svc_authrole = 'trusted' svc_authid = 'routerworker-{}-realm-{}-serviceagent'.format( self._worker_id, realm_id) rlm.session = RouterServiceAgent(cfg, rlm.router) self._router_session_factory.add(rlm.session, rlm.router, authid=svc_authid, authrole=svc_authrole) yield extra['onready'] self.set_service_session(rlm.session, realm_name, authrole=svc_authrole) self.log.info( 'RouterServiceAgent started on realm="{realm_name}" with authrole="{authrole}", authid="{authid}"', realm_name=realm_name, authrole=svc_authrole, authid=svc_authid) self.publish('{}.on_realm_started'.format(self._uri_prefix), realm_id) topic = '{}.on_realm_started'.format(self._uri_prefix) event = rlm.marshal() caller = details.caller if details else None self.publish(topic, event, options=PublishOptions(exclude=caller)) self.log.info( 'Realm "{realm_id}" (name="{realm_name}", authrole="{authrole}", authid="{authid}") started', realm_id=realm_id, realm_name=rlm.session._realm, authrole=svc_authrole, authid=svc_authid) return event