def test_connect_no_auth_method(self, fake_sleep): endpoint = Mock() directlyProvides(endpoint, IStreamClientEndpoint) component = Component( transports={ "type": "websocket", "url": "ws://127.0.0.1/ws", "endpoint": endpoint, }, is_fatal=lambda e: True, ) def connect(factory, **kw): proto = factory.buildProtocol('boom') proto.makeConnection(Mock()) from autobahn.websocket.protocol import WebSocketProtocol from base64 import b64encode from hashlib import sha1 key = proto.websocket_key + WebSocketProtocol._WS_MAGIC proto.data = ( b"HTTP/1.1 101 Switching Protocols\x0d\x0a" b"Upgrade: websocket\x0d\x0a" b"Connection: upgrade\x0d\x0a" b"Sec-Websocket-Protocol: wamp.2.json\x0d\x0a" b"Sec-Websocket-Accept: " + b64encode(sha1(key).digest()) + b"\x0d\x0a\x0d\x0a" ) proto.processHandshake() from autobahn.wamp import role subrole = role.RoleSubscriberFeatures() msg = Hello(u"realm", roles=dict(subscriber=subrole), authmethods=[u"anonymous"]) serializer = JsonSerializer() data, is_binary = serializer.serialize(msg) proto.onMessage(data, is_binary) msg = Abort(reason=u"wamp.error.no_auth_method") proto.onMessage(*serializer.serialize(msg)) proto.onClose(False, 100, u"wamp.error.no_auth_method") return succeed(proto) endpoint.connect = connect # XXX it would actually be nicer if we *could* support # passing a reactor in here, but the _batched_timer = # make_batched_timer() stuff (slash txaio in general) # makes this "hard". reactor = Clock() with replace_loop(reactor): with self.assertRaises(RuntimeError) as ctx: d = component.start(reactor=reactor) # make sure we fire all our time-outs reactor.advance(3600) yield d self.assertIn( "Exhausted all transport", str(ctx.exception) )
def test_reconnect_on_handshake_timeout(request, temp_dir, crossbar, reactor, virtualenv): """ """ comp = Component(transports=[{ "type": "websocket", "url": "ws://localhost:6565/ws", "max_retries": 2, "options": { "open_handshake_timeout": .1, } }]) errors = [] @comp.on_connectfailure def error(component, e): errors.append(e) @comp.on_join def joined(session, details): import time time.sleep(2.0) print(f"joined: {session} {details}") @comp.on_leave def left(session, reason): print(f"left: {session} {reason}") try: yield comp.start() except Exception as e: # will fail, because can't connect print(e)
def test_cancel(self, fake_sleep): """ if we start a component but call .stop before it connects, ever, it should still exit properly """ endpoint = Mock() directlyProvides(endpoint, IStreamClientEndpoint) component = Component( transports={ "type": "websocket", "url": "ws://127.0.0.1/ws", "endpoint": endpoint, }) def connect(factory, **kw): return Deferred() endpoint.connect = connect # XXX it would actually be nicer if we *could* support # passing a reactor in here, but the _batched_timer = # make_batched_timer() stuff (slash txaio in general) # makes this "hard". reactor = Clock() with replace_loop(reactor): d = component.start(reactor=reactor) component.stop() yield d
def __init__(self, app, config): self.app = app self.wamp_session = None self.wamp_comp = Component(transports=config['router'], realm=config['realm']) self.wamp_comp.on('join', self.initialize) self.wamp_comp.on('leave', self.uninitialize)
def test_connect_no_auth_method(self, fake_sleep): endpoint = Mock() directlyProvides(endpoint, IStreamClientEndpoint) component = Component( transports={ "type": "websocket", "url": "ws://127.0.0.1/ws", "endpoint": endpoint, }, is_fatal=lambda e: True, ) def connect(factory, **kw): proto = factory.buildProtocol('boom') proto.makeConnection(Mock()) from autobahn.websocket.protocol import WebSocketProtocol from base64 import b64encode from hashlib import sha1 key = proto.websocket_key + WebSocketProtocol._WS_MAGIC proto.data = (b"HTTP/1.1 101 Switching Protocols\x0d\x0a" b"Upgrade: websocket\x0d\x0a" b"Connection: upgrade\x0d\x0a" b"Sec-Websocket-Protocol: wamp.2.json\x0d\x0a" b"Sec-Websocket-Accept: " + b64encode(sha1(key).digest()) + b"\x0d\x0a\x0d\x0a") proto.processHandshake() from autobahn.wamp import role subrole = role.RoleSubscriberFeatures() msg = Hello("realm", roles=dict(subscriber=subrole), authmethods=["anonymous"]) serializer = JsonSerializer() data, is_binary = serializer.serialize(msg) proto.onMessage(data, is_binary) msg = Abort(reason="wamp.error.no_auth_method") proto.onMessage(*serializer.serialize(msg)) proto.onClose(False, 100, "wamp.error.no_auth_method") return succeed(proto) endpoint.connect = connect # XXX it would actually be nicer if we *could* support # passing a reactor in here, but the _batched_timer = # make_batched_timer() stuff (slash txaio in general) # makes this "hard". reactor = Clock() with replace_loop(reactor): with self.assertRaises(RuntimeError) as ctx: d = component.start(reactor=reactor) # make sure we fire all our time-outs reactor.advance(3600) yield d self.assertIn("Exhausted all transport", str(ctx.exception))
def test_component_wrong_auth(reactor, component_crossbar): """ a component connects which can't authenticate; should get errors """ def main(reactor, session): assert False, "should not have joined the session" component = Component( transports=[ { u"url": u"ws://localhost:7171/auth_ws", u"endpoint": { u"type": u"tcp", u"host": u"localhost", u"port": 7171, }, u"max_retries": 1, }, ], authentication={ u"anonymous": {}, }, realm=u"auth_realm", main=main, ) try: yield component.start(reactor) assert False, "should fail" except Exception as e: assert "Exhausted all transport connect attempts" in str(e)
def test_component_cryptosign_auth(reactor, component_crossbar): joined = Deferred() def main(reactor, session): joined.callback(session) return session.leave() component = Component( transports=[ { u"url": u"ws://*****:*****@example.com", u"authrole": u"authenticated", } }, realm=u"auth_realm", main=main, ) yield component.start(reactor) yield joined
def test_cancel(self, fake_sleep): """ if we start a component but call .stop before it connects, ever, it should still exit properly """ endpoint = Mock() directlyProvides(endpoint, IStreamClientEndpoint) component = Component( transports={ "type": "websocket", "url": "ws://127.0.0.1/ws", "endpoint": endpoint, } ) def connect(factory, **kw): return Deferred() endpoint.connect = connect # XXX it would actually be nicer if we *could* support # passing a reactor in here, but the _batched_timer = # make_batched_timer() stuff (slash txaio in general) # makes this "hard". reactor = Clock() with replace_loop(reactor): d = component.start(reactor=reactor) component.stop() yield d
class WAMPApplication: def __init__(self, app, config): self.app = app self.wamp_session = None self.wamp_comp = Component(transports=config['router'], realm=config['realm']) self.wamp_comp.on('join', self.initialize) self.wamp_comp.on('leave', self.uninitialize) @to_deferred async def initialize(self, session, details): logger.info("Connected to WAMP router") self.wamp_session = session await session.register(self.app.list_units, 'sjw.list_units') await session.register(self.app.query, 'sjw.query') await session.register(self.app.start, 'sjw.start') await session.register(self.app.stop, 'sjw.stop') await session.register(self.app.enable, 'sjw.enable') await session.register(self.app.disable, 'sjw.disable') def uninitialize(self, session, reason): logger.info("%s %s", session, reason) logger.info("Lost WAMP connection") self.wamp_session = None def on_unit_changed(self, unit, props): if not self.wamp_session: return self.wamp_session.publish('sjw.unit.' + unit, props) @to_deferred async def start(self, reactor=None): logger.info("Starting component") return (await self.wamp_comp.start(reactor))
def test_successful_proxy_connect(self, fake_sleep): endpoint = Mock() directlyProvides(endpoint, IStreamClientEndpoint) component = Component( transports={ "type": "websocket", "url": "ws://127.0.0.1/ws", "endpoint": endpoint, "proxy": { "host": "10.0.0.0", "port": 65000, }, "max_retries": 0, }, is_fatal=lambda _: True, ) @component.on_join def joined(session, details): return session.leave() def connect(factory, **kw): return succeed(Mock()) endpoint.connect = connect # XXX it would actually be nicer if we *could* support # passing a reactor in here, but the _batched_timer = # make_batched_timer() stuff (slash txaio in general) # makes this "hard". reactor = Clock() got_proxy_connect = Deferred() def _tcp(host, port, factory, **kw): self.assertEqual("10.0.0.0", host) self.assertEqual(port, 65000) got_proxy_connect.callback(None) return endpoint.connect(factory._wrappedFactory) reactor.connectTCP = _tcp with replace_loop(reactor): d = component.start(reactor=reactor) def done(x): if not got_proxy_connect.called: got_proxy_connect.callback(x) # make sure we fire all our time-outs d.addCallbacks(done, done) reactor.advance(3600) return got_proxy_connect
def test_successful_proxy_connect(self, fake_sleep): endpoint = Mock() directlyProvides(endpoint, IStreamClientEndpoint) component = Component( transports={ u"type": u"websocket", u"url": u"ws://127.0.0.1/ws", u"endpoint": endpoint, u"proxy": { u"host": u"10.0.0.0", u"port": 65000, }, u"max_retries": 0, }, is_fatal=lambda _: True, ) @component.on_join def joined(session, details): return session.leave() def connect(factory, **kw): return succeed(Mock()) endpoint.connect = connect # XXX it would actually be nicer if we *could* support # passing a reactor in here, but the _batched_timer = # make_batched_timer() stuff (slash txaio in general) # makes this "hard". reactor = Clock() got_proxy_connect = Deferred() def _tcp(host, port, factory, **kw): self.assertEqual("10.0.0.0", host) self.assertEqual(port, 65000) got_proxy_connect.callback(None) return endpoint.connect(factory._wrappedFactory) reactor.connectTCP = _tcp with replace_loop(reactor): d = component.start(reactor=reactor) def done(x): if not got_proxy_connect.called: got_proxy_connect.callback(x) # make sure we fire all our time-outs d.addCallbacks(done, done) reactor.advance(3600) return got_proxy_connect
def test_invalid_serializer(self): with self.assertRaises(ValueError) as ctx: Component(transports=[{ "url": "ws://127.0.0.1/ws", "serializers": ["quux"], }]) self.assertIn("Invalid serializer", str(ctx.exception))
def test_invalid_serializer_type_1(self): with self.assertRaises(ValueError) as ctx: Component(transports=[{ "url": "ws://127.0.0.1/ws", "serializers": 1, }]) self.assertIn("must be a list", str(ctx.exception))
def test_verification_fails(reactor, crypto_crossbar, request, self_signed_cert): """ TLS fails to a self-signed cert """ tls_client = Component( transports=u"wss://localhost:6464/tls_ws", is_fatal=lambda _: True, ) d = tls_client.start(reactor) try: session = yield d assert False, "Connection should fail due to certificate error" except Exception as e: print("failed (we wanted this): {}".format(e))
def _create_component(options): """ Configure and return a Component instance according to the given `options` """ if options.url.startswith('ws://'): kind = 'websocket' elif options.url.startswith('rs://'): kind = 'rawsocket' else: raise ValueError("URL should start with ws:// or rs://") authentication = dict() if options.private_key: if not options.authid: raise ValueError( "Require --authid and --authrole if --private-key (or WAMP_PRIVATE_KEY) is provided" ) authentication["cryptosign"] = { "authid": options.authid, "authrole": options.authrole, "privkey": options.private_key, } return Component( transports=[{ "type": kind, "url": options.url, }], authentication=authentication if authentication else None, realm=options.realm, )
def test_no_url(self): with self.assertRaises(ValueError) as ctx: Component(main=lambda r, s: None, transports=[{ "type": "websocket", }]) self.assertIn("Transport requires 'url'", str(ctx.exception))
def test_invalid_type_key(self): with self.assertRaises(ValueError) as ctx: Component(main=lambda r, s: None, transports=[{ "type": "bad", }]) self.assertIn("Invalid transport type", str(ctx.exception))
def test_invalid_key(self): with self.assertRaises(ValueError) as ctx: Component( transports=dict( foo='bar', # totally invalid key ), ) self.assertIn("'foo' is not", str(ctx.exception))
class ConnectionHandler(object): def __init__(self): self.logger = logging.getLogger("Connection Handler") self.rie = None self.session_observers = Observable() self.session = None @inlineCallbacks def on_connect(self, session, details=None): self.logger.debug("Created session: {}".format(session)) self.session = session yield self.session_observers.notify_all(session) def start_rie_session(self, robot_name=None, robot_realm=None): try: if robot_realm is None: # get the realm from config name_key = "pepper" if robot_name is None else robot_name.lower( ) robot_realm = config_helper.get_robot_settings( )["realm"][name_key] self.logger.info("{} REALM: {}".format(robot_name, robot_realm)) self.rie = Component(transports=[{ 'url': u"wss://wamp.robotsindeklas.nl", 'serializers': ['msgpack'], 'max_retries': 0 }], realm=robot_realm) self.logger.info("** {}".format(threading.current_thread().name)) self.rie.on_join(self.on_connect) self.logger.info("Running the rie component") run([self.rie]) except Exception as e: self.logger.error("Unable to run the rie component | {}".format(e)) def stop_session(self): try: if self.session: self.session.leave() self.session_observers.notify_all(None) self.logger.info("Closed the robot session.") else: self.logger.info("There is no active session.") except Exception as e: self.logger.error("Error while closing rie session: {}".format(e))
def test_invalid_key_transport_list(self): with self.assertRaises(ValueError) as ctx: Component(transports=[ dict(type='websocket', url='ws://127.0.0.1/ws'), dict(foo='bar'), # totally invalid key ]) self.assertIn("'foo' is not a valid configuration item", str(ctx.exception))
def test_invalid_serializer_key(self): with self.assertRaises(ValueError) as ctx: Component(main=lambda r, s: None, transports=[{ "url": "ws://127.0.0.1/ws", "serializer": ["quux"], }]) self.assertIn("only for rawsocket", str(ctx.exception))
def test_invalid_type(self): with self.assertRaises(ValueError) as ctx: Component( transports=[ "foo" ] ) self.assertIn("must be a dict", str(ctx.exception))
def test_endpoint_bogus_object(self): with self.assertRaises(ValueError) as ctx: Component(main=lambda r, s: None, transports=[{ "type": "websocket", "url": "ws://example.com/ws", "endpoint": ("not", "a", "dict"), }]) self.assertIn("'endpoint' configuration must be", str(ctx.exception))
def test_cancel_while_waiting(self): """ if we start a component but call .stop before it connects, ever, it should still exit properly -- even if we're 'between' connection attempts """ endpoint = Mock() directlyProvides(endpoint, IStreamClientEndpoint) component = Component( transports={ "type": "websocket", "url": "ws://127.0.0.1/ws", "endpoint": endpoint, u"max_retries": 0, u"max_retry_delay": 5, u"initial_retry_delay": 5, }, ) # XXX it would actually be nicer if we *could* support # passing a reactor in here, but the _batched_timer = # make_batched_timer() stuff (slash txaio in general) # makes this "hard". reactor = Clock() with replace_loop(reactor): def connect(factory, **kw): d = Deferred() reactor.callLater(10, d.errback(RuntimeError("no connect for you"))) return d endpoint.connect = connect d0 = component.start(reactor=reactor) assert component._delay_f is not None assert not component._done_f.called d1 = component.stop() assert component._done_f is None assert d0.called yield d1 yield d0
def test_cancel_while_waiting(self): """ if we start a component but call .stop before it connects, ever, it should still exit properly -- even if we're 'between' connection attempts """ endpoint = Mock() directlyProvides(endpoint, IStreamClientEndpoint) component = Component(transports={ "type": "websocket", "url": "ws://127.0.0.1/ws", "endpoint": endpoint, "max_retries": 0, "max_retry_delay": 5, "initial_retry_delay": 5, }, ) # XXX it would actually be nicer if we *could* support # passing a reactor in here, but the _batched_timer = # make_batched_timer() stuff (slash txaio in general) # makes this "hard". reactor = Clock() with replace_loop(reactor): def connect(factory, **kw): d = Deferred() reactor.callLater( 10, d.errback(RuntimeError("no connect for yo"))) return d endpoint.connect = connect d0 = component.start(reactor=reactor) assert component._delay_f is not None assert not component._done_f.called d1 = component.stop() assert component._done_f is None assert d0.called yield d1 yield d0
def test_endpoint_valid(self): Component(main=lambda r, s: None, transports=[{ "type": "websocket", "url": "ws://example.com/ws", "endpoint": { "type": "tcp", "host": "1.2.3.4", "port": "4321", } }])
def main(reactor, teste): wsurl = u"ws://localhost/ws" if acesso_remoto: wsurl = u"ws://201.131.170.231:8080/ws" # wsurl = u"ws://192.168.1.70/ws" print('host:', wsurl) # configuração do cliente WAMP component = Component( transports=[ { u"url": wsurl, # you can set various websocket options here if you want u"max_retries": -1, u"initial_retry_delay": 5, u"options": { u"open_handshake_timeout": 30, } }, ], realm=u"realm1", authentication={u"wampcra": { u"authid": u"raspi", u"secret": "1234" }}) # When not using run() we also must start logging ourselves. import txaio txaio.start_logging(level='info') # cria app principal controller = app.Controlraspi(component, reactor, teste=teste) # we don't *have* to hand over control of the reactor to # component.run -- if we don't want to, we call .start() # The Deferred it returns fires when the component is "completed" # (or errbacks on any problems). comp_d = controller._wamp.start(reactor) # If the Component raises an exception we want to exit. Note that # things like failing to connect will be swallowed by the # re-connection mechanisms already so won't reach here. def _failed(f): print("Component failed: {}".format(f)) done.errback(f) comp_d.addErrback(_failed) # wait forever (unless the Component raises an error) done = Deferred() yield done
def assemble(): transport = { "type": "rawsocket", "url": "ws://localhost/ws", "endpoint": UNIXClientEndpoint(reactor, sock_path), "serializer": "cbor", } component = Component(transports=[transport], realm="deskconn", session_factory=GPIOComponent) component._transports[0].max_retries = 0 return component
def test_component_start_twice(reactor, component_crossbar): """ a component which start()s twice """ sessions = [] def main(reactor, session): sessions.append(session) return session.leave() component = Component( transports=[ { u"url": u"ws://*****:*****@example.com", u"authrole": u"authenticated", } }, realm=u"auth_realm", main=main, ) d0 = component.start(reactor) yield d0 d1 = component.start(reactor) yield d1 assert len(sessions) == 2
def start_rie_session(self, robot_name=None, robot_realm=None): try: if robot_realm is None: # get the realm from config name_key = "pepper" if robot_name is None else robot_name.lower( ) robot_realm = config_helper.get_robot_settings( )["realm"][name_key] self.logger.info("{} REALM: {}".format(robot_name, robot_realm)) self.rie = Component(transports=[{ 'url': u"wss://wamp.robotsindeklas.nl", 'serializers': ['msgpack'], 'max_retries': 0 }], realm=robot_realm) self.logger.info("** {}".format(threading.current_thread().name)) self.rie.on_join(self.on_connect) self.logger.info("Running the rie component") run([self.rie]) except Exception as e: self.logger.error("Unable to run the rie component | {}".format(e))
def get_component(): principle = DB.get_local_principle() if not principle: print("The backend is likely not running, please ensure its up.") sys.exit(1) return Component(transports="ws://localhost:5020/ws", realm=principle.realm, authentication={ "cryptosign": AuthCryptoSign(authid=principle.auth_id, authrole=principle.auth_role, privkey=principle.private_key, authextra={}) })
def main(reactor): component = Component( transports=u"ws://localhost:8080/ws", realm=u"crossbardemo", ) app = Klein() webapp = WebApplication(app, component) # have our Web site listen on 8090 site = Site(app.resource()) server_ep = TCP4ServerEndpoint(reactor, 8090) port = yield server_ep.listen(site) print("Web application on {}".format(port)) # we don't *have* to hand over control of the reactor to # component.run -- if we don't want to, we call .start() # The Deferred it returns fires when the component is "completed" # (or errbacks on any problems). comp_d = component.start(reactor) # When not using run() we also must start logging ourselves. import txaio txaio.start_logging(level='info') # If the Component raises an exception we want to exit. Note that # things like failing to connect will be swallowed by the # re-connection mechanisms already so won't reach here. def _failed(f): print("Component failed: {}".format(f)) done.errback(f) comp_d.addErrback(_failed) # wait forever (unless the Component raises an error) done = Deferred() yield done
def __init__(self, url, bot): self.__bot = bot self.__component = Component( realm=u'realm1', transports=[{ 'endpoint': { 'type': 'tcp', 'host': u'api.poloniex.com', 'port': 443, 'tls': CertificateOptions() }, 'type': 'websocket', 'url': url, 'options': { 'open_handshake_timeout': 60.0 } }] )
from twisted.internet.defer import inlineCallbacks import os import argparse import json from datetime import datetime from twisted.internet import task, reactor import time # parser = argparse.ArgumentParser(description='Devices prototype') # parser.add_argument('-i', '--id', default=1, help='DeviceId') # args = parser.parse_args() url = os.environ.get('CBURL', 'ws://localhost:8080/ws') realmvalue = os.environ.get('CBREALM', 'realm1') topic = os.environ.get('CBTOPIC', 'com.myapp.hello') component = Component(transports=url, realm=realmvalue) device_id = "1" save_session = None save_detail = None prc_call_id = 1 def schedule_work(interval): global prc_call_id time.sleep(interval) try: print(f"Call RPC id: {prc_call_id}") res = save_session.call('my.com.date', device_id, prc_call_id)
def test_successful_connect(self, fake_sleep): endpoint = Mock() joins = [] def joined(session, details): joins.append((session, details)) return session.leave() directlyProvides(endpoint, IStreamClientEndpoint) component = Component( transports={ "type": "websocket", "url": "ws://127.0.0.1/ws", "endpoint": endpoint, } ) component.on('join', joined) def connect(factory, **kw): proto = factory.buildProtocol('boom') proto.makeConnection(Mock()) from autobahn.websocket.protocol import WebSocketProtocol from base64 import b64encode from hashlib import sha1 key = proto.websocket_key + WebSocketProtocol._WS_MAGIC proto.data = ( b"HTTP/1.1 101 Switching Protocols\x0d\x0a" b"Upgrade: websocket\x0d\x0a" b"Connection: upgrade\x0d\x0a" b"Sec-Websocket-Protocol: wamp.2.json\x0d\x0a" b"Sec-Websocket-Accept: " + b64encode(sha1(key).digest()) + b"\x0d\x0a\x0d\x0a" ) proto.processHandshake() from autobahn.wamp import role features = role.RoleBrokerFeatures( publisher_identification=True, pattern_based_subscription=True, session_meta_api=True, subscription_meta_api=True, subscriber_blackwhite_listing=True, publisher_exclusion=True, subscription_revocation=True, payload_transparency=True, payload_encryption_cryptobox=True, ) msg = Welcome(123456, dict(broker=features), realm=u'realm') serializer = JsonSerializer() data, is_binary = serializer.serialize(msg) proto.onMessage(data, is_binary) msg = Goodbye() proto.onMessage(*serializer.serialize(msg)) proto.onClose(True, 100, "some old reason") return succeed(proto) endpoint.connect = connect # XXX it would actually be nicer if we *could* support # passing a reactor in here, but the _batched_timer = # make_batched_timer() stuff (slash txaio in general) # makes this "hard". reactor = Clock() with replace_loop(reactor): yield component.start(reactor=reactor) self.assertTrue(len(joins), 1) # make sure we fire all our time-outs reactor.advance(3600)