def __init__(self, hostname=None, catalogue_port=9090, clients=None, clients_config=None, dnssd_enabled=False, dnssd_instance_name=None): self._hostname = hostname if hostname is not None else _get_hostname_fallback( ) if not isinstance(self._hostname, six.string_types): raise ValueError("Invalid hostname: {}".format(self._hostname)) if isinstance(clients, list): clients = {item.protocol: item for item in clients} self._servers = {} self._clients = clients if clients else {} self._clients_config = clients_config self._catalogue_port = catalogue_port self._catalogue_server = None self._exposed_thing_set = ExposedThingSet() self._servient_lock = tornado.locks.Lock() self._is_running = False self._dnssd_enabled = dnssd_enabled if dnssd_enabled and is_dnssd_supported( ) else False self._dnssd_instance_name = dnssd_instance_name self._dnssd = None self._enabled_exposed_thing_ids = set() if not len(self._clients): self._build_default_clients()
#!/usr/bin/env python # -*- coding: utf-8 -*- """ DNS Service Discovery (based on Multicast DNS) Thing discovery service. .. autosummary:: :toctree: _dnssd wotpy.wot.discovery.dnssd.service """ from wotpy.support import is_dnssd_supported if is_dnssd_supported() is False: raise NotImplementedError("DNS-SD is not supported in this platform")
observable = wot.discover(thing_filter) subscription = observable.subscribe( on_next=lambda td_str: found.append(ThingDescription(td_str) ) or resolve()) yield future_done assert_equal_td_sequences(found, [TD_DICT_01, TD_DICT_02]) subscription.dispose() run_test_coroutine(test_coroutine) @pytest.mark.skipif(not is_dnssd_supported(), reason="Only for platforms that support DNS-SD") def test_discovery_method_multicast_dnssd(): """Things can be discovered usin the multicast method supported by DNS-SD.""" catalogue_port_01 = find_free_port() catalogue_port_02 = find_free_port() instance_name_01 = "servient-01-{}".format(Faker().pystr()) instance_name_02 = "servient-02-{}".format(Faker().pystr()) servient_01 = Servient(catalogue_port=catalogue_port_01, dnssd_enabled=True, dnssd_instance_name=instance_name_01) servient_02 = Servient(catalogue_port=catalogue_port_02,
import collections import logging import socket import pytest import tornado.gen import tornado.ioloop from faker import Faker from tests.utils import find_free_port from wotpy.support import is_dnssd_supported from wotpy.wot.servient import Servient collect_ignore = [] if not is_dnssd_supported(): logging.warning("Skipping DNS-SD tests due to unsupported platform") collect_ignore.extend(["test_service.py"]) @pytest.fixture def asyncio_zeroconf(): """Builds an aiozeroconf service instance and starts browsing for WoT Servient services. Provides a deque that contains the service state change history.""" from aiozeroconf import Zeroconf, ServiceBrowser from wotpy.wot.discovery.dnssd.service import DNSSDDiscoveryService loop = tornado.ioloop.IOLoop.current() service_history = collections.deque([])
'faker>=0.8.15,<0.9', 'Sphinx>=1.7.5,<2.0.0', 'sphinx-rtd-theme>=0.4.0,<0.5.0', 'futures>=3.1.1,<4.0.0', 'pyOpenSSL>=18.0.0,<19.0.0', 'coveralls>=1.0,<2.0', 'coverage>=5.0<6.0', 'autopep8>=1.4,<2.0', 'rope>=0.14.0,<1.0' ] if sys.version_info[0] is 3: test_requires.append("bump2version>=1.0,<2.0") if is_coap_supported(): install_requires.append('aiocoap[linkheader]==0.4a1') if is_mqtt_supported(): install_requires.append('hbmqtt>=0.9.4,<1.0') if is_dnssd_supported(): install_requires.append('zeroconf>=0.21.3,<0.22.0') test_requires.append('aiozeroconf==0.1.8') this_dir = path.abspath(path.dirname(__file__)) with open(path.join(this_dir, 'README.md')) as fh: long_description = fh.read() setup(name='wotpy', version=__version__, description= 'Python implementation of a W3C WoT Runtime and the WoT Scripting API', long_description=long_description, long_description_content_type='text/markdown', keywords='wot iot gateway fog w3c',
def _build_dnssd_discover_observable(self, thing_filter, dnssd_find_kwargs): """Builds an Observable to discover Things using the multicast method based on DNS-SD.""" if not is_dnssd_supported(): warnings.warn("Unsupported DNS-SD multicast discovery") # noinspection PyUnresolvedReferences return Observable.empty() dnssd_find_kwargs = dnssd_find_kwargs if dnssd_find_kwargs else {} if not self._servient.dnssd: # noinspection PyUnresolvedReferences return Observable.empty() def subscribe(observer): """Browses the Servient services using DNS-SD and retrieves the TDs that match the filters.""" state = {"stop": False} @handle_observer_finalization(observer) @tornado.gen.coroutine def callback(): address_port_pairs = yield self._servient.dnssd.find( **dnssd_find_kwargs) def build_pair_url(idx, path=None): addr, port = address_port_pairs[idx] base = "http://{}:{}".format(addr, port) path = path if path else '' return "{}/{}".format(base, path.strip("/")) http_client = AsyncHTTPClient() catalogue_resps = [ http_client.fetch(build_pair_url(idx)) for idx in range(len(address_port_pairs)) ] wait_iter = tornado.gen.WaitIterator(*catalogue_resps) while not wait_iter.done() and not state["stop"]: try: catalogue_resp = yield wait_iter.next() except Exception as ex: self._logr.warning( "Exception on HTTP request to TD catalogue: {}". format(ex)) else: catalogue = json.loads(catalogue_resp.body) if state["stop"]: return td_resps = yield [ http_client.fetch( build_pair_url(wait_iter.current_index, path=path)) for thing_id, path in six.iteritems(catalogue) ] tds = [ ThingDescription(td_resp.body) for td_resp in td_resps ] tds_filtered = [ td for td in tds if self._is_fragment_match(td, thing_filter) ] [observer.on_next(td.to_str()) for td in tds_filtered] def unsubscribe(): state["stop"] = True tornado.ioloop.IOLoop.current().add_callback(callback) return unsubscribe # noinspection PyUnresolvedReferences return Observable.create(subscribe)