Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
Stop an app component currently running in this router worker.
:param id: The ID of the component to stop.
:type id: str
"""
self.log.debug("{name}.stop_router_component({id})", name=self.__class__.__name__, id=id)
if id in self.components:
self.log.debug("Worker {worker}: stopping component {id}", worker=self.config.extra.worker, id=id)
try:
# self._components[id].disconnect()
self._session_factory.remove(self.components[id])
del self.components[id]
except Exception as e:
raise ApplicationError(u"crossbar.error.cannot_stop", "Failed to stop component {}: {}".format(id, e))
else:
raise ApplicationError(u"crossbar.error.no_such_object", "No component {}".format(id))
def connect_error(fail):
if isinstance(fail.value, asyncio.CancelledError):
reconnect[0] = False
txaio.reject(done_f, fail)
return
self.log.debug(u'component failed: {error}', error=txaio.failure_message(fail))
self.log.debug(u'{tb}', tb=txaio.failure_format_traceback(fail))
# If this is a "fatal error" that will never work,
# we bail out now
if isinstance(fail.value, ApplicationError):
if fail.value.error in [u'wamp.error.no_such_realm']:
reconnect[0] = False
self.log.error(u"Fatal error, not reconnecting")
txaio.reject(done_f, fail)
return
self.log.error(u"{msg}", msg=fail.value.error_message())
return one_reconnect_loop(None)
elif isinstance(fail.value, OSError):
# failed to connect entirely, like nobody
# listening etc.
self.log.info(u"Connection failed: {msg}", msg=txaio.failure_message(fail))
return one_reconnect_loop(None)
elif _is_ssl_error(fail.value):
:type details: instance of :class:`autobahn.wamp.types.CallDetails`
:returns: Component startup information.
:rtype: dict
"""
self.log.debug('{klass}.start_component({component_id}, {config})',
klass=self.__class__.__name__,
component_id=component_id,
config=config)
# prohibit starting a component twice
#
if component_id in self.components:
emsg = 'duplicate component "{}" - a component with this ID is already running (or starting)'.format(component_id)
self.log.debug(emsg)
raise ApplicationError('crossbar.error.already_running', emsg)
# check component configuration
#
try:
self.personality.check_container_component(self.personality, config)
except Exception as e:
emsg = 'invalid container component configuration: {}'.format(e)
self.log.debug(emsg)
raise ApplicationError('crossbar.error.invalid_configuration', emsg)
else:
self.log.debug('starting component "{component_id}" ..', component_id=component_id)
# WAMP application component factory
#
realm = config.get('realm', None)
assert type(realm) == str
# Setup Jinja2 to point to our templates folder or a package resource
#
templates_config = config.get("templates")
if type(templates_config) == str:
# resolve specified template directory path relative to node directory
templates_dir = os.path.abspath(
os.path.join(self._worker.config.extra.cbdir, templates_config))
templates_source = 'directory'
elif type(templates_config) == dict:
# in case we got a dict, that must contain "package" and "resource" attributes
if 'package' not in templates_config:
raise ApplicationError('crossbar.error.invalid_configuration', 'missing attribute "resource" in WAP web service configuration')
if 'resource' not in templates_config:
raise ApplicationError('crossbar.error.invalid_configuration', 'missing attribute "resource" in WAP web service configuration')
try:
importlib.import_module(templates_config['package'])
except ImportError as e:
emsg = 'Could not import resource {} from package {}: {}'.format(templates_config['resource'], templates_config['package'], e)
raise ApplicationError('crossbar.error.invalid_configuration', emsg)
else:
try:
# resolve template directory from package resource
templates_dir = os.path.abspath(pkg_resources.resource_filename(templates_config['package'], templates_config['resource']))
except Exception as e:
emsg = 'Could not import resource {} from package {}: {}'.format(templates_config['resource'], templates_config['package'], e)
raise ApplicationError('crossbar.error.invalid_configuration', emsg)
self,
prefix='{}.'.format(self._uri_prefix),
options=RegisterOptions(details_arg='details'),
)
procs = []
errors = []
for reg in regs:
if isinstance(reg, Failure):
self.log.error("Failed to register management procedure: {f}", f=reg, log_failure=reg)
errors.append(str(reg))
else:
procs.append(reg.procedure)
if errors:
raise ApplicationError('crossbar.error.cannot_start', 'management API could not be initialized',
errors=errors)
else:
self.log.info('Ok, registered {len_reg} management procedures on realm "{realm}" [{func}]:\n\n{procs}\n',
len_reg=hlval(len(regs)),
realm=hl(self.realm),
func=hltype(self.onJoin),
procs=hl(pformat(procs), color='white', bold=True))
returnValue(regs)
( self._option_uri_strict and not _URI_PAT_STRICT_NON_EMPTY.match(publish.topic)):
if publish.acknowledge:
reply = message.Error(message.Publish.MESSAGE_TYPE, publish.request, ApplicationError.INVALID_URI, ["publish with invalid topic URI '{0}'".format(publish.topic)])
session._transport.send(reply)
return
if publish.topic in self._topic_to_sessions or publish.acknowledge:
## validate payload
##
try:
self._router.validate('event', publish.topic, publish.args, publish.kwargs)
except Exception as e:
reply = message.Error(message.Publish.MESSAGE_TYPE, publish.request, ApplicationError.INVALID_ARGUMENT, ["publish to topic URI '{0}' with invalid application payload: {1}".format(publish.topic, e)])
session._transport.send(reply)
return
## authorize action
##
d = self._as_future(self._router.authorize, session, publish.topic, IRouter.ACTION_PUBLISH)
def on_authorize_success(authorized):
if not authorized:
if publish.acknowledge:
reply = message.Error(message.Publish.MESSAGE_TYPE, publish.request, ApplicationError.NOT_AUTHORIZED, ["session not authorized to publish to topic '{0}'".format(publish.topic)])
session._transport.send(reply)
else:
"""
Get a component currently running within this container.
:param component_id: The ID of the component to get.
:type component_id: str
:param details: Caller details.
:type details: instance of :class:`autobahn.wamp.types.CallDetails`
:returns: Component detail information.
:rtype: dict
"""
self.log.debug('{klass}.get_component({component_id}, {details})', klass=self.__class__.__name__, component_id=component_id, details=details)
if component_id not in self.components:
raise ApplicationError('crossbar.error.no_such_object', 'no component with ID {} running in this container'.format(component_id))
return self.components[component_id].marshal()
# now that we have the data encryption key, decrypt the application payload
# the decryption key here is an instance of nacl.secret.SecretBox
try:
message = self._keys[key_id].decrypt(ciphertext)
except nacl.exceptions.CryptoError as e:
# Decryption failed. Ciphertext failed verification
raise ApplicationError('xbr.error.decryption_failed', '{}.unwrap() - failed to unwrap encrypted data: {}'.format(self.__class__.__name__, e))
# deserialize the application payload
# FIXME: support more app payload serializers
try:
payload = cbor2.loads(message)
except cbor2.decoder.CBORDecodeError as e:
# premature end of stream (expected to read 4187 bytes, got 27 instead)
raise ApplicationError('xbr.error.deserialization_failed', '{}.unwrap() - failed to deserialize application payload: {}'.format(self.__class__.__name__, e))
return payload
:type msg: instance of :class:`autobahn.wamp.message.Error`
"""
# FIXME:
# 1. map to ecls based on error URI wildcard/prefix
# 2. extract additional args/kwargs from error URI
exc = None
enc_err = None
if msg.enc_algo:
if not self._payload_codec:
log_msg = u"received encoded payload, but no payload codec active"
self.log.warn(log_msg)
enc_err = ApplicationError(ApplicationError.ENC_NO_PAYLOAD_CODEC, log_msg, enc_algo=msg.enc_algo)
else:
try:
encoded_payload = EncodedPayload(msg.payload, msg.enc_algo, msg.enc_serializer, msg.enc_key)
decrypted_error, msg.args, msg.kwargs = self._payload_codec.decode(True, msg.error, encoded_payload)
except Exception as e:
self.log.warn("failed to decrypt application payload 1: {err}", err=e)
enc_err = ApplicationError(
ApplicationError.ENC_DECRYPT_ERROR,
u"failed to decrypt application payload 1: {}".format(e),
enc_algo=msg.enc_algo,
)
else:
if msg.error != decrypted_error:
self.log.warn(
u"URI within encrypted payload ('{decrypted_error}') does not match the envelope ('{error}')",
decrypted_error=decrypted_error,
if not subscriber:
raise ApplicationError(
ApplicationError.NO_SUCH_SESSION,
message='no session with ID {} exists on this router'.format(subscriber_id),
)
subscription = self._router._broker._subscription_map.get_observation_by_id(subscription_id)
if subscription:
if is_protected_uri(subscription.uri, details):
raise ApplicationError(
ApplicationError.NOT_AUTHORIZED,
message='not authorized to remove subscriber for protected URI "{}"'.format(subscription.uri),
)
if subscriber not in subscription.observers:
raise ApplicationError(
ApplicationError.NO_SUCH_SUBSCRIPTION,
'session {} is not subscribed on subscription {} on this broker'.format(subscriber_id, subscription_id),
)
self._router._broker.removeSubscriber(subscription, subscriber, reason=reason)
else:
raise ApplicationError(
ApplicationError.NO_SUCH_SUBSCRIPTION,
'no subscription with ID {} exists on this broker'.format(subscription_id),
)