Exemple #1
0
def create_component(config, pubsub, query_func):
    subscriber = WAMPSubscriber()
    comp = Component(
        transports=config['router'],
        realm=config['realm'],
    )
    comp.log = _TxaioLogWrapper(logger.getChild('component'))

    @comp.on_join
    async def joined(session, details):
        logger.info("Session ready! %s %s", session, details)
        subscriber.session = session
        pubsub.subscribe('', subscriber)

    @comp.on_leave
    async def left(session, details):
        pubsub.unsubscribe(subscriber)
        subscriber.session = None
        logger.info("Session left! %s %s", session, details)

    @comp.register('mtd.query')
    async def query(*metrics):
        return query_func(*metrics)

    return comp
    async def connectToNode(self):
        
        self.__logger.debug(f"Try to connect")
        
        if not self.__node.running:
            raise Exception("Cannot connect API if node is not running")
        
        if self.connected:
            return
        
        #make the OCP node connection!            
        uri = f"ws://{self.__node.apiUri}:{self.__node.apiPort}/ws"
        self.__wamp = Component(  transports={
                                    "url":uri,
                                    "serializers": ['msgpack'],
                                    "initial_retry_delay": 10
                                },
                                realm = "ocp")
        self.__wamp.on('join', self.__onJoin)
        self.__wamp.on('leave', self.__onLeave)
        self.__wamp.on('disconnect', self.__onDisconnect)
        self.__wamp.on('ready', self.__onReady)

        #run the component
        self.__wamp.start()
Exemple #3
0
    def __init__(self, transports, realm, client):
        self._component = Component(transports=transports, realm=realm)
        self._client = client
        self._component.on('join', self._join)
        self._component.on('leave', self._leave)

        self._session = None
Exemple #4
0
def main(options):
    """Main function."""
    auth = build_authentication(options)
    comp = Component(transports=[{
        'url': args.url,
        'max_retries': -1,
        'max_retry_delay': 30,
    }],
                     realm=args.realm,
                     authentication=auth,
                     extra={
                         'market_maker_adr':
                         os.environ.get(
                             'XBR_MARKET_MAKER_ADR',
                             '0x3e5e9111ae8eb78fe1cc3bb8915d5d461f3ef9a9'),
                         'seller_privkey':
                         options.privkey,
                     })

    if options.privkey is None:
        pub = WampPublisher()
    else:
        pub = SellingPublisher(options.name)

    factory = VehicleFleetFactory()
    sim_type = factory.create_simulation(options.type)
    _ = sim_type(comp, pub, options.sumo_cfg, options.name)

    run([comp])
Exemple #5
0
 def handle(self, *args, **options):
     comp = Component(
         transports="ws://crossbar:8080/ws",
         realm="realm1",
         session_factory=GPSComponent,
     )
     run([comp])
 async def _startup(self, connection):
     
     
     self.__connection = connection
     await connection.api.waitTillReady()
     
     #register ourself to the OCP node
     await connection.api.subscribe("testhandler", self.__receiveSync, "ocp.documents..content.Document.sync", options=SubscribeOptions(match="wildcard"))
     
     #connect to testserver       
     uri = os.getenv('OCP_TEST_SERVER_URI', '')
     self.test = Component(transports=uri, realm = "ocptest")
     self.test.on('join', self.__onJoin)
     self.test.on('leave', self.__onLeave)
     
     self.test.start()
Exemple #7
0
    def __init__(self):

        LOG.debug("wamp url: %s wamp realm: %s", CONF.wamp.wamp_transport_url,
                  CONF.wamp.wamp_realm)

        self.loop = asyncio.get_event_loop()
        global LOOP
        LOOP = self.loop

        comp = Component(transports=CONF.wamp.wamp_transport_url,
                         realm=CONF.wamp.wamp_realm)

        self.comp = comp

        @comp.on_join
        async def onJoin(session, details):

            global connected
            connected = True

            global wamp_session_caller, AGENT_HOST
            wamp_session_caller = session

            import iotronic.wamp.functions as fun

            session.subscribe(fun.board_on_leave, 'wamp.session.on_leave')
            session.subscribe(fun.board_on_join, 'wamp.session.on_join')

            try:
                if CONF.wamp.register_agent:
                    session.register(fun.registration,
                                     u'stack4things.register')
                    LOG.info("I have been set as registration agent")
                session.register(fun.connection,
                                 AGENT_HOST + u'.stack4things.connection')
                session.register(fun.echo, AGENT_HOST + u'.stack4things.echo')
                LOG.debug("procedure registered")

            except Exception as e:
                LOG.error("could not register procedure: {0}".format(e))

            LOG.info("WAMP session ready.")

            session_l = await session.call(u'wamp.session.list')
            session_l.remove(details.session)
            fun.update_sessions(session_l)

        @comp.on_leave
        async def onLeave(session, details):
            LOG.warning('WAMP Session Left: ' + str(details))

        @comp.on_disconnect
        async def onDisconnect(session, was_clean):
            LOG.warning('WAMP Transport Left: ' + str(was_clean))

            global connected
            connected = False
            if not connected:
                comp.start(self.loop)
Exemple #8
0
 def __init__(self, config_file):
     self.config_file = config_file
     self.config = self.load_config(self.config_file)
     self.database = DatabaseWorker(filename='db.sqlite')
     self.messages = MessageService(self.database)
     self.webapp = create_webapp(self.config['web'], self.messages)
     # WAMP
     self.channel_handlers = {}
     wamp_config = self.config['wamp']
     self.wamp_session = None
     self.wamp_comp = Component(
         transports=wamp_config['router'],
         realm=wamp_config['realm']
     )
     #self.wamp_comp.log = _TxaioLogWrapper(logger.getChild('wamp'))
     self.wamp_comp.on('join', self.initialize_wamp)
     self.wamp_comp.on('leave', self.uninitialize_wamp)
Exemple #9
0
    def __init__(self,
                 group=None,
                 target=None,
                 name=None,
                 args=(),
                 kwargs=None,
                 daemon=None) -> None:
        super().__init__(group=group,
                         target=target,
                         name=name,
                         args=args,
                         kwargs=kwargs,
                         daemon=daemon)
        self.args = args
        self.kwargs = kwargs

        def joined(session, details):
            print("session ready")
            self.mySession = session

        comp = Component(transports="ws://host.docker.internal:8090/ws",
                         realm=u"racelog.state")
        comp.on_join(joined)

        comp.start(loop=self)
Exemple #10
0
    def test_asyncio_component(event_loop):
        orig_loop = txaio.config.loop
        txaio.config.loop = event_loop

        comp = Component(
            transports=[
                {
                    "url": "ws://localhost:12/bogus",
                    "max_retries": 1,
                    "max_retry_delay": 0.1,
                }
            ]
        )

        # if having trouble, try starting some logging (and use
        # "py.test -s" to get real-time output)
        # txaio.start_logging(level="debug")
        f = comp.start(loop=event_loop)
        txaio.config.loop = event_loop
        finished = txaio.create_future()

        def fail():
            finished.set_exception(AssertionError("timed out"))
            txaio.config.loop = orig_loop
        txaio.call_later(4.0, fail)

        def done(f):
            try:
                f.result()
                finished.set_exception(AssertionError("should get an error"))
            except RuntimeError as e:
                if 'Exhausted all transport connect attempts' not in str(e):
                    finished.set_exception(AssertionError("wrong exception caught"))
            finished.set_result(None)
            txaio.config.loop = orig_loop
            assert comp._done_f is None
        f.add_done_callback(done)
        return finished
class Publisher:
    def __init__(self):
        self.component = None

    async def connect(self, crossbar_url):
        """Method used to initialize a session for the publisher

        :param crossbar_url: url hosting the crossbar instance
        """
        log.debug(f"Connecting to {crossbar_url}")

        self.component = Component(transports=crossbar_url, realm='realm1')

        loop = asyncio.get_event_loop()
        txaio.config.loop = loop

        session_ready = asyncio.Event()

        async def setup_session(created_session, _details):
            """Callback method used to retrieve a session and notify interested parties with an event"""
            self.session = created_session
            nonlocal session_ready
            session_ready.set()

        self.component.start(loop=loop)
        self.component.on_join(setup_session)

        await session_ready.wait()

    def publish(self, topic, payload):
        """Publish the payload on the specified topic

        :param topic: target topic
        :param payload: payload to be published
        """
        self.session.publish(topic, payload)
        log.debug(f"data is published to : {topic}")
    async def connect(self, crossbar_url):
        """Method used to initialize a session for the publisher

        :param crossbar_url: url hosting the crossbar instance
        """
        log.debug(f"Connecting to {crossbar_url}")

        self.component = Component(transports=crossbar_url, realm='realm1')

        loop = asyncio.get_event_loop()
        txaio.config.loop = loop

        session_ready = asyncio.Event()

        async def setup_session(created_session, _details):
            """Callback method used to retrieve a session and notify interested parties with an event"""
            self.session = created_session
            nonlocal session_ready
            session_ready.set()

        self.component.start(loop=loop)
        self.component.on_join(setup_session)

        await session_ready.wait()
Exemple #13
0
async def start(config=None, engine=None):
    loop = asyncio.get_event_loop()

    # TODO: Read this config from the config object
    component = Component(
        transports=[
            {
                "type":
                "websocket",
                "url":
                u"{}".format("{}://{}:{}/ws".format(
                    "wss" if config.get('wamp_ssl', False) else "wss",
                    config.get('wamp_host', 'localhost'),
                    config.get('wamp_port', 8080))),
                "endpoint": {
                    "type": "tcp",
                    "host": config.get('wamp_host', 'localhost'),
                    "port": config.get('wamp_port', 8080),
                },
                "options": {
                    "open_handshake_timeout": 100,
                },
                "serializers": ["json"]
            },
        ],
        realm=config.get('wamp_realm', 'realm1'),
        extra=engine,
    )

    @component.on_join
    def join(session, details):
        log.debug("Joined crossbar server")
        log.debug("Registering methods")
        for function in pygmalion.views.registrations:
            log.debug("  Registering {}".format(function['name']))
            session.register(functools.partial(function['method'], engine),
                             function['name'],
                             options=RegisterOptions(**function['options']))
        pygmalion.plugins.start(engine=engine, config=config)

    @component.on_disconnect
    def disconnect(session, was_clean):
        # This connection has died, so kill the loop and let a new one get created
        loop.stop()

    await component.start(loop)
Exemple #14
0
async def start(config=None, engine=None):
    loop = asyncio.get_event_loop()

    # TODO: Read this config from the config object
    component = Component(
        transports=[
            {
                "type": "websocket",
                "url": u"ws://localhost:8083/ws",
                "endpoint": {
                    "type": "tcp",
                    "host": "localhost",
                    "port": 8080,
                },
                "options": {
                    "open_handshake_timeout": 100,
                },
                "serializers": ["json"]
            },
        ],
        realm=u"realm1",
        extra=engine,
    )

    @component.on_join
    def join(session, details):
        log.debug("Joined crossbar server")
        log.debug("Registering methods")
        for function in orthogonalspace.views.registrations:
            log.debug("  Registering {}".format(function['name']))
            session.register(functools.partial(function['method'], engine),
                             function['name'],
                             options=RegisterOptions(**function['options']))

    @component.on_disconnect
    def disconnect(session, was_clean):
        # This connection has died, so kill the loop and let a new one get created
        loop.stop()

    await component.start(loop)
Exemple #15
0
def create_component(rpc_cert_filepath=None,
                     cli_secret_filepath=None,
                     host='localhost',
                     port=61000):
    # Mismatch golem.local - localhost
    ssl.match_hostname = lambda cert, hostname: True
    context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
    context.check_hostname = False
    context.load_verify_locations(rpc_cert_filepath)

    with open(cli_secret_filepath, 'rb') as secretf:
        wampcra_secret = secretf.read()

    component = Component(
        transports=[{
            "type": "websocket",
            "url": "wss://{host}:{port}".format(host=host, port=port),
            "max_retries": 0,
            "endpoint": {
                "host": host,
                "type": "tcp",
                "port": port,
                "tls": context
            },
            "options": {
                "open_handshake_timeout": 3,
            }
        }],
        authentication={
            u"wampcra": {
                u'authid': 'golemcli',
                u'secret': wampcra_secret
            }
        },
        realm=u"golem",
    )
    return component
Exemple #16
0
        res = yield from session.register(
            lambda: None,
            u"prefix.fail.",
            options=RegisterOptions(match=u'prefix'),
        )
        print("\n\nshould have failed\n\n")
    except ApplicationError as e:
        print("prefix-match 'prefix.fail.' failed as expected: {}".format(
            e.error))

    print("calling 'example.foo'")
    res = yield from session.call(u"example.foo")
    print("example.foo() = {}".format(res))

    print("done")


component = Component(transports=u"ws://localhost:8080/auth_ws",
                      main=main,
                      realm=u"crossbardemo",
                      authentication={
                          u"wampcra": {
                              u"authid": u"bob",
                              u"authrole": "dynamic_authed",
                              u"secret": u"p4ssw0rd",
                          }
                      })

if __name__ == "__main__":
    run([component])
Exemple #17
0
import asyncio

import psutil
import txaio
from autobahn.asyncio.component import Component, run
from speedtest import Speedtest

component_kwargs = {
    "transports": "ws://localhost:8080/ws",
    "realm": "dashboard",
}

monitor = Component(**component_kwargs)

txaio.use_asyncio()
logger = txaio.make_logger()


@monitor.on_join
async def run_speedtest(session, details):
    # Not sure why we need this but the first published result never gets picked
    # up by the subscriber.
    session.publish("speedtest")
    while True:
        s = Speedtest()
        logger.info("Starting speedtest...")
        loop = asyncio.get_event_loop()
        await loop.run_in_executor(None, s.get_best_server)
        await loop.run_in_executor(None, s.download)
        result = {
            key: s.results.dict()[key]
Exemple #18
0
component = Component(
    # you can configure multiple transports; here we use two different
    # transports which both exist in the mamoc router
    transports=[
        {
            u"type": u"websocket",
            u"url": u"ws://127.0.0.1:8080/ws",
            u"endpoint": {
                u"type": u"tcp",
                u"host": u"localhost",
                u"port": 8080,
            },
            # you can set various websocket options here if you want
            u"options": {
                u"open_handshake_timeout": 100,
            }
        },
    ],
    # authentication can also be configured (this will only work on
    # the demo router on the first transport above)
    # authentication={
    #     u"cryptosign": {
    #         u'authid': u'alice',
    #         # this key should be loaded from disk, database etc never burned into code like this...
    #         u'privkey': '6e3a302aa67d55ffc2059efeb5cf679470b37a26ae9ac18693b56ea3d0cd331c',
    #     }
    # },
    # must provide a realm
    realm=u"mamoc_realm",
)
Exemple #19
0
import asyncio
import ssl

context = ssl.create_default_context(
    purpose=ssl.Purpose.SERVER_AUTH,
    cafile='../../../router/.crossbar/server.crt',
)
component = Component(
    transports=[
        {
            "type": "websocket",
            "url": u"wss://localhost:8083/ws",
            "endpoint": {
                "type": "tcp",
                "host": "localhost",
                "port": 8083,
                "tls": context,
            },
            "options": {
                "open_handshake_timeout": 100,
            }
        },
    ],
    realm=u"crossbardemo",
)


@component.on_join
def join(session, details):
    print("joined {}".format(details))

Exemple #20
0
                    type=str,
                    help="wamp router address, default localhost")

args = parser.parse_args()
address = args.address if args.address else "localhost"
print(address)

component = Component(
    transports=[
        {
            "type": "websocket",
            "url": f"ws://{address}:9002/",
            "endpoint": {
                "type": "tcp",
                "host": f"{address}",
                "port": 9002,
            },
            "options": {
                "open_handshake_timeout": 100,
            }
        },
    ],
    realm="apartment",
)


@component.on_join
async def join(session, details):
    def event_handler(event):
        print(f"Got event {event}")
Exemple #21
0
    async def onJoin(self, details):
        print('Call test_echo_payload')
        loop = asyncio.get_running_loop()
        loop.create_task(self.test_echo_payload())

    async def onDisconnect(self):
        loop  = asyncio.get_event_loop()
        loop.stop()

    async def test_echo_payload(self):
        message_bytes = b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10'
        ret = await self.call('test.echo.payload', message_bytes)
        print("Received response:", ret)


if __name__ == '__main__':
    client = Component(
            session_factory = Client,
            transports      = [
                {
                    'type':        'websocket',
                    'serializers': ['msgpack'],
                    'url':         'ws://localhost:8080/ws',
                    'max_retries': 3
                }
            ]
        )

    run([client])
Exemple #22
0
import paho.mqtt.client as mqtt  # pip install paho-mqtt
import ssl
import json
import math
import struct
from autobahn.asyncio.component import Component
from autobahn.asyncio.component import run
from asyncio import sleep

# WAMP

wamp_session = None
alarm_timer = None

wamp_component = Component(
    transports=u"ws://localhost:8080/ws",
    realm=u"realm1",
)


@wamp_component.on_join
async def joined(session, details):
    global wamp_session
    print("WAMP connected")
    wamp_session = session


# MQTT
server = "mioty-summercamp.iis.fraunhofer.de"
username = "******"
password = "******"
path = 'mioty/+/+/uplink'
from autobahn.asyncio.component import Component, run
import asyncio

from config import config


class FakeFrontendComponent:
    @classmethod
    def run(cls):
        print(f"Starting {cls.__name__}...")

        run([component])


component = Component(
    transports=f"ws://{config['crossbar']['host']}:{config['crossbar']['port']}/ws",
    realm=config["crossbar"]["realm"]
)


@component.subscribe(topic=config["crossbar"]["topics"]["temperature"])
def on_temperature_change(new_temperature):
    print(f"Current temperature: {new_temperature}")


@component.on_join
async def join(session, details):
    print("Successfully connected to Crossbar router")

    while True:
        results = await session.call(config["crossbar"]["endpoints"]["current_state"])
        print(results)
Exemple #24
0
from autobahn.asyncio.component import Component, run

from .controller import Controller

COMPONENT = Component(transports="ws://localhost:8081/ws", realm="realm1")
CONTROLLER = Controller(COMPONENT)

run([COMPONENT])
Exemple #25
0
from .constants import COURSES_DICT, ALLOW_LANGUAGE
from .tables_db import (
    session,
    Contests,
    UserSessions,
    Problems,
    ContestProblems,
    Groups,
    Users,
    UserGroup,
    ContestUsers,
)


comp = Component()


async def check_dsid(dsid, author_id=None):
    print(f'Checking role for Author: {author_id}')
    user_session = session.query(UserSessions).filter(UserSessions.session_id == dsid).first()
    print(f'check dsid: user_session -- {user_session}')
    if not author_id:
        author_id = user_session.session_data.split('uid|i:')[1].split(';')[0]
        author = session.query(Users).filter(Users.user_id == author_id).first().FIO
        print(f'author: {author}')
        return (author_id, author)
    elif (author_id == user_session.session_data.split('uid|i:')[1].split(';')[0]
        and session.query(Users).filter(Users.user_id == author_id).first().access >= 65534):
        return author_id
    return None
# In[ ]:


from autobahn.asyncio.component import Component, run
from autobahn.wamp.types import RegisterOptions

import asyncio


component = Component(
    transports=[
        {
            "type": "websocket",
            "url": "ws://crossbar:8080/ws",
            "endpoint": {
                "type": "tcp",
                "host": "crossbar",
                "port": 8080
            }
        },
    ],
    realm="realm1",
)


async def add2(x, y, details):
    print("add2(x={}, y={}, details={})".format(x, y, details))
    return x + y


@component.on_join
async def join(session, details):
def create_component(args, extra):

    log = txaio.make_logger()

    # 'transports' can also be a list of dicts containing more
    # detailed connection information (and multiple ways to connect)
    client = Component(
        transports=args.url,
        realm=args.realm,
        extra=extra,
        authentication={
            "anonymous": {
                "authrole": "anonymous",
            },
        }
    )

    info = {
        "ident": "unknown",
        "type": "Python",
    }

    @client.on_connect
    def connected(session, x):
        log.info("Client connected: {klass}, {extra}", klass=session.__class__, extra=session.config.extra)

    @client.on_join
    async def joined(session, details):
        log.info("Joined: {details}", details=details)

        info["ident"] = details.authid

        log.info("Component ID is  {ident}", **info)
        log.info("Component type is  {type}", **info)

        # this could go in a "main" procedure to be passed to
        # Component, declared as "def main(reactor, session):" and
        # passed to Component() via "main="
        x = 0
        counter = 0
        while True:

            # CALL
            try:
                res = await session.call(u'com.example.add2', x, 3)
                print('----------------------------')
                log.info("add2 result: {result}", result=res[0])
                log.info("from component {id} ({type})", id=res[1], type=res[2])
                x += 1
            except ApplicationError as e:
                # ignore errors due to the frontend not yet having
                # registered the procedure we would like to call
                if e.error != 'wamp.error.no_such_procedure':
                    raise e

            # PUBLISH
            # (we only have to 'await' publish() if we asked for an acknowledge)
            session.publish(u'com.example.oncounter', counter, info["ident"], info["type"])
            print('----------------------------')
            log.info("published to 'oncounter' with counter {counter}",
                     counter=counter)
            counter += 1

            await sleep(2)  # note this is an "async sleep" using callLater()

    @client.register(
        "com.example.add2",
        options=RegisterOptions(invoke=u'roundrobin'),
    )
    def add2(a, b):
        print('----------------------------')
        print("add2 called on {}".format(info["ident"]))
        return [ a + b, info["ident"], info["type"]]


    @client.subscribe("com.example.oncounter")
    def oncounter(counter, ident, kind):
        print('----------------------------')
        log.info("'oncounter' event, counter value: {counter}", counter=counter)
        log.info("from component {ident} ({kind})", ident=ident, kind=kind)

    @client.on_leave
    def left(session, details):
        log.info("session left: {}".format(details))

    return client
Exemple #28
0
            print("Successfully paired with server\n")
            print("Public key: {}".format(public_key_hex))
            print("Private key: {}\n".format(private_key_hex))
            if os.path.exists(KEYS_FILE):
                Path(KEYS_FILE).unlink()
            with open(KEYS_FILE, 'w+') as file:
                file.write("{}\n".format(public_key_hex))
                file.write("{}".format(private_key_hex))
            print("Keys are save in {}".format(KEYS_FILE))
        else:
            print("Invalid OTP")
        session.leave()


if __name__ == '__main__':
    parser = argparse.ArgumentParser("DeskConnD pairing")
    parser.add_argument("otp", type=int)
    args = parser.parse_args()

    key = PrivateKey.generate()
    signing_key = SigningKey.from_key_bytes(key.encode())
    public_key_hex = signing_key.public_key()
    private_key_hex = key.encode(HexEncoder).decode('ascii')

    auth = AuthAnonymous(authrole='anonymous')
    component = Component(transports="ws://localhost:5020/ws",
                          realm="deskconn",
                          authentication={"anonymous": auth})
    main()
    run(component, log_level='warn')
Exemple #29
0
    def test_asyncio_component_404(event_loop):
        """
        If something connects but then gets aborted, it should still try
        to re-connect (in real cases this could be e.g. wrong path,
        TLS failure, WebSocket handshake failure, etc)
        """
        orig_loop = txaio.config.loop
        txaio.config.loop = event_loop

        class FakeTransport(object):
            def close(self):
                pass

            def write(self, data):
                pass

        fake_transport = FakeTransport()
        actual_protocol = [None]  # set in a closure below

        def create_connection(protocol_factory=None, server_hostname=None, host=None, port=None, ssl=False):
            if actual_protocol[0] is None:
                protocol = protocol_factory()
                actual_protocol[0] = protocol
                protocol.connection_made(fake_transport)
                return txaio.create_future_success((fake_transport, protocol))
            else:
                return txaio.create_future_error(RuntimeError("second connection fails completely"))

        with mock.patch.object(event_loop, 'create_connection', create_connection):
            event_loop.create_connection = create_connection

            comp = Component(
                transports=[
                    {
                        "url": "ws://localhost:12/bogus",
                        "max_retries": 1,
                        "max_retry_delay": 0.1,
                    }
                ]
            )

            # if having trouble, try starting some logging (and use
            # "py.test -s" to get real-time output)
            # txaio.start_logging(level="debug")
            f = comp.start(loop=event_loop)
            txaio.config.loop = event_loop

            # now that we've started connecting, we *should* be able
            # to connetion_lost our transport .. but we do a
            # call-later to ensure we're after the setup stuff in the
            # event-loop (because asyncio doesn't synchronously
            # process already-completed Futures like Twisted does)

            def nuke_transport():
                actual_protocol[0].connection_lost(None)  # asyncio can call this with None
            txaio.call_later(0.1, nuke_transport)

            finished = txaio.create_future()

            def fail():
                finished.set_exception(AssertionError("timed out"))
                txaio.config.loop = orig_loop
            txaio.call_later(1.0, fail)

            def done(f):
                try:
                    f.result()
                    finished.set_exception(AssertionError("should get an error"))
                except RuntimeError as e:
                    if 'Exhausted all transport connect attempts' not in str(e):
                        finished.set_exception(AssertionError("wrong exception caught"))
                finished.set_result(None)
                txaio.config.loop = orig_loop
            f.add_done_callback(done)
            return finished
Exemple #30
0
class ComponentBase(object):
    """A base class for WAMP components

    This class provides a template to turn an asynchronous Modbus client into a
    WAMP client using the Autobahn package. Provided you have an API client
    derived from  :class:`modbusclient.asyncio.ApiWrapper`, you can use this
    class as base class for your WAMP client and provice the API client
    as `client` argument. This avoids the repetition of some boiler plate code.

    Arguments:
        transports (list or str): Passed verbatim to
            :class:`autobahn.asyncio.component.Component` as `transports`.
        realm (str): WAMP realm. Passed verbatim to
            :class:`autobahn.asyncio.component.Component` as `realm`.
        client (:class:`modbusclient.asyncio.ApiWrapper`): An implementation of
            an API wrapper.

    Attributes:
        component (:class:`autobahn.asyncio.component.Component`): Autobahn
            WAMP component wrapped by this class
        session (:class:`autobahn.wamp.protocol.ApplicationSession`): Session
            passed during on_join. ``None`` if client has not joined any session.
    """
    def __init__(self, transports, realm, client):
        self._component = Component(transports=transports, realm=realm)
        self._client = client
        self._component.on('join', self._join)
        self._component.on('leave', self._leave)

        self._session = None

    @property
    def component(self):
        """Get component wrapped by this instance

        Return:
            :class:`autobahn.asyncio.component.Component`: Autobahn
            WAMP component wrapped by this class
        """
        return self._component

    @property
    def session(self):
        """Get currently joined session

        Return:
            :class:`autobahn.wamp.protocol.ApplicationSession`: Session passed
                during on_join. ``None`` if client is currently not joined to
                any session.
        """
        return self._session

    async def _join(self, session, details):
        """Call back invoked when joining (on_join)

        Sets the internal session member variable and prints an info message.

        Arguments:
            session (:class:`autobahn.wamp.protocol.ApplicationSession`):
                Application session.
            details (dict): Dictionary with details.
        """
        self._session = session
        self.info('Joined session {session}: {details}',
                  session=session,
                  details=details)

    async def _leave(self, session, reason):
        self.info("Disconnecting from session {session}. Reason: {reason}",
                  session=session,
                  reason=reason)
        self._session = None

    def debug(self, msg, **kwargs):
        """Create debug level log message

        Arguments:
            msg (str): Log message.
            **kwargs: Keyword arguments passed to message formatter
        """
        self._component.log.debug(msg, **kwargs)

    def info(self, msg, **kwargs):
        """Create info level log message

        Arguments:
            msg (str): Log message.
            **kwargs: Keyword arguments passed to message formatter
        """
        self._component.log.info(msg, **kwargs)

    def warning(self, msg, **kwargs):
        """Create warning level log message

        Arguments:
            msg (str): Log message.
            **kwargs: Keyword arguments passed to message formatter
        """
        self._component.log.warning(msg, **kwargs)

    def error(self, msg, **kwargs):
        """Create error level log message

        Arguments:
            msg (str): Log message.
            **kwargs: Keyword arguments passed to message formatter
        """
        self._component.log.error(msg, **kwargs)