Home | History | Annotate | Download | only in n_faced_peerd
      1 # Copyright 2015 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import dbus
      6 import dbus.service
      7 import logging
      8 import time
      9 
     10 from autotest_lib.client.cros.tendo import peerd_dbus_helper
     11 from autotest_lib.client.cros.tendo.n_faced_peerd import dbus_property_exposer
     12 from autotest_lib.client.cros.tendo.n_faced_peerd import service
     13 
     14 
     15 class Peer(dbus_property_exposer.DBusPropertyExposer):
     16     """Represents local and remote peers."""
     17 
     18     def __init__(self, bus, path, peer_id, object_manager, is_self=False):
     19         """Construct a org.chromium.peerd.Peer DBus object.
     20 
     21         @param bus: dbus.Bus object to export this object on.
     22         @param path: string object path to export this object at.
     23         @param peer_id: string peerd peer ID; a UUID.
     24         @param is_self: True iff this object will servce as a self peer.
     25         @param object_manager: an instance of ObjectManager.
     26 
     27         """
     28         super(Peer, self).__init__(
     29                 bus, path, peerd_dbus_helper.DBUS_INTERFACE_PEER)
     30         # Fill in the initial values for our properties.
     31         self.uuid = peer_id
     32         self._is_self = is_self
     33         self._update_last_seen()
     34         # Register properties with the property exposer.
     35         self.register_property(peerd_dbus_helper.PEER_PROPERTY_ID,
     36                                self._get_dbus_id)
     37         self.register_property(peerd_dbus_helper.PEER_PROPERTY_LAST_SEEN,
     38                                self._get_dbus_last_seen)
     39         # Claim our interace with the object manager.
     40         self._object_manager = object_manager
     41         self._path = path
     42         self._object_manager.claim_interface(
     43                 path, peerd_dbus_helper.DBUS_INTERFACE_PEER,
     44                 self.property_getter)
     45         # We need to keep a good bit of stuff around because we're responsible
     46         # for creating child service objects.
     47         self._bus = bus
     48         self.services = dict()
     49         self._services_counter = 0
     50 
     51 
     52     def _get_dbus_id(self):
     53         """Getter for PEER_PROPERTY_ID.
     54 
     55         @return dbus.String containing our peer ID.
     56 
     57         """
     58         return dbus.String(self.uuid)
     59 
     60 
     61     def _get_dbus_last_seen(self):
     62         """Getter for PEER_PROPERTY_LAST_SEEN.
     63 
     64         @return dbus.UInt64 containing the last time this peer was seen
     65                 in milliseconds since the Unix epoc.
     66 
     67         """
     68         return dbus.UInt64(int(1000 * self._last_seen_seconds))
     69 
     70 
     71     def _update_last_seen(self):
     72         """Updates our last seen value.
     73 
     74         This would be a simple call to time.time(), except that peerd
     75         has to report a last seen time of 0 for the peer object representing
     76         itself.
     77 
     78         """
     79         if self._is_self:
     80             self._last_seen_seconds = 0
     81         else:
     82             self._last_seen_seconds = time.time()
     83 
     84 
     85     def close(self):
     86         """Releases interfaces claimed over DBus."""
     87         # TODO(wiley) call close on child services.
     88         raise NotImplementedError('Peer.close() does not work properly')
     89 
     90 
     91     def update_service(self, service_id, service_info, ip_info):
     92         """Update a service associated with this peer.
     93 
     94         @param service_id: string peerd service ID.
     95         @param service_info: dictionary of string,string items comprising
     96                 the metadata for the service.
     97         @param ip_info: an instance of IpInfo defined in service.py.
     98 
     99         """
    100         if service_id in self.services:
    101             self.services[service_id].update(service_info, ip_info)
    102         else:
    103             self._services_counter += 1
    104             service_path = '%s/services/%d' % (self._path,
    105                                                self._services_counter)
    106             self.services[service_id] = service.Service(
    107                     self._bus, service_path, self.uuid, service_id,
    108                     service_info, ip_info, self._object_manager)
    109         logging.info('service=%s has info %r.', service_id, service_info)
    110         self._update_last_seen()
    111         self.on_property_changed(peerd_dbus_helper.PEER_PROPERTY_LAST_SEEN)
    112 
    113 
    114     def remove_service(self, service_id):
    115         """Remove a service associated with this peer.
    116 
    117         @param service_id: string peerd service ID.
    118 
    119         """
    120         removed_service = self.services.pop(service_id, None)
    121         if removed_service is not None:
    122             removed_service.close()
    123         self._update_last_seen()
    124         self.on_property_changed(peerd_dbus_helper.PEER_PROPERTY_LAST_SEEN)
    125