def _export_service(self, io_handler, service_id, export_config=None, filename=None): # type: (ShellSession, str, str, str) -> None """ Export service with given service.id. """ svc_ref = self._context.get_service_reference( None, "(service.id={0})".format(service_id)) if not svc_ref: io_handler.write_line( "Service with id={0} cannot be found so no service " "can be exported", service_id, ) return if export_config: self._export_config = export_config if filename: self._edef_filename = filename # Finally export with required SERVICE_EXPORTED_INTERFACES = '*' # and SERVICE_EXPORTED_CONFIGS to self._export_config export_regs = self._rsa.export_service( svc_ref, { SERVICE_EXPORTED_INTERFACES: "*", SERVICE_EXPORTED_CONFIGS: self._export_config, }, ) exported_eds = [] for export_reg in export_regs: exp = export_reg.get_exception() if exp: io_handler.write_line( "\nException exporting service={0}", export_reg.get_reference(), ) print_exception(exp[0], exp[1], exp[2], limit=None, file=io_handler) io_handler.flush() else: exported_eds.append(export_reg.get_description()) # write exported_eds to filename EDEFWriter().write(exported_eds, self._edef_filename) io_handler.write_line( "Service={0} exported by {1} providers. EDEF written to file={2}", svc_ref, len(exported_eds), self._edef_filename, )
def remote_admin_event(self, event): # type: (RemoteServiceAdminEvent) -> None """ Handle a remote service admin event """ if event.get_type() == RemoteServiceAdminEvent.EXPORT_REGISTRATION: EDEFWriter().write([event.get_description()], self._edef_filename)
def _list_imports(self, session, import_regs, endpoint_id=None): # type: (ShellSession, List[ImportRegistration], str) -> None """ Lists the imported services """ if endpoint_id: matching_eds = [ x.get_description() for x in import_regs if x.get_description().get_id() == endpoint_id ] if matching_eds: session.write_line("Endpoint description for endpoint.id={0}:", endpoint_id) session.write_line(EDEFWriter().to_string(matching_eds)) else: title = ( "Endpoint ID", "Container ID", "Local Service ID", "Remote Service ID", ) rows = [] for import_reg in import_regs: ed = import_reg.get_description() rows.append(( ed.get_id(), ed.get_container_id()[1], import_reg.get_reference().get_property(SERVICE_ID), ed.get_service_id(), )) session.write_line(self._utils.make_table(title, rows))
def _show_edef(self, io_handler): # type: (ShellSession) -> None """ Show contents of EDEF file """ if not os.path.isfile(self._edef_filename): io_handler.write_line("EDEF file '{0}' does not exist!", self._edef_filename) else: with open(self._edef_filename, "r") as f: eds = EDEFReader().parse(f.read()) io_handler.write_line(EDEFWriter().to_string(eds))
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 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 test_export_import_update(self): """ Tests an export of a service (with XML-RPC) """ context = self.framework.get_bundle_context() # Start an HTTP server, required by XML-RPC context.install_bundle("pelix.http.basic").start() with use_ipopo(context) as ipopo: ipopo.instantiate( 'pelix.http.service.basic.factory', 'http-server', {'pelix.http.address': 'localhost', 'pelix.http.port': 0}) # Install the XML-RPC provider to have an endpoint # Indicate the XML-RPC server self.framework.add_property("ecf.xmlrpc.server.hostname", "localhost") context.install_bundle( "pelix.rsa.providers.distribution.xmlrpc").start() # Register a service to be exported spec = "test.svc" key = "foo" val_1 = "bar" val_2 = "fighters" svc_reg = context.register_service(spec, object(), {key: val_1}) svc_ref = svc_reg.get_reference() # Export the service export_regs = self.rsa.export_service( svc_ref, {rsa.SERVICE_EXPORTED_INTERFACES: '*', rsa.SERVICE_EXPORTED_CONFIGS: "ecf.xmlrpc.server"}) # Get the export endpoints export_reg = None export_endpoint = None for export_reg in export_regs: exp = export_reg.get_exception() if exp: self.fail("Error exporting service: {}".format(exp)) else: export_endpoint = export_reg.get_description() break # Export & import the EDEF XML edef_1 = EDEFWriter().to_string([export_endpoint]) parsed_endpoint = EDEFReader().parse(edef_1)[0] import_endpoint = None import_reg = self.rsa.import_service(parsed_endpoint) if import_reg: exp = import_reg.get_exception() if exp: self.fail("Error importing service: {}".format(exp)) else: import_endpoint = import_reg.get_description() # Get the imported service imported_svc_ref = context.get_service_reference( spec, "(service.imported=*)") # Check property value in export and import beans self.assertEqual(val_1, export_endpoint.get_properties()[key]) self.assertEqual(val_1, import_endpoint.get_properties()[key]) self.assertEqual(val_1, imported_svc_ref.get_property(key)) # Update service properties svc_reg.set_properties({key: val_2}) # Update the endpoint export_endpoint_2 = export_reg.get_export_reference().update({}) self.assertEqual(val_2, export_endpoint_2.get_properties()[key]) # Write & load it # Export & import the EDEF XML edef_2 = EDEFWriter().to_string([export_endpoint_2]) parsed_endpoint_2 = EDEFReader().parse(edef_2)[0] # Check parsed file self.assertEqual(val_2, parsed_endpoint_2.get_properties()[key]) import_endpoint_2 = None import_reg_2 = self.rsa.import_service(parsed_endpoint_2) if import_reg_2: exp = import_reg_2.get_exception() if exp: self.fail("Error re-importing service: {}".format(exp)) else: import_endpoint_2 = import_reg_2.get_description() # Check property value in export and import beans self.assertEqual(val_2, import_endpoint_2.get_properties()[key]) # Check if the imported have been updated self.assertEqual(val_2, imported_svc_ref.get_property(key))
def test_export_import(self): """ Tests an export of a service (with XML-RPC) """ context = self.framework.get_bundle_context() # Start an HTTP server, required by XML-RPC context.install_bundle("pelix.http.basic").start() with use_ipopo(context) as ipopo: ipopo.instantiate( 'pelix.http.service.basic.factory', 'http-server', {'pelix.http.address': 'localhost', 'pelix.http.port': 0}) # Install the XML-RPC provider to have an endpoint # Indicate the XML-RPC server self.framework.add_property("ecf.xmlrpc.server.hostname", "localhost") context.install_bundle( "pelix.rsa.providers.distribution.xmlrpc").start() # Register a service to be exported spec = "test.svc" svc = object() svc_reg = context.register_service(spec, svc, {}) svc_ref = svc_reg.get_reference() # Export the service export_regs = self.rsa.export_service( svc_ref, {rsa.SERVICE_EXPORTED_INTERFACES: '*', rsa.SERVICE_EXPORTED_CONFIGS: "ecf.xmlrpc.server"}) # Get the export endpoints export_endpoints = [] for export_reg in export_regs: exp = export_reg.get_exception() if exp: self.fail("Error exporting service: {}".format(exp)) export_endpoints.append(export_reg.get_description()) if not export_endpoints: self.fail("No exported endpoints") # Temporary file tmp_file = tempfile.mktemp() # Write the EDEF XML file EDEFWriter().write(export_endpoints, tmp_file) # Reload it with open(tmp_file, "r") as fd: parsed_endpoints = EDEFReader().parse(fd.read()) for parsed_endpoint in parsed_endpoints: import_reg = self.rsa.import_service(parsed_endpoint) if import_reg: exp = import_reg.get_exception() endpoint_desc = import_reg.get_description() if exp: self.fail("Error importing service: {}".format(exp)) else: break else: self.fail("No imported service")