def _handle_add_nodes(self, sessionid, nodes): for node in nodes: # we only care about properties node_val = node.value if node_val: json_obj = json.loads(node_val) if isinstance(json_obj, dict): json_properties = json_obj["properties"] # get the name and value from each entry raw_props = { entry["name"]: entry["value"] for entry in json_properties if entry["type"] == "string" } # decode decoded_props = decode_endpoint_props(raw_props) new_ed = EndpointDescription(properties=decoded_props) old_ed = self._has_discovered_endpoint(new_ed.get_id()) if not old_ed: # add discovered endpoint to our internal list self._add_discovered_endpoint(sessionid, new_ed) # dispatch self._fire_endpoint_event(EndpointEvent.ADDED, new_ed) else: # get timestamp and make sure new one is newer (an # update) old_ts = old_ed.get_timestamp() new_ts = new_ed.get_timestamp() if new_ts > old_ts: self._remove_discovered_endpoint(old_ed.get_id()) self._add_discovered_endpoint(sessionid, new_ed) self._fire_endpoint_event(EndpointEvent.MODIFIED, new_ed)
def testConstructor(self): """ Tests the behavior of the __init__ method """ # Must fail due to the lack of endpoint.id self.assertRaises(ValueError, EndpointDescription, self.svc_ref, None) # Must not fail EndpointDescription( self.svc_ref, {pelix.rsa.ENDPOINT_ID: "toto", pelix.rsa.ECF_ENDPOINT_ID: "toto", pelix.rsa.ECF_ENDPOINT_CONTAINERID_NAMESPACE: "test", pelix.rsa.ENDPOINT_FRAMEWORK_UUID: "other-fw", pelix.rsa.SERVICE_IMPORTED_CONFIGS: ['titi']}) # Must fail due to the lack of properties for mandatory in (pelix.rsa.ENDPOINT_ID, pelix.rsa.SERVICE_IMPORTED_CONFIGS): self.assertRaises(ValueError, EndpointDescription, None, {mandatory: "toto", pelix.constants.OBJECTCLASS: "spec", pelix.constants.SERVICE_ID: 1}) # Must not fail EndpointDescription( None, {pelix.rsa.ENDPOINT_ID: "toto", pelix.rsa.ECF_ENDPOINT_ID: "toto", pelix.rsa.ECF_ENDPOINT_CONTAINERID_NAMESPACE: "test", pelix.rsa.ENDPOINT_FRAMEWORK_UUID: "other-fw", pelix.rsa.SERVICE_IMPORTED_CONFIGS: ['titi'], pelix.constants.OBJECTCLASS: "spec", pelix.constants.SERVICE_ID: 1})
def export_service(self, svc_ref, export_props): # type: (ServiceReference, Dict[str, Any]) -> EndpointDescription """ Exports the given service :param svc_ref: Reference to the service to export :param export_props: Export properties :return: The endpoint description """ ed = EndpointDescription.fromprops(export_props) self._export_service(self._get_bundle_context().get_service(svc_ref), ed) return ed
def testEdefStringReload(self): """ Tries to convert an EndpointDescription to its XML format (EDEF) and to reload this string """ original = EndpointDescription( self.svc_ref, {pelix.rsa.ENDPOINT_ID: "toto", pelix.rsa.ECF_ENDPOINT_ID: "toto", pelix.rsa.ECF_ENDPOINT_CONTAINERID_NAMESPACE: "test", pelix.rsa.ENDPOINT_FRAMEWORK_UUID: "other-fw", pelix.rsa.SERVICE_IMPORTED_CONFIGS: ['titi'], pelix.constants.OBJECTCLASS: "spec"}) # Write the endpoint to an XML string writer = EDEFWriter() xml_string = writer.to_string([original]) # Parse the XML reader = EDEFReader() endpoints = reader.parse(xml_string) # Ensure we have a valid result self.assertEqual(len(endpoints), 1, "Parsed more than one endpoint") endpoint = endpoints[0] # Ensure equality self.assertIsNot(original, endpoint, "Same exact endpoint object returned") self.assertEqual(original, endpoint, "Parsed endpoint is different") self.assertEqual(endpoint, original, "Parsed endpoint is different") # Ensure properties equality self.assertDictEqual(original.get_properties(), endpoint.get_properties(), "Endpoint properties changed")
def _parse_description(self, node): # type: (ElementTree.Element) -> EndpointDescription """ Parse an endpoint description node :param node: The endpoint description node :return: The parsed EndpointDescription bean :raise KeyError: Attribute missing :raise ValueError: Invalid description """ endpoint = {} for prop_node in node.findall(TAG_PROPERTY): name, value = self._parse_property(prop_node) endpoint[name] = value return EndpointDescription(None, endpoint)
def testEdefIOTypes(self): """ Tests the writing and parsing of an EndpointDescription bean with "complex" properties """ properties = { # Strings whitespaces are not well kept in XML "string": "some string just to see...", "int": 12, "float": 12.0, "tuple_str": ("a", "b", "c"), "tuple_int": (1, 2, 3), "tuple_float": (1.0, 2.0, 3.0), "list_str": ["a", "b", "c"], "list_int": [1, 2, 3], "list_float": [1.0, 2.0, 3.0], "set_str": {"a", "b", "c"}, "set_int": {1, 2, 3}, "set_float": {1.0, 2.0, 3.0}} all_props = properties.copy() all_props[pelix.rsa.ENDPOINT_ID] = 'toto' all_props[pelix.rsa.SERVICE_IMPORTED_CONFIGS] = ['titi'] all_props[pelix.rsa.ECF_ENDPOINT_ID] = "toto" all_props[pelix.rsa.ECF_ENDPOINT_CONTAINERID_NAMESPACE] = "test" all_props[pelix.rsa.ENDPOINT_FRAMEWORK_UUID] = "other-fw" # Prepare an endpoint description with different property values endpoint = EndpointDescription(self.svc_ref, all_props) # Write it & parse it xml_string = EDEFWriter().to_string([endpoint]) parsed = EDEFReader().parse(xml_string)[0] parsed_properties = parsed.get_properties() # Check values for key, initial_value in properties.items(): if isinstance(initial_value, tuple): # EDEF transformation merges the tuple/list types initial_value = list(initial_value) self.assertEqual(parsed_properties[key], initial_value)
def _worker(self): while True: with self._lock: # If self._done flag is set, return and that's it if self._done: return # otherwise block to get items from queue placed by service_imported, # service_modified, and service_unimported # called by Py4j handler thread item = self._queue.get() f = None try: # get the function from item[2] f = item[2] except Exception: logging.error("Exception getting code in item=%s", item) if f: try: # get the endpoint description properties from item[1] # and create EndpointDescription instance ed = EndpointDescription(properties=item[1]) except Exception: logging.error( "Exception creating endpoint description from props=%s", item[1], ) else: # call appropriate function try: f(ed) except Exception: logging.error("Exception invoking function=%s", f) # no matter what, we are done with this task self._queue.task_done()