diff --git a/src/tribler-core/tribler_core/components/bandwidth_accounting/bandwidth_accounting_component.py b/src/tribler-core/tribler_core/components/bandwidth_accounting/bandwidth_accounting_component.py index cc04dca4b8d..e68794d7280 100644 --- a/src/tribler-core/tribler_core/components/bandwidth_accounting/bandwidth_accounting_component.py +++ b/src/tribler-core/tribler_core/components/bandwidth_accounting/bandwidth_accounting_component.py @@ -1,10 +1,13 @@ from ipv8.peerdiscovery.discovery import RandomWalk + from ipv8_service import IPv8 + from tribler_common.simpledefs import STATEDIR_DB_DIR + from tribler_core.components.base import Component from tribler_core.components.ipv8 import Ipv8Component from tribler_core.components.reporter import ReporterComponent -from tribler_core.components.restapi import RESTComponent +from tribler_core.components.restapi import RestfulComponent from tribler_core.components.upgrade import UpgradeComponent from tribler_core.components.bandwidth_accounting.community.community import ( BandwidthAccountingCommunity, @@ -14,14 +17,13 @@ from tribler_core.restapi.rest_manager import RESTManager -class BandwidthAccountingComponent(Component): +class BandwidthAccountingComponent(RestfulComponent): community: BandwidthAccountingCommunity - _rest_manager: RESTManager _ipv8: IPv8 async def run(self): - await self.get_component(ReporterComponent) + await super().run() await self.get_component(UpgradeComponent) config = self.session.config @@ -29,9 +31,6 @@ async def run(self): self._ipv8 = ipv8_component.ipv8 peer = ipv8_component.peer - rest_component = await self.require_component(RESTComponent) - self._rest_manager = rest_component.rest_manager - if config.general.testnet or config.bandwidth_accounting.testnet: bandwidth_cls = BandwidthAccountingTestnetCommunity else: @@ -48,10 +47,9 @@ async def run(self): community.bootstrappers.append(ipv8_component.make_bootstrapper()) self.community = community - self._rest_manager.get_endpoint('trustview').bandwidth_db = community.database - self._rest_manager.get_endpoint('bandwidth').bandwidth_community = community + await self.init_endpoints(endpoints=['trustview', 'bandwidth'], + values={'bandwidth_db': community.database, 'bandwidth_community': community}) async def shutdown(self): - self._rest_manager.get_endpoint('trustview').bandwidth_db = None - self._rest_manager.get_endpoint('bandwidth').bandwidth_community = None + await super().shutdown() await self._ipv8.unload_overlay(self.community) diff --git a/src/tribler-core/tribler_core/components/bandwidth_accounting/restapi/bandwidth_endpoint.py b/src/tribler-core/tribler_core/components/bandwidth_accounting/restapi/bandwidth_endpoint.py index 4aad4a56f63..60f2d168d8a 100644 --- a/src/tribler-core/tribler_core/components/bandwidth_accounting/restapi/bandwidth_endpoint.py +++ b/src/tribler-core/tribler_core/components/bandwidth_accounting/restapi/bandwidth_endpoint.py @@ -18,6 +18,7 @@ class BandwidthEndpoint(RESTEndpoint): def __init__(self): super().__init__() + self.bandwidth_db = None # added to simlify the initialization code of BandwidthAccountingComponent self.bandwidth_community = None def setup_routes(self) -> None: diff --git a/src/tribler-core/tribler_core/components/bandwidth_accounting/tests/test_bandwidth_accounting_component.py b/src/tribler-core/tribler_core/components/bandwidth_accounting/tests/test_bandwidth_accounting_component.py index 3265357b990..413b1c27e5f 100644 --- a/src/tribler-core/tribler_core/components/bandwidth_accounting/tests/test_bandwidth_accounting_component.py +++ b/src/tribler-core/tribler_core/components/bandwidth_accounting/tests/test_bandwidth_accounting_component.py @@ -12,15 +12,15 @@ async def test_bandwidth_accounting_component(tribler_config): + tribler_config.ipv8.enabled = True components = [RESTComponent(), MasterKeyComponent(), Ipv8Component(), BandwidthAccountingComponent()] session = Session(tribler_config, components) with session: - comp = BandwidthAccountingComponent.instance() - with patch.object(RESTManager, 'get_endpoint'): - await session.start() + await session.start() - assert comp.community - assert comp._rest_manager - assert comp._ipv8 + comp = BandwidthAccountingComponent.instance() + assert comp.started.is_set() and not comp.failed + assert comp.community + assert comp._ipv8 - await session.shutdown() + await session.shutdown() diff --git a/src/tribler-core/tribler_core/components/base.py b/src/tribler-core/tribler_core/components/base.py index 912ac984b75..060b9c2a432 100644 --- a/src/tribler-core/tribler_core/components/base.py +++ b/src/tribler-core/tribler_core/components/base.py @@ -186,7 +186,7 @@ async def get_component(self, dependency: Type[T]) -> Optional[T]: dep.in_use_by.add(self) return dep - async def release_component(self, dependency: Type[T]): + def release_component(self, dependency: Type[T]): dep = dependency.instance() if dep: self._release_instance(dep) diff --git a/src/tribler-core/tribler_core/components/gigachannel/gigachannel_component.py b/src/tribler-core/tribler_core/components/gigachannel/gigachannel_component.py index b7a86687bd0..eb3399745ac 100644 --- a/src/tribler-core/tribler_core/components/gigachannel/gigachannel_component.py +++ b/src/tribler-core/tribler_core/components/gigachannel/gigachannel_component.py @@ -1,25 +1,27 @@ from ipv8.peerdiscovery.discovery import RandomWalk + from ipv8_service import IPv8 + from tribler_core.components.base import Component from tribler_core.components.ipv8 import Ipv8Component from tribler_core.components.gigachannel.community.gigachannel_community import GigaChannelCommunity, \ GigaChannelTestnetCommunity from tribler_core.components.metadata_store.metadata_store_component import MetadataStoreComponent from tribler_core.components.reporter import ReporterComponent -from tribler_core.components.restapi import RESTComponent +from tribler_core.components.restapi import RestfulComponent from tribler_core.components.gigachannel.community.sync_strategy import RemovePeers from tribler_core.restapi.rest_manager import RESTManager INFINITE = -1 -class GigaChannelComponent(Component): +class GigaChannelComponent(RestfulComponent): community: GigaChannelCommunity - _rest_manager: RESTManager _ipv8: IPv8 async def run(self): + await super().run() await self.get_component(ReporterComponent) config = self.session.config @@ -29,9 +31,6 @@ async def run(self): self._ipv8 = ipv8_component.ipv8 peer = ipv8_component.peer - rest_component = await self.require_component(RESTComponent) - self._rest_manager = rest_component.rest_manager - metadata_store_component = await self.require_component(MetadataStoreComponent) giga_channel_cls = GigaChannelTestnetCommunity if config.general.testnet else GigaChannelCommunity @@ -52,14 +51,10 @@ async def run(self): community.bootstrappers.append(ipv8_component.make_bootstrapper()) - self._rest_manager.get_endpoint('remote_query').gigachannel_community = community - self._rest_manager.get_endpoint('channels').gigachannel_community = community - self._rest_manager.get_endpoint('collections').gigachannel_community = community + await self.init_endpoints(endpoints=['remote_query', 'channels', 'collections'], + values={'gigachannel_community': community}) async def shutdown(self): - self._rest_manager.get_endpoint('remote_query').gigachannel_community = None - self._rest_manager.get_endpoint('channels').gigachannel_community = None - self._rest_manager.get_endpoint('collections').gigachannel_community = None - await self.release_component(RESTComponent) + await super().shutdown() if self._ipv8: await self._ipv8.unload_overlay(self.community) diff --git a/src/tribler-core/tribler_core/components/gigachannel/tests/test_gigachannel_component.py b/src/tribler-core/tribler_core/components/gigachannel/tests/test_gigachannel_component.py index 5d9e7bd64ec..1fe5a66a6b9 100644 --- a/src/tribler-core/tribler_core/components/gigachannel/tests/test_gigachannel_component.py +++ b/src/tribler-core/tribler_core/components/gigachannel/tests/test_gigachannel_component.py @@ -13,16 +13,18 @@ async def test_giga_channel_component(tribler_config): + tribler_config.ipv8.enabled = True + tribler_config.libtorrent.enabled = True + tribler_config.chant.enabled = True components = [MetadataStoreComponent(), RESTComponent(), MasterKeyComponent(), Ipv8Component(), GigaChannelComponent()] session = Session(tribler_config, components) with session: - comp = GigaChannelComponent.instance() - with patch.object(RESTManager, 'get_endpoint'): - await session.start() + await session.start() - assert comp.community - assert comp._rest_manager - assert comp._ipv8 + comp = GigaChannelComponent.instance() + assert comp.started.is_set() and not comp.failed + assert comp.community + assert comp._ipv8 - await session.shutdown() + await session.shutdown() diff --git a/src/tribler-core/tribler_core/components/gigachannel_manager/gigachannel_manager_component.py b/src/tribler-core/tribler_core/components/gigachannel_manager/gigachannel_manager_component.py index 537fd8659eb..1e20f665522 100644 --- a/src/tribler-core/tribler_core/components/gigachannel_manager/gigachannel_manager_component.py +++ b/src/tribler-core/tribler_core/components/gigachannel_manager/gigachannel_manager_component.py @@ -2,18 +2,16 @@ from tribler_core.components.libtorrent import LibtorrentComponent from tribler_core.components.metadata_store.metadata_store_component import MetadataStoreComponent from tribler_core.components.reporter import ReporterComponent -from tribler_core.components.restapi import RESTComponent +from tribler_core.components.restapi import RestfulComponent from tribler_core.components.gigachannel_manager.gigachannel_manager import GigaChannelManager from tribler_core.restapi.rest_manager import RESTManager -class GigachannelManagerComponent(Component): +class GigachannelManagerComponent(RestfulComponent): gigachannel_manager: GigaChannelManager - _rest_manager: RESTManager - async def run(self): - await self.get_component(ReporterComponent) + await super().run() config = self.session.config notifier = self.session.notifier @@ -22,9 +20,6 @@ async def run(self): download_manager = libtorrent_component.download_manager if libtorrent_component else None metadata_store_component = await self.require_component(MetadataStoreComponent) - rest_component = await self.require_component(RESTComponent) - - self._rest_manager = rest_component.rest_manager self.gigachannel_manager = GigaChannelManager( notifier=notifier, metadata_store=metadata_store_component.mds, download_manager=download_manager @@ -32,14 +27,10 @@ async def run(self): if not config.gui_test_mode: self.gigachannel_manager.start() - self._rest_manager.get_endpoint('channels').gigachannel_manager = self.gigachannel_manager - self._rest_manager.get_endpoint('collections').gigachannel_manager = self.gigachannel_manager + await self.init_endpoints(endpoints=['channels', 'collections'], + values={'gigachannel_manager': self.gigachannel_manager}) async def shutdown(self): self.session.notifier.notify_shutdown_state("Shutting down Gigachannel Manager...") - self._rest_manager.get_endpoint('channels').gigachannel_manager = None - self._rest_manager.get_endpoint('collections').gigachannel_manager = None - - await self.release_component(RESTComponent) - + await super().shutdown() await self.gigachannel_manager.shutdown() diff --git a/src/tribler-core/tribler_core/components/gigachannel_manager/tests/test_gigachannel_manager_component.py b/src/tribler-core/tribler_core/components/gigachannel_manager/tests/test_gigachannel_manager_component.py index 8ac64ac6c34..17cb66368d9 100644 --- a/src/tribler-core/tribler_core/components/gigachannel_manager/tests/test_gigachannel_manager_component.py +++ b/src/tribler-core/tribler_core/components/gigachannel_manager/tests/test_gigachannel_manager_component.py @@ -13,15 +13,17 @@ # pylint: disable=protected-access async def test_gigachannel_manager_component(tribler_config): + tribler_config.ipv8.enabled = True + tribler_config.libtorrent.enabled = True + tribler_config.chant.enabled = True components = [SocksServersComponent(), MasterKeyComponent(), RESTComponent(), MetadataStoreComponent(), LibtorrentComponent(), GigachannelManagerComponent()] session = Session(tribler_config, components) with session: comp = GigachannelManagerComponent.instance() - with patch.object(RESTManager, 'get_endpoint'): - await session.start() + await session.start() - assert comp.gigachannel_manager - assert comp._rest_manager + assert comp.started.is_set() and not comp.failed + assert comp.gigachannel_manager - await session.shutdown() + await session.shutdown() diff --git a/src/tribler-core/tribler_core/components/ipv8.py b/src/tribler-core/tribler_core/components/ipv8.py index d13be92162b..af1529bb413 100644 --- a/src/tribler-core/tribler_core/components/ipv8.py +++ b/src/tribler-core/tribler_core/components/ipv8.py @@ -16,29 +16,25 @@ from tribler_core.components.base import Component from tribler_core.components.masterkey import MasterKeyComponent from tribler_core.components.reporter import ReporterComponent -from tribler_core.components.restapi import RESTComponent +from tribler_core.components.restapi import RestfulComponent from tribler_core.restapi.rest_manager import RESTManager INFINITE = -1 -class Ipv8Component(Component): +class Ipv8Component(RestfulComponent): ipv8: IPv8 peer: Peer dht_discovery_community: Optional[DHTDiscoveryCommunity] = None _task_manager: TaskManager - _rest_manager: Optional[RESTManager] _peer_discovery_community: Optional[DiscoveryCommunity] = None async def run(self): - await self.get_component(ReporterComponent) + await super().run() config = self.session.config - rest_component = await self.get_component(RESTComponent) - self._rest_manager = rest_component.rest_manager if rest_component else None - self._task_manager = TaskManager() port = config.ipv8.port @@ -81,9 +77,6 @@ async def run(self): config.ipv8.walk_interval, config.ipv8.walk_scaling_upper_limit).start(self._task_manager) - if self._rest_manager: - self._rest_manager.get_endpoint('statistics').ipv8 = ipv8 - if config.dht.enabled: self.init_dht_discovery_community() @@ -94,13 +87,10 @@ async def run(self): if config.dht.enabled: self.dht_discovery_community.routing_tables[UDPv4Address] = RoutingTable('\x00' * 20) - endpoints_to_init = ['/asyncio', '/attestation', '/dht', '/identity', - '/isolation', '/network', '/noblockdht', '/overlays'] - - if self._rest_manager: - for path, endpoint in self._rest_manager.get_endpoint('ipv8').endpoints.items(): - if path in endpoints_to_init: - endpoint.initialize(ipv8) + await self.init_endpoints(endpoints=['statistics'], values={'ipv8': ipv8}) + await self.init_ipv8_endpoints(ipv8, endpoints=[ + 'asyncio', 'attestation', 'dht', 'identity', 'isolation', 'network', 'noblockdht', 'overlays' + ]) def make_bootstrapper(self) -> DispersyBootstrapper: args = DISPERSY_BOOTSTRAPPER['init'] @@ -127,15 +117,12 @@ def init_dht_discovery_community(self): self.dht_discovery_community = community async def shutdown(self): - if self._rest_manager: - self._rest_manager.get_endpoint('statistics').ipv8 = None - await self.release_component(RESTComponent) + await super().shutdown() for overlay in (self.dht_discovery_community, self._peer_discovery_community): if overlay: await self.ipv8.unload_overlay(overlay) - await self.unused.wait() self.session.notifier.notify_shutdown_state("Shutting down IPv8...") await self._task_manager.shutdown_task_manager() await self.ipv8.stop(stop_loop=False) diff --git a/src/tribler-core/tribler_core/components/libtorrent.py b/src/tribler-core/tribler_core/components/libtorrent.py index 21fb71c94e9..79547c7ef52 100644 --- a/src/tribler-core/tribler_core/components/libtorrent.py +++ b/src/tribler-core/tribler_core/components/libtorrent.py @@ -1,35 +1,27 @@ from tribler_common.simpledefs import STATE_CHECKPOINTS_LOADED, STATE_LOAD_CHECKPOINTS, STATE_START_LIBTORRENT + from tribler_core.components.base import Component from tribler_core.components.masterkey import MasterKeyComponent from tribler_core.components.reporter import ReporterComponent -from tribler_core.components.restapi import RESTComponent +from tribler_core.components.restapi import RestfulComponent from tribler_core.components.socks_configurator import SocksServersComponent from tribler_core.components.upgrade import UpgradeComponent from tribler_core.modules.libtorrent.download_manager import DownloadManager from tribler_core.restapi.rest_manager import RESTManager -class LibtorrentComponent(Component): +class LibtorrentComponent(RestfulComponent): download_manager: DownloadManager - _endpoints = ['createtorrent', 'libtorrent', 'torrentinfo', 'downloads', 'channels', 'collections', 'settings'] - _rest_manager: RESTManager - async def run(self): - await self.get_component(ReporterComponent) + await super().run() await self.get_component(UpgradeComponent) socks_servers_component = await self.require_component(SocksServersComponent) master_key_component = await self.require_component(MasterKeyComponent) config = self.session.config - # TODO: move rest_manager check after download manager init. Use notifier instead of direct call to endpoint - rest_component = await self.require_component(RESTComponent) - self._rest_manager = rest_component.rest_manager - state_endpoint = self._rest_manager.get_endpoint('state') if self._rest_manager else None - if state_endpoint: - state_endpoint.readable_status = STATE_START_LIBTORRENT - + await self.set_readable_status(STATE_START_LIBTORRENT) self.download_manager = DownloadManager( config=config.libtorrent, state_dir=config.state_dir, @@ -40,23 +32,19 @@ async def run(self): socks_listen_ports=socks_servers_component.socks_ports, dummy_mode=config.gui_test_mode) self.download_manager.initialize() - if state_endpoint: - state_endpoint.readable_status = STATE_LOAD_CHECKPOINTS + + await self.set_readable_status(STATE_LOAD_CHECKPOINTS) await self.download_manager.load_checkpoints() - if state_endpoint: - state_endpoint.readable_status = STATE_CHECKPOINTS_LOADED + await self.set_readable_status(STATE_CHECKPOINTS_LOADED) + + endpoints = ['createtorrent', 'libtorrent', 'torrentinfo', 'downloads', 'channels', 'collections', 'settings'] + await self.init_endpoints(endpoints=endpoints, values={'download_manager': self.download_manager}) - self._rest_manager.set_attr_for_endpoints(self._endpoints, 'download_manager', self.download_manager, - skip_missing=True) if config.gui_test_mode: uri = "magnet:?xt=urn:btih:0000000000000000000000000000000000000000" await self.download_manager.start_download_from_uri(uri) async def shutdown(self): - # Release endpoints - self._rest_manager.set_attr_for_endpoints(self._endpoints, 'download_manager', None, skip_missing=True) - - await self.release_component(RESTComponent) - + await super().shutdown() self.download_manager.stop_download_states_callback() await self.download_manager.shutdown() diff --git a/src/tribler-core/tribler_core/components/metadata_store/metadata_store_component.py b/src/tribler-core/tribler_core/components/metadata_store/metadata_store_component.py index 86e384801d0..04c8a08d3f5 100644 --- a/src/tribler-core/tribler_core/components/metadata_store/metadata_store_component.py +++ b/src/tribler-core/tribler_core/components/metadata_store/metadata_store_component.py @@ -1,27 +1,22 @@ from tribler_common.simpledefs import NTFY, STATEDIR_DB_DIR + from tribler_core.components.base import Component from tribler_core.components.masterkey import MasterKeyComponent from tribler_core.components.reporter import ReporterComponent -from tribler_core.components.restapi import RESTComponent +from tribler_core.components.restapi import RestfulComponent from tribler_core.components.upgrade import UpgradeComponent from tribler_core.components.metadata_store.db.store import MetadataStore from tribler_core.components.metadata_store.utils import generate_test_channels from tribler_core.restapi.rest_manager import RESTManager -class MetadataStoreComponent(Component): +class MetadataStoreComponent(RestfulComponent): mds: MetadataStore - _rest_manager: RESTManager - _endpoints = ['search', 'metadata', 'remote_query', 'downloads', 'channels', 'collections', 'statistics'] - async def run(self): - await self.get_component(ReporterComponent) + await super().run() await self.get_component(UpgradeComponent) - rest_component = await self.require_component(RESTComponent) - self._rest_manager = rest_component.rest_manager - config = self.session.config channels_dir = config.chant.get_path_as_absolute('channels_dir', config.state_dir) chant_testnet = config.general.testnet or config.chant.testnet @@ -53,7 +48,12 @@ async def run(self): disable_sync=config.gui_test_mode, ) self.mds = metadata_store - self._rest_manager.set_attr_for_endpoints(self._endpoints, 'mds', metadata_store, skip_missing=True) + + await self.init_endpoints( + endpoints=['search', 'metadata', 'remote_query', 'downloads', 'channels', 'collections', 'statistics'], + values={'mds': metadata_store} + ) + self.session.notifier.add_observer(NTFY.TORRENT_METADATA_ADDED, metadata_store.TorrentMetadata.add_ffa_from_dict) @@ -61,10 +61,6 @@ async def run(self): generate_test_channels(metadata_store) async def shutdown(self): - # Release endpoints - self._rest_manager.set_attr_for_endpoints(self._endpoints, 'mds', None, skip_missing=True) - await self.release_component(RESTComponent) - - await self.unused.wait() + await super().shutdown() self.session.notifier.notify_shutdown_state("Shutting down Metadata Store...") self.mds.shutdown() diff --git a/src/tribler-core/tribler_core/components/metadata_store/tests/test_metadata_store_component.py b/src/tribler-core/tribler_core/components/metadata_store/tests/test_metadata_store_component.py index 9d4b6a51aa1..d6c8ce3fb4a 100644 --- a/src/tribler-core/tribler_core/components/metadata_store/tests/test_metadata_store_component.py +++ b/src/tribler-core/tribler_core/components/metadata_store/tests/test_metadata_store_component.py @@ -10,14 +10,15 @@ # pylint: disable=protected-access async def test_metadata_store_component(tribler_config): + tribler_config.libtorrent.enabled = True + tribler_config.chant.enabled = True components = [MasterKeyComponent(), RESTComponent(), MetadataStoreComponent()] session = Session(tribler_config, components) with session: comp = MetadataStoreComponent.instance() - with patch.object(RESTManager, 'get_endpoint'): - await session.start() + await session.start() - assert comp.mds - assert comp._rest_manager + assert comp.started.is_set() and not comp.failed + assert comp.mds - await session.shutdown() + await session.shutdown() diff --git a/src/tribler-core/tribler_core/components/resource_monitor.py b/src/tribler-core/tribler_core/components/resource_monitor.py index 787e87e512d..b67a684d60f 100644 --- a/src/tribler-core/tribler_core/components/resource_monitor.py +++ b/src/tribler-core/tribler_core/components/resource_monitor.py @@ -1,15 +1,15 @@ from tribler_core.components.base import Component from tribler_core.components.reporter import ReporterComponent -from tribler_core.components.restapi import RESTComponent +from tribler_core.components.restapi import RestfulComponent from tribler_core.components.upgrade import UpgradeComponent from tribler_core.modules.resource_monitor.core import CoreResourceMonitor -class ResourceMonitorComponent(Component): +class ResourceMonitorComponent(RestfulComponent): resource_monitor: CoreResourceMonitor async def run(self): - await self.get_component(ReporterComponent) + await super().run() await self.get_component(UpgradeComponent) config = self.session.config @@ -23,9 +23,9 @@ async def run(self): resource_monitor.start() self.resource_monitor = resource_monitor - rest_component = await self.require_component(RESTComponent) - rest_component.rest_manager.get_endpoint('debug').resource_monitor = resource_monitor + await self.init_endpoints(endpoints=['debug'], values={'resource_monitor': resource_monitor}) async def shutdown(self): self.session.notifier.notify_shutdown_state("Shutting down Resource Monitor...") + await super().shutdown() await self.resource_monitor.stop() diff --git a/src/tribler-core/tribler_core/components/restapi.py b/src/tribler-core/tribler_core/components/restapi.py index 95ce888fe5f..f31c1f5c0a9 100644 --- a/src/tribler-core/tribler_core/components/restapi.py +++ b/src/tribler-core/tribler_core/components/restapi.py @@ -1,9 +1,65 @@ +from abc import ABC +from typing import Any, Dict, List, Set, Tuple + +from ipv8_service import IPv8 + from tribler_common.simpledefs import STATE_START_API from tribler_core.components.base import Component from tribler_core.components.reporter import ReporterComponent from tribler_core.exception_handler import CoreExceptionHandler from tribler_core.restapi.rest_manager import ApiKeyMiddleware, RESTManager, error_middleware from tribler_core.restapi.root_endpoint import RootEndpoint +from tribler_core.restapi.state_endpoint import StateEndpoint + + +class RestfulComponent(Component, ABC): + endpoint_attrs: Set[Tuple[str, str]] + + def __init__(self): + super().__init__() + self.endpoint_attrs = set() + + async def set_readable_status(self, readable_status): + rest_component = await self.get_component(RESTComponent) + if rest_component: + state_endpoint: StateEndpoint = rest_component.rest_manager.get_endpoint('state') + state_endpoint.readable_status = readable_status + + async def init_endpoints(self, endpoints: List[str], values: Dict[str, Any]): + rest_component = await self.get_component(RESTComponent) + if not rest_component: + return + + for endpoint_name in endpoints: + endpoint = rest_component.rest_manager.get_endpoint(endpoint_name) + if endpoint: + for attr_name, attr_value in values.items(): + setattr(endpoint, attr_name, attr_value) + self.endpoint_attrs.add((endpoint_name, attr_name)) + + async def init_ipv8_endpoints(self, ipv8: IPv8, endpoints: List[str]): + rest_component = await self.get_component(RESTComponent) + if not rest_component: + return + + ipv8_root_endpoint = rest_component.rest_manager.get_endpoint('ipv8') + if ipv8_root_endpoint: + path_set = {'/' + name for name in endpoints} + for path, endpoint in ipv8_root_endpoint.endpoints.items(): + if path in path_set: + endpoint.initialize(ipv8) + + async def run(self): + await self.get_component(ReporterComponent) + + async def shutdown(self): + rest_component = await self.get_component(RESTComponent) + if not rest_component: + return + + for endpoint_name, attr_name in self.endpoint_attrs: + endpoint = rest_component.rest_manager.get_endpoint(endpoint_name) + setattr(endpoint, attr_name, None) class RESTComponent(Component): diff --git a/src/tribler-core/tribler_core/components/tests/test_tribler_components.py b/src/tribler-core/tribler_core/components/tests/test_tribler_components.py index cbdcd159c6d..1a7debf2b84 100644 --- a/src/tribler-core/tribler_core/components/tests/test_tribler_components.py +++ b/src/tribler-core/tribler_core/components/tests/test_tribler_components.py @@ -53,73 +53,78 @@ def test_session_context_manager(loop, tribler_config): async def test_masterkey_component(tribler_config): session = Session(tribler_config, [MasterKeyComponent()]) with session: - comp = MasterKeyComponent.instance() await session.start() + comp = MasterKeyComponent.instance() + assert comp.started.is_set() and not comp.failed assert comp.keypair await session.shutdown() async def test_ipv8_component(tribler_config): + tribler_config.ipv8.enabled = True components = [MasterKeyComponent(), RESTComponent(), Ipv8Component()] session = Session(tribler_config, components) with session: - comp = Ipv8Component.instance() - with patch.object(RESTManager, 'get_endpoint'): - await session.start() + await session.start() - assert comp.ipv8 - assert comp.peer - assert not comp.dht_discovery_community - assert comp._task_manager - assert comp._rest_manager - assert not comp._peer_discovery_community + comp = Ipv8Component.instance() + assert comp.started.is_set() and not comp.failed + assert comp.ipv8 + assert comp.peer + assert not comp.dht_discovery_community + assert comp._task_manager + assert not comp._peer_discovery_community - await session.shutdown() + await session.shutdown() async def test_libtorrent_component(tribler_config): + tribler_config.libtorrent.enabled = True + tribler_config.chant.enabled = True components = [RESTComponent(), MasterKeyComponent(), SocksServersComponent(), LibtorrentComponent()] session = Session(tribler_config, components) with session: - comp = LibtorrentComponent.instance() - with patch.object(RESTManager, 'get_endpoint'): - await session.start() + await session.start() - assert comp.download_manager - assert comp._rest_manager + comp = LibtorrentComponent.instance() + assert comp.started.is_set() and not comp.failed + assert comp.download_manager - await session.shutdown() + await session.shutdown() async def test_payout_component(tribler_config): + tribler_config.ipv8.enabled = True components = [BandwidthAccountingComponent(), MasterKeyComponent(), RESTComponent(), Ipv8Component(), PayoutComponent()] session = Session(tribler_config, components) with session: - comp = PayoutComponent.instance() - with patch.object(RESTManager, 'get_endpoint'): - await session.start() + await session.start() - assert comp.payout_manager + comp = PayoutComponent.instance() + assert comp.started.is_set() and not comp.failed + assert comp.payout_manager - await session.shutdown() + await session.shutdown() async def test_popularity_component(tribler_config): + tribler_config.ipv8.enabled = True + tribler_config.libtorrent.enabled = True + tribler_config.chant.enabled = True components = [SocksServersComponent(), LibtorrentComponent(), TorrentCheckerComponent(), MetadataStoreComponent(), MasterKeyComponent(), RESTComponent(), Ipv8Component(), PopularityComponent()] session = Session(tribler_config, components) with session: - comp = PopularityComponent.instance() - with patch.object(RESTManager, 'get_endpoint'): - await session.start() + await session.start() - assert comp.community - assert comp._ipv8 + comp = PopularityComponent.instance() + assert comp.community + assert comp._ipv8 - await session.shutdown() + await session.shutdown() async def test_reporter_component(tribler_config): @@ -127,113 +132,126 @@ async def test_reporter_component(tribler_config): session = Session(tribler_config, components) with session: await session.start() + + comp = ReporterComponent.instance() + assert comp.started.is_set() and not comp.failed + await session.shutdown() async def test_resource_monitor_component(tribler_config): + tribler_config.ipv8.enabled = True + tribler_config.libtorrent.enabled = True + tribler_config.chant.enabled = True components = [MasterKeyComponent(), RESTComponent(), ResourceMonitorComponent()] session = Session(tribler_config, components) with session: - comp = ResourceMonitorComponent.instance() - with patch.object(RESTManager, 'get_endpoint'): - await session.start() + await session.start() - assert comp.resource_monitor + comp = ResourceMonitorComponent.instance() + assert comp.started.is_set() and not comp.failed + assert comp.resource_monitor - await session.shutdown() + await session.shutdown() async def test_REST_component(tribler_config): components = [MasterKeyComponent(), RESTComponent()] session = Session(tribler_config, components) with session: - comp = RESTComponent.instance() - with patch.object(RESTManager, 'get_endpoint'): - await session.start() + await session.start() - assert comp.rest_manager + comp = RESTComponent.instance() + assert comp.started.is_set() and not comp.failed + assert comp.rest_manager - await session.shutdown() + await session.shutdown() async def test_socks_servers_component(tribler_config): components = [SocksServersComponent()] session = Session(tribler_config, components) with session: - comp = SocksServersComponent.instance() - with patch.object(RESTManager, 'get_endpoint'): - await session.start() + await session.start() - assert comp.socks_ports - assert comp.socks_servers + comp = SocksServersComponent.instance() + assert comp.started.is_set() and not comp.failed + assert comp.socks_ports + assert comp.socks_servers - await session.shutdown() + await session.shutdown() async def test_torrent_checker_component(tribler_config): + tribler_config.libtorrent.enabled = True + tribler_config.chant.enabled = True components = [SocksServersComponent(), LibtorrentComponent(), MasterKeyComponent(), RESTComponent(), MetadataStoreComponent(), TorrentCheckerComponent()] session = Session(tribler_config, components) with session: - comp = TorrentCheckerComponent.instance() - with patch.object(RESTManager, 'get_endpoint'): - await session.start() + await session.start() - assert comp.torrent_checker - assert comp._rest_manager + comp = TorrentCheckerComponent.instance() + assert comp.started.is_set() and not comp.failed + assert comp.torrent_checker - await session.shutdown() + await session.shutdown() async def test_tunnels_component(tribler_config): + tribler_config.ipv8.enabled = True + tribler_config.libtorrent.enabled = True + tribler_config.chant.enabled = True components = [Ipv8Component(), MasterKeyComponent(), RESTComponent(), TunnelsComponent()] session = Session(tribler_config, components) with session: - comp = TunnelsComponent.instance() - with patch.object(RESTManager, 'get_endpoint'): - await session.start() + await session.start() - assert comp.community - assert comp._ipv8 + comp = TunnelsComponent.instance() + assert comp.started.is_set() and not comp.failed + assert comp.community + assert comp._ipv8 - await session.shutdown() + await session.shutdown() async def test_upgrade_component(tribler_config): components = [MasterKeyComponent(), RESTComponent(), UpgradeComponent()] session = Session(tribler_config, components) with session: - comp = UpgradeComponent.instance() - with patch.object(RESTManager, 'get_endpoint'): - await session.start() + await session.start() - assert comp.upgrader + comp = UpgradeComponent.instance() + assert comp.started.is_set() and not comp.failed + assert comp.upgrader - await session.shutdown() + await session.shutdown() async def test_version_check_component(tribler_config): components = [VersionCheckComponent()] session = Session(tribler_config, components) with session: - comp = VersionCheckComponent.instance() - with patch.object(RESTManager, 'get_endpoint'): - await session.start() + await session.start() - assert comp.version_check_manager + comp = VersionCheckComponent.instance() + assert comp.started.is_set() and not comp.failed + assert comp.version_check_manager - await session.shutdown() + await session.shutdown() async def test_watch_folder_component(tribler_config): + tribler_config.libtorrent.enabled = True + tribler_config.chant.enabled = True components = [MasterKeyComponent(), RESTComponent(), SocksServersComponent(), LibtorrentComponent(), WatchFolderComponent()] session = Session(tribler_config, components) with session: - comp = WatchFolderComponent.instance() - with patch.object(RESTManager, 'get_endpoint'): - await session.start() + await session.start() - assert comp.watch_folder + comp = WatchFolderComponent.instance() + assert comp.started.is_set() and not comp.failed + assert comp.watch_folder - await session.shutdown() + await session.shutdown() diff --git a/src/tribler-core/tribler_core/components/torrent_checker.py b/src/tribler-core/tribler_core/components/torrent_checker.py index 9dcf88c98c2..d5ef2499242 100644 --- a/src/tribler-core/tribler_core/components/torrent_checker.py +++ b/src/tribler-core/tribler_core/components/torrent_checker.py @@ -1,30 +1,26 @@ from tribler_common.simpledefs import STATE_START_TORRENT_CHECKER + from tribler_core.components.base import Component from tribler_core.components.libtorrent import LibtorrentComponent from tribler_core.components.metadata_store.metadata_store_component import MetadataStoreComponent from tribler_core.components.reporter import ReporterComponent -from tribler_core.components.restapi import RESTComponent +from tribler_core.components.restapi import RestfulComponent from tribler_core.components.socks_configurator import SocksServersComponent from tribler_core.modules.torrent_checker.torrent_checker import TorrentChecker from tribler_core.modules.torrent_checker.tracker_manager import TrackerManager from tribler_core.restapi.rest_manager import RESTManager -class TorrentCheckerComponent(Component): +class TorrentCheckerComponent(RestfulComponent): torrent_checker: TorrentChecker - _rest_manager: RESTManager - async def run(self): - await self.get_component(ReporterComponent) + await super().run() config = self.session.config metadata_store_component = await self.require_component(MetadataStoreComponent) libtorrent_component = await self.require_component(LibtorrentComponent) - rest_component = await self.require_component(RESTComponent) - self._rest_manager = rest_component.rest_manager - socks_servers_component = await self.require_component(SocksServersComponent) tracker_manager = TrackerManager(state_dir=config.state_dir, metadata_store=metadata_store_component.mds) @@ -35,16 +31,10 @@ async def run(self): socks_listen_ports=socks_servers_component.socks_ports, metadata_store=metadata_store_component.mds) self.torrent_checker = torrent_checker - self._rest_manager.get_endpoint('state').readable_status = STATE_START_TORRENT_CHECKER - await torrent_checker.initialize() - self._rest_manager.set_attr_for_endpoints(['metadata'], 'torrent_checker', torrent_checker, - skip_missing=True) + await self.init_endpoints(endpoints=['metadata'], values={'torrent_checker': torrent_checker}) async def shutdown(self): self.session.notifier.notify_shutdown_state("Shutting down Torrent Checker...") - self._rest_manager.set_attr_for_endpoints(['metadata'], 'torrent_checker', None, skip_missing=True) - - await self.release_component(RESTComponent) - + await super().shutdown() await self.torrent_checker.shutdown() diff --git a/src/tribler-core/tribler_core/components/tunnels.py b/src/tribler-core/tribler_core/components/tunnels.py index 7fa9f585bd2..8f97c3ef8d7 100644 --- a/src/tribler-core/tribler_core/components/tunnels.py +++ b/src/tribler-core/tribler_core/components/tunnels.py @@ -7,7 +7,7 @@ from tribler_core.components.ipv8 import Ipv8Component from tribler_core.components.libtorrent import LibtorrentComponent from tribler_core.components.reporter import ReporterComponent -from tribler_core.components.restapi import RESTComponent +from tribler_core.components.restapi import RestfulComponent from tribler_core.components.socks_configurator import SocksServersComponent from tribler_core.modules.tunnel.community.community import TriblerTunnelCommunity, TriblerTunnelTestnetCommunity from tribler_core.modules.tunnel.community.discovery import GoldenRatioStrategy @@ -15,12 +15,12 @@ INFINITE = -1 -class TunnelsComponent(Component): +class TunnelsComponent(RestfulComponent): community: TriblerTunnelCommunity _ipv8: IPv8 async def run(self): - await self.get_component(ReporterComponent) + await super().run() config = self.session.config ipv8_component = await self.require_component(Ipv8Component) @@ -70,14 +70,9 @@ async def run(self): self.community = community - rest_component = await self.get_component(RESTComponent) - if rest_component: - rest_component.rest_manager.get_endpoint('ipv8').endpoints['/tunnel'].initialize(self._ipv8) - if download_component: - rest_component.rest_manager.get_endpoint('downloads').tunnel_community = community - - debug_endpoint = rest_component.rest_manager.get_endpoint('debug') - debug_endpoint.tunnel_community = community + await self.init_endpoints(endpoints=['downloads', 'debug'], values={'tunnel_community': community}) + await self.init_ipv8_endpoints(self._ipv8, endpoints=['tunnel']) async def shutdown(self): + await super().shutdown() await self._ipv8.unload_overlay(self.community) diff --git a/src/tribler-core/tribler_core/components/upgrade.py b/src/tribler-core/tribler_core/components/upgrade.py index 73f83f92d66..5c7390d3bae 100644 --- a/src/tribler-core/tribler_core/components/upgrade.py +++ b/src/tribler-core/tribler_core/components/upgrade.py @@ -1,16 +1,17 @@ from tribler_common.simpledefs import STATE_UPGRADING_READABLE + from tribler_core.components.base import Component from tribler_core.components.masterkey import MasterKeyComponent from tribler_core.components.reporter import ReporterComponent -from tribler_core.components.restapi import RESTComponent +from tribler_core.components.restapi import RestfulComponent from tribler_core.upgrade.upgrade import TriblerUpgrader -class UpgradeComponent(Component): +class UpgradeComponent(RestfulComponent): upgrader: TriblerUpgrader async def run(self): - await self.get_component(ReporterComponent) + await super().run() config = self.session.config notifier = self.session.notifier master_key_component = await self.require_component(MasterKeyComponent) @@ -22,8 +23,6 @@ async def run(self): trustchain_keypair=master_key_component.keypair, notifier=notifier) - rest_component = await self.require_component(RESTComponent) - rest_component.rest_manager.get_endpoint('upgrader').upgrader = self.upgrader - rest_component.rest_manager.get_endpoint('state').readable_status = STATE_UPGRADING_READABLE - + await self.init_endpoints(endpoints=['upgrader'], values={'upgrader': self.upgrader}) + await self.set_readable_status(STATE_UPGRADING_READABLE) await self.upgrader.run() diff --git a/src/tribler-core/tribler_core/components/watch_folder.py b/src/tribler-core/tribler_core/components/watch_folder.py index ce149068e27..71a6f4b1275 100644 --- a/src/tribler-core/tribler_core/components/watch_folder.py +++ b/src/tribler-core/tribler_core/components/watch_folder.py @@ -1,16 +1,17 @@ from tribler_common.simpledefs import STATE_START_WATCH_FOLDER + from tribler_core.components.base import Component from tribler_core.components.libtorrent import LibtorrentComponent from tribler_core.components.reporter import ReporterComponent -from tribler_core.components.restapi import RESTComponent +from tribler_core.components.restapi import RestfulComponent from tribler_core.modules.watch_folder.watch_folder import WatchFolder -class WatchFolderComponent(Component): +class WatchFolderComponent(RestfulComponent): watch_folder: WatchFolder async def run(self): - await self.get_component(ReporterComponent) + await super().run() config = self.session.config notifier = self.session.notifier libtorrent_component = await self.require_component(LibtorrentComponent) @@ -19,13 +20,11 @@ async def run(self): watch_folder = WatchFolder(watch_folder_path=watch_folder_path, download_manager=libtorrent_component.download_manager, notifier=notifier) - - rest_component = await self.require_component(RESTComponent) - rest_component.rest_manager.get_endpoint('state').readable_status = STATE_START_WATCH_FOLDER - + await self.set_readable_status(STATE_START_WATCH_FOLDER) watch_folder.start() self.watch_folder = watch_folder async def shutdown(self): self.session.notifier.notify_shutdown_state("Shutting down Watch Folder...") + await super().shutdown() await self.watch_folder.stop() diff --git a/src/tribler-core/tribler_core/restapi/rest_manager.py b/src/tribler-core/tribler_core/restapi/rest_manager.py index da32821fb84..e014f5aebba 100644 --- a/src/tribler-core/tribler_core/restapi/rest_manager.py +++ b/src/tribler-core/tribler_core/restapi/rest_manager.py @@ -98,17 +98,6 @@ def __init__(self, config: APISettings, root_endpoint: RootEndpoint, state_dir=N def get_endpoint(self, name): return self.root_endpoint.endpoints['/' + name] - def set_attr_for_endpoints(self, endpoints: List[str], attr_name: str, attr_value, skip_missing=False): - """ - Set attribute value for each endpoint in the list. Can be used for delayed initialization of endpoints. - """ - for endpoint_name in endpoints: - endpoint = self.root_endpoint.endpoints.get('/' + endpoint_name) - if endpoint is not None: - setattr(endpoint, attr_name, attr_value) - elif not skip_missing: - raise KeyError(f'Endpoint not found: /{endpoint_name}') - async def start(self): """ Starts the HTTP API with the listen port as specified in the session configuration. diff --git a/src/tribler-core/tribler_core/restapi/trustview_endpoint.py b/src/tribler-core/tribler_core/restapi/trustview_endpoint.py index dd2aca2ac80..1736e2c77b2 100644 --- a/src/tribler-core/tribler_core/restapi/trustview_endpoint.py +++ b/src/tribler-core/tribler_core/restapi/trustview_endpoint.py @@ -18,8 +18,8 @@ class TrustViewEndpoint(RESTEndpoint): def __init__(self): super().__init__() - self.bandwidth_db = None + self.bandwidth_community = None # added to simlify the initialization code of BandwidthAccountingComponent def setup_routes(self): self.app.add_routes([web.get('', self.get_view)])