def main(): # Create server # commented block is for 3.7 # with SimpleXMLRPCServer(('localhost', 8000), # requestHandler=RequestHandler) as server: server = SimpleXMLRPCServer( (HOST, PORT), requestHandler=SingleClientRequestHandler, allow_none=True, ) server.register_introspection_functions() controller = GoPiGoController() server.register_instance(controller) # Run the server's main loop uprint('Serving XML-RPC on {host}:{port}'.format(host=HOST, port=PORT)) try: server.serve_forever() except KeyboardInterrupt: uprint('\nKeyboard interrupt received, exiting.') server.shutdown() controller.cleanup() sys.exit(0) finally: del controller
class RPCServer(object): """ An aynchronous RPC server. """ def __init__(self, port, context): self.__running = False logging.info('Setting up an RPC server on port %d', port) self.__server = SimpleXMLRPCServer(("localhost", port), logRequests=False, allow_none=True) self.__server.register_function(context['api']['show_settings'], 'show_settings') self.__server.register_function(context['api']['show_about'], 'show_about') self.__server.register_function(context['api']['enable_safeeyes'], 'enable_safeeyes') self.__server.register_function(context['api']['disable_safeeyes'], 'disable_safeeyes') self.__server.register_function(context['api']['take_break'], 'take_break') self.__server.register_function(context['api']['quit'], 'quit') def start(self): """ Start the RPC server. """ if not self.__running: self.__running = True logging.info('Start the RPC server') server_thread = Thread(target=self.__server.serve_forever) server_thread.start() def stop(self): """ Stop the server. """ if self.__running: logging.info('Stop the RPC server') self.__running = False self.__server.shutdown()
class CallbackThread(threading.Thread): """Thread for XML-RPC callback server To prevent SimpleXMLRPCServer blocking whole app it is started in a thread """ def __init__(self, port): log("%s.%s port=%r", self.__class__.__name__, self.__init__.__name__, port) super().__init__() self.server = None self.callback = ClientCallback() self.port = port self.current_test_case = None def run(self): """Starts the xmlrpc callback server""" log("%s.%s", self.__class__.__name__, self.run.__name__) log("Serving on port %s ...", self.port) self.server = SimpleXMLRPCServer(("", self.port), allow_none=True, logRequests=False) self.server.register_instance(self.callback) self.server.register_introspection_functions() self.server.serve_forever() def stop(self): thread = threading.Thread(target=self._shutdown_thread) thread.start() thread.join() def _shutdown_thread(self): self.server.shutdown() def set_current_test_case(self, name): log("%s.%s %s", self.__class__.__name__, self.set_current_test_case.__name__, name) self.current_test_case = name def get_current_test_case(self): log("%s.%s %s", self.__class__.__name__, self.get_current_test_case.__name__, self.current_test_case) return self.current_test_case def error_code(self): log("%s.%s", self.__class__.__name__, self.error_code.__name__) return self.callback.error_code() def set_pending_response(self, pending_response): log("%s.%s, %r", self.__class__.__name__, self.set_pending_response.__name__, pending_response) return self.callback.set_pending_response(pending_response) def clear_pending_responses(self): log("%s.%s", self.__class__.__name__, self.clear_pending_responses.__name__) return self.callback.clear_pending_responses() def cleanup(self): log("%s.%s", self.__class__.__name__, self.cleanup.__name__) return self.callback.cleanup()
class Dispatcher(threading.Thread): def __init__(self, docker_image, input_file, port=0): threading.Thread.__init__(self) self.server = SimpleXMLRPCServer(('0.0.0.0', port), allow_none=True) self.server.register_instance(self) self.docker_image = docker_image self.input_file = input_file def run(self): self.server.serve_forever() def start_container(self, token): assert (token == '12345') input_file_host_path = os.path.abspath(self.input_file) self.input_file_container_path = '/grader/testing/input.file' self.container = docker_container_create(self.docker_image, ['sleep', 'infinity'], crippled=True) self.container.start() def stop(self): self.server.shutdown() def exec_step(self, token, command): assert (token == '12345') return docker_container_exec(self.container, command)
class RPCServer(threading.Thread): """ The RPCServer thread provides an API for external programs to interact with MOM. """ def __init__(self, config, momFuncs): threading.Thread.__init__(self, name="RPCServer") self.setDaemon(True) self.config = config self.momFuncs = momFuncs self.logger = logging.getLogger('mom.RPCServer') self.server = None self.start() def thread_ok(self): if self.server is None: return True return self.isAlive() def create_server(self): try: unix_port = None port = self.config.getint('main', 'rpc-port') except ValueError: port = None unix_port = self.config.get('main', 'rpc-port') self.logger.info("Using unix socket "+unix_port) if unix_port is None and (port is None or port < 0): return None if unix_port: self.server = UnixXmlRpcServer(unix_port) else: self.server = SimpleXMLRPCServer(("localhost", port), requestHandler=RequestHandler, logRequests=0) self.server.register_introspection_functions() self.server.register_instance(self.momFuncs) def shutdown(self): if self.server is not None: self.server.shutdown() def run(self): try: self.create_server() if self.server is not None: self.logger.info("RPC Server starting") self.server.serve_forever() self.logger.info("RPC Server ending") else: self.logger.info("RPC Server is disabled") except Exception as e: self.logger.error("RPC Server crashed", exc_info=True)
class SubAliveSlave: """ Class for handling a master's alive pings. If the alive timeouts, we can quit. """ def __init__(self): # print('starting with master alive period', master_alive_period_s) self.alive_check_period_s = _AlivePeriod_s * 1.5 # last time the master pinged alive self.prev_alive_ping_time = time.time() # previously received alive counter self.prev_alive_cnt = None # start RPC server for alive ping self.server = SimpleXMLRPCServer(_RPC_ADDRESS, logRequests=False) # register alive ping function, to be called by the master process self.server.register_function(self.alive, 'alive') # create and start the RPC server in a separate thread self.rpc_thread = threading.Thread(target=self.server.serve_forever) self.rpc_thread.start() # start the periodic timeout checker self.check_timeout() def alive(self, alive_cnt: int): """ Method to be called via RPC by the master :param alive_cnt: master increments it modulo _AliveCounterMax :return: 0, because xmlrpc requires something. """ # print('alive received', alive_cnt) if self.prev_alive_cnt is not None: if (alive_cnt - self.prev_alive_cnt) not in [1, 1 - _AliveCounterMax]: print('Invalid alive received.') self.prev_alive_cnt = alive_cnt self.prev_alive_ping_time = time.time() return 0 def check_timeout(self): """ Periodic timeout check for the master's alive ping """ # print('checking timeout') if time.time() - self.prev_alive_ping_time >= self.alive_check_period_s: # timeout, shutdown RPC server and quit. self.server.shutdown() print('timeout, closing.') self.rpc_thread.join(timeout=5) # time.sleep(2) exit(0) else: pass # print(' ok') # reschedule timeout checking threading.Timer(self.alive_check_period_s, self.check_timeout).start()
class XmlRpcServer(object): """ XMLRPC service, exported functions are in class _RpcFuncs """ def __init__(self, host, port): self._server = SimpleXMLRPCServer((host, port)) self._server.register_introspection_functions() self._server.register_instance(_RpcFuncs()) logger.info('Listening for XMLRPC clients on %s:%d', host, port) self._server.serve_forever() def shutdown(self): self._server.shutdown()
class RemoteController(metaclass=Singleton): """ Provide control over a SimpleXMLRPCServer. """ def __init__(self, ip='localhost', port=8070): try: self.server = SimpleXMLRPCServer((ip, port), allow_none=True, logRequests=False) self._announcer = Announcer() except OSError as error: # If address already in use if error.errno == 98: raise Exception( "Only one application instance can use this module") else: raise error self.server.register_introspection_functions() self.server.register_instance(RemoteDispatcher()) @async def start(self): logging.info('REMOTE: Session started at ' + str(self.server.server_address)) self._announcer.start() self.server.serve_forever() # Blocking self._announcer.stop() logging.info('REMOTE: Session ended') def stop(self): self.server.shutdown() @staticmethod def connect_to(uri): proxy = ServerProxy(uri, transport=TimeoutTransport()) try: # Call a fictive method. proxy._() except Fault: # Connected, the method doesn't exist, which is expected. pass except socket.error: # Not connected, socket error mean that the service is unreachable. raise OSError('Session at ' + uri + ' is unreachable') # Just in case the method is registered in the XmlRPC server return proxy
class RemoteController(metaclass=Singleton): """ Provide control over a SimpleXMLRPCServer. """ def __init__(self, ip='localhost', port=8070): try: self.server = SimpleXMLRPCServer((ip, port), allow_none=True, logRequests=False) self._announcer = Announcer() except OSError as error: # If address already in use if error.errno == 98: raise Exception( "Only one application instance can use this module") else: raise error self.server.register_introspection_functions() self.server.register_instance(RemoteDispatcher()) @async_function def start(self): logging.info('REMOTE: Session started at ' + str(self.server.server_address)) self._announcer.start() self.server.serve_forever() # Blocking self._announcer.stop() logging.info('REMOTE: Session ended') def stop(self): self.server.shutdown() @staticmethod def connect_to(uri): proxy = ServerProxy(uri, transport=TimeoutTransport()) try: # Call a fictive method. proxy._() except Fault: # Connected, the method doesn't exist, which is expected. pass except socket.error: # Not connected, socket error mean that the service is unreachable. raise OSError('Session at ' + uri + ' is unreachable') # Just in case the method is registered in the XmlRPC server return proxy
def main(): server_address = (Communicator.LOCALHOST, Communicator().com_registry["hmc"]) # Enabled by default logging causes RPC to malfunction when the GUI runs on # pythonw. Explicitly disable logging for the XML server. server = SimpleXMLRPCServer(server_address, logRequests=False, allow_none=True) app = QApplication(sys.argv) window = SettingsDialog(server) window.show() exit_code = app.exec_() server.shutdown() sys.exit(exit_code)
class RPCServer: def __init__(self, addr, port, peer): self.peer = peer self._server = SimpleXMLRPCServer((addr, port)) self._server.register_function(self.peer.append_entry, "append_entry") self._server.register_function(self.peer.request_vote, "request_vote") def start(self): server_thread = threading.Thread(target=self._server.serve_forever) server_thread.daemn = True server_thread.start() def close(self): self._server.shutdown() self._server.server_close()
class RemoteController(Thread, metaclass=Singleton): def __init__(self, ip='localhost', port=8070): super().__init__(daemon=True) self.setName('RemoteController') self.server = SimpleXMLRPCServer((ip, port), allow_none=True, logRequests=False) self.server.register_introspection_functions() self.server.register_instance(RemoteDispatcher()) self._announcer = Announcer() def start(self): self._announcer.start() Thread.start(self) def run(self): logging.info('REMOTE: Session started at ' + str(self.server.server_address)) self.server.serve_forever() logging.info('REMOTE: Session ended') def stop(self): self.server.shutdown() self._announcer.stop() @staticmethod def connect_to(uri): proxy = ServerProxy(uri, transport=TimeoutTransport()) try: # Call a fictive method. proxy._() except Fault: # Connected, the method doesn't exist, which is expected. pass except socket.error: # Not connected, socket error mean that the service is unreachable. raise Exception('Session at ' + uri + ' is unreachable') # Just in case the method is registered in the XmlRPC server return proxy
class RTevald(): def __init__(self, options, log): self.options = options self.log = log self.server = None self.config = RTevald_config() def __prepare_datadir(self): startdir = os.getcwd() for dir in self.config.datadir.split("/"): if dir is '': continue if not os.path.exists(dir): os.mkdir(dir, 0o700) os.chdir(dir) if not os.path.exists('queue'): os.mkdir('queue', 0o700) os.chdir(startdir) def StartServer(self): # Create server self.server = SimpleXMLRPCServer( (self.options.listen, self.options.port), requestHandler=RequestHandler) self.server.register_introspection_functions() # setup a class to handle requests self.server.register_instance( xmlrpc_API1.XMLRPC_API1(self.config, nodbaction=True, debug=True)) # Run the server's main loop self.log.Log( "StartServer", "Listening on %s:%i" % (self.options.listen, self.options.port)) try: self.__prepare_datadir() self.server.serve_forever() except KeyboardInterrupt: self.log.Log("StartServer", "Server caught SIGINT") self.server.shutdown() finally: self.log.Log("StartServer", "Server stopped") def StopServer(self): self.server.shutdown()
class PilotwireServer: def __init__(self, port, debug, controller_name): self.xmlrpc_server = SimpleXMLRPCServer(('', port), logRequests=debug) manager = DriverManager( namespace='pilotwire.controller', name=controller_name, invoke_on_load=True, ) self.controller = manager.driver self.xmlrpc_server.register_instance(XMLRPCMethods(self.controller)) def start(self): self.xmlrpc_server.serve_forever() def stop(self): self.xmlrpc_server.shutdown() self.xmlrpc_server.server_close()
class DispatchService: """ Service providing access to the dispatcher """ def __init__(self, dispatcher: Dispatcher, bind_address): self._server = SimpleXMLRPCServer(bind_address, SimpleXMLRPCRequestHandler, allow_none=True, logRequests=False) self._server.register_instance(DispatchServiceInterface(dispatcher)) def serve_forever(self): """ Serves until shutdown """ self._server.serve_forever() def shutdown(self): """ Stops the serve_forever loop """ self._server.shutdown() def server_close(self): """ Cleans-up the server: releases all resources used by the server """ self._server.server_close()
class RPCUtilities: """Useful functions exposed to RPC server""" server: Optional[SimpleXMLRPCServer] = None def __init__(self, channel: 'TelegramChannel'): self.channel = channel rpc_config = self.channel.config.get('rpc') if not rpc_config: return # Restrict to a particular path. class RequestHandler(SimpleXMLRPCRequestHandler): rpc_paths = ('/', '/RPC2') server_addr = rpc_config['server'] port = rpc_config['port'] self.server = SimpleXMLRPCServer((server_addr, port), requestHandler=RequestHandler) self.server.register_introspection_functions() self.server.register_multicall_functions() self.server.register_instance(self.channel.db) self.server.register_function(self.get_slave_channels_ids) # type: ignore # TODO: Wait for https://github.com/python/typeshed/pull/4165 to be pushed to pypi with mypy threading.Thread(target=self.server.serve_forever, name="ETM RPC server thread") def shutdown(self): """Shutdown RPC server if running.""" if self.server: self.server.shutdown() @staticmethod def get_slave_channels_ids() -> List[str]: """Get the collection of slave channel IDs in current instance""" return list(coordinator.slaves.keys())
def main(): try: if os.path.exists("products.pickle"): try: products = open("products.pickle", "rb") inventory = pickle.load(products) except EOFError: inventory = Inventory() else: inventory = Inventory() server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) inventory_system_pb2_grpc.add_InventorySystemServicer_to_server( InventorySystem(inventory), server) server.add_insecure_port('[::]:50051') server.start() server_xml = SimpleXMLRPCServer(("", 25565)) XMLRPC.start_xml(server_xml, inventory) server.wait_for_termination() except KeyboardInterrupt: server_xml.shutdown() products = open("products.pickle", "wb") pickle.dump(inventory, products) products.close()
class myServiceServer(Thread): def __init__(self, ip, port): #super(myServiceServer, self).__init__() self.running = True self._Host = ip self._Port = port #self.server = SimpleXMLRPCServer((self._Host, self._Port), allow_none = True) self.server = SimpleXMLRPCServer((self._Host, self._Port), logRequests=False, allow_none=True) self.server.register_introspection_functions() Thread.__init__(self) def register_function(self, function): self.server.register_function(function) def run(self): self.server.serve_forever() def stop_server(self): self.server.shutdown()
class server: """ handles xmlrpc comms to/from the control software """ rpc_server = None def __init__(self, interface, port): self.rpc_server = SimpleXMLRPCServer((interface, port), requestHandler=RequestHandler) self.rpc_server.register_introspection_functions() self.rpc_server.serve_forever def __del__(self): try: self.rpc_server.shutdown() except: pass def run_server(self): self.rpc_server.serve_forever() def stop_server(self): self.rpc_server.shutdown()
class FakeNeosServer: def __init__(self, solution): self.service = FakeNeosService(solution) # Create server self.server = SimpleXMLRPCServer( ("localhost", 8000), logRequests=False) self.server.register_introspection_functions() self.server.register_instance(self.service) self.server.register_multicall_functions() self.thread = Thread(target=self.run) self.thread.start() def run(self): # Run the server's main loop self.server.serve_forever() def stop(self): if self.server is not None: self.server.shutdown() self.server.server_close() self.server = None
class CoinpyDaemonRPCServer(object): def __init__(self, loop: asyncio.AbstractEventLoop, node: Node, **config: Any) -> None: self.__io_loop = loop self.__node = node self.__RPCserver = None if 'rpcbind' in config: _, host, port = config['rpcbind'] logger.info(f'starting rpc server {(host, port)}') self.__RPCserver = SimpleXMLRPCServer( (host, port), logRequests=True, requestHandler=CoinpyDaemonRPCHandler) # rpc procedures def stop_daemon_cmd(): self.__io_loop.call_soon_threadsafe(self.__node.stop_sync) return 'daemon stopped' self.__RPCserver.register_function(stop_daemon_cmd, 'stop') def addnode_daemon_cmd(): return 'neighbor added' self.__RPCserver.register_function(addnode_daemon_cmd, 'addnode') def stop(self) -> None: if self.__RPCserver is not None: logger.info('stopping rpc server') self.__RPCserver.shutdown() self.__RPCserver.server_close() def run(self) -> None: if self.__RPCserver is not None: self.__io_loop.run_in_executor(None, self.__RPCserver.serve_forever)
class ServerThread(threading.Thread): """XML-RPC server thread to handle messages from CCU / Homegear""" def __init__(self, local=LOCAL, localport=LOCALPORT): self._local = local self._localport = localport LOG.debug("ServerThread.__init__") threading.Thread.__init__(self) # Create proxies to interact with CCU / Homegear LOG.debug("__init__: Registering RPC methods") self._rpcfunctions = RPCFunctions() # Setup server to handle requests from CCU / Homegear LOG.debug("ServerThread.__init__: Setting up server") self.server = SimpleXMLRPCServer((self._local, self._localport), requestHandler=RequestHandler, logRequests=False) self._localport = self.server.socket.getsockname()[1] self.server.register_introspection_functions() self.server.register_multicall_functions() LOG.debug("ServerThread.__init__: Registering RPC functions") self.server.register_instance(self._rpcfunctions, allow_dotted_names=True) def run(self): LOG.info("Starting server at http://%s:%i" % (self._local, self._localport)) self.server.serve_forever() def stop(self): """Shut down our XML-RPC server.""" LOG.info("Shutting down server") self.server.shutdown() LOG.debug("ServerThread.stop: Stopping ServerThread") self.server.server_close() LOG.info("Server stopped")
class Source(threading.Thread): """ Facade for simple remote communication using XMLRPCServer. """ def __init__(self, addr): threading.Thread.__init__(self) ip, port = addr self.addr = addr self.server = SimpleXMLRPCServer((ip, port), requestHandler=RequestHandler, logRequests=False, allow_none=True) # self.server.register_introspection_functions() def register_function(self, func): self.server.register_function(func, 'send') def run(self): self.server.serve_forever() def stop(self): self.server.shutdown() self.server.server_close()
class DroidMaster(object): """ The main class of droidmaster DroidMaster currently supports QEMU instance pool only """ # this is a single instance class instance = None POLL_INTERVAL = 1 def __init__(self, app_path=None, is_emulator=False, output_dir=None, env_policy=None, policy_name=None, random_input=False, script_path=None, event_count=None, event_interval=None, timeout=None, keep_app=None, keep_env=False, cv_mode=False, debug_mode=False, profiling_method=None, grant_perm=False, enable_accessibility_hard=False, qemu_hda=None, qemu_no_graphic=False, humanoid=None, ignore_ad=False, replay_output=None): """ initiate droidmaster, and initiate droidbot's with configurations :return: """ logging.basicConfig(level=logging.DEBUG if debug_mode else logging.INFO) self.logger = logging.getLogger('DroidMaster') DroidMaster.instance = self # 1. Save DroidBot Parameters self.app_path = app_path self.is_emulator = is_emulator self.output_dir = output_dir if not os.path.isdir(output_dir): os.makedirs(output_dir) self.env_policy = env_policy self.policy_name = policy_name self.random_input = random_input self.script_path = script_path self.event_count = event_count self.event_interval = event_interval self.timeout = timeout self.keep_app = keep_app self.keep_env = keep_env self.cv_mode = cv_mode self.debug_mode = debug_mode self.profiling_method = profiling_method self.grant_perm = grant_perm self.enable_accessibility_hard = enable_accessibility_hard self.humanoid = humanoid self.ignore_ad = ignore_ad self.replay_output = replay_output # 2. Initiate Device Pool self.domain = "localhost" self.rpc_port = Device(device_serial="").get_random_port() self.qemu_hda = qemu_hda self.qemu_no_graphic = qemu_no_graphic self.device_pool_capacity = 6 self.device_pool = {} self.device_unique_id = 0 self.app = App(app_path, output_dir=self.output_dir) self.qemu_app_hda = "%s_%s" % (self.qemu_hda, self.app.get_package_name()) for i in range(self.device_pool_capacity): adb_port = Device(device_serial="").get_random_port() device_serial = "%s:%s" % (self.domain, adb_port) qemu_port = Device(device_serial="").get_random_port() device = Device( device_serial=device_serial, is_emulator=self.is_emulator, output_dir=self.output_dir, cv_mode=self.cv_mode, grant_perm=self.grant_perm, enable_accessibility_hard=self.enable_accessibility_hard) self.device_pool[device_serial] = { "domain": self.domain, "adb_port": adb_port, "qemu_port": qemu_port, # droidbot is indexed by device_serial # qemu is indexed by droidbot "droidbot": None, "qemu": None, "id": None, "device": device } self.logger.info(self.device_pool) # 2. This Server's Parameter self.timer = None self.enabled = True self.successful_spawn_events = set() @staticmethod def get_instance(): if DroidMaster.instance is None: print("Error: DroidMaster is not initiated!") sys.exit(-1) return DroidMaster.instance def get_available_devices(self): return sorted([self.device_pool[x] for x in self.device_pool if self.device_pool[x]["droidbot"] is None and \ self.device_pool[x]["qemu"] is None], key=lambda x: x["adb_port"]) def get_running_devices(self): return sorted([self.device_pool[x] for x in self.device_pool if self.device_pool[x]["droidbot"] is not None and \ self.device_pool[x]["qemu"] is not None], key=lambda x: x["adb_port"]) def start_device(self, device, hda, from_snapshot=False, init_script_path=None): # 1. get device ID device["id"] = self.device_unique_id # 2. new QEMU adapter device["qemu"] = QEMUConn(hda, device["qemu_port"], device["adb_port"], self.qemu_no_graphic) device["qemu"].set_up() device["qemu"].connect(from_snapshot) # 3. new DroidWorker adapter script_path = init_script_path if init_script_path else self.script_path device["droidbot"] = DroidBotConn(device["id"], app_path=self.app_path, device_serial=device["device"].serial, is_emulator=self.is_emulator, output_dir=self.output_dir, env_policy=self.env_policy, policy_name=self.policy_name, random_input=self.random_input, script_path=script_path, event_count=self.event_count, event_interval=self.event_interval, timeout=self.timeout, keep_app=self.keep_app, keep_env=self.keep_env, cv_mode=self.cv_mode, debug_mode=self.debug_mode, profiling_method=self.profiling_method, grant_perm=self.grant_perm, enable_accessibility_hard=self.enable_accessibility_hard, master="http://%s:%d/" % (self.domain, self.rpc_port), humanoid=self.humanoid, ignore_ad=self.ignore_ad, replay_output=self.replay_output) device["droidbot"].set_up() self.logger.info("Worker: DOMAIN[%s], ADB[%s], QEMU[%d], ID[%d]" % (device["domain"], device["adb_port"], device["qemu_port"], device["id"])) self.device_unique_id += 1 def stop_device(self, device): device["droidbot"].tear_down() device["droidbot"].disconnect() device["droidbot"] = None device["qemu"].disconnect() device["qemu"].tear_down() device["qemu"] = None def qemu_create_img(self, new_hda, back_hda): self.logger.info("%s -> %s" % (back_hda, new_hda)) p = subprocess.Popen(["qemu-img", "create", "-f", "qcow2", new_hda, "-o", "backing_file=%s" % back_hda, "8G"]) p.wait() def spawn(self, device_serial, init_script_json): """ A worker requests to spawn a new worker based on its current state """ if init_script_json in self.successful_spawn_events: self.logger.warning("Event spawned already") return False available_devices = self.get_available_devices() if not len(available_devices): self.logger.warning("No available device slot") return False calling_device = self.device_pool[device_serial] calling_device["qemu"].send_command("stop") calling_device["qemu"].send_command("savevm spawn") # copy qemu image file (almost RAM image size only) new_hda = "%s.%d" % (self.qemu_app_hda, self.device_unique_id) shutil.copyfile(calling_device["qemu"].hda, new_hda) # prepare init script file init_script_path = os.path.join(self.output_dir, "%d.json" % self.device_unique_id) with open(init_script_path, "w") as init_script_file: init_script_file.write(init_script_json) self.start_device(available_devices[0], new_hda, from_snapshot=True, init_script_path=init_script_path) calling_device["qemu"].send_command("delvm spawn") calling_device["qemu"].send_command("cont") self.successful_spawn_events.add(init_script_json) self.logger.info("Spawning worker") return True def start_worker(self): """ Start the first worker (with device 0), used by DroidMaster itself """ available_devices = self.get_available_devices() if not len(available_devices): self.logger.warning("No available device slot") return False device = available_devices[0] # if app image doesn't exist, create it first if not os.path.exists(self.qemu_app_hda): self.qemu_create_img(self.qemu_app_hda, self.qemu_hda) app_install_qemu = QEMUConn(self.qemu_app_hda, device["qemu_port"], device["adb_port"], self.qemu_no_graphic) app_install_qemu.set_up() app_install_qemu.connect() device["device"].wait_for_device() device["device"].install_app(self.app) app_install_qemu.disconnect() device["device"].shutdown() app_install_qemu.tear_down() new_hda = "%s.%d" % (self.qemu_app_hda, self.device_unique_id) self.qemu_create_img(new_hda, self.qemu_app_hda) self.start_device(available_devices[0], new_hda) return True def stop_worker(self, device_serial): self.stop_device(self.device_pool[device_serial]) def start_daemon(self): self.server = SimpleXMLRPCServer((self.domain, self.rpc_port), RPCHandler) print("Listening on port %s..." % self.rpc_port) self.server.register_function(self.spawn, "spawn") self.server.register_function(self.start_worker, "start_worker") self.server.register_function(self.stop_worker, "stop_worker") self.server.serve_forever() def stop_daemon(self): print("Shutting down DroidMaster server...") self.server.shutdown() self.server_thread.join(0) def start(self): """ start interacting :return: """ if not self.enabled: return self.logger.info("Starting DroidMaster") try: if self.timeout > 0: self.timer = threading.Timer(self.timeout, self.stop) self.timer.start() if not self.enabled: return # enable server listening workers self.server_thread = threading.Thread(target=self.start_daemon) self.server_thread.daemon = True self.server_thread.start() time.sleep(1) # wait server to start # create first droidbot instance proxy = ServerProxy("http://%s:%d/" % (self.domain, self.rpc_port)) proxy.start_worker() while len(self.get_running_devices()): time.sleep(self.POLL_INTERVAL) except KeyboardInterrupt: self.logger.info("Keyboard interrupt.") pass except Exception: import traceback traceback.print_exc() self.stop() sys.exit(-1) self.stop() self.logger.info("DroidMaster Stopped") def stop(self): self.enabled = False if self.timer and self.timer.isAlive(): self.timer.cancel() # stop listening server self.stop_daemon() # stop all workers running_devices = self.get_running_devices() for device in running_devices: self.stop_device(device)
class ServerThread(threading.Thread): """XML-RPC server thread to handle messages from CCU / Homegear""" def __init__(self, local=LOCAL, localport=LOCALPORT, remotes=REMOTES, devicefile=DEVICEFILE, paramsetfile=PARAMSETFILE, interface_id=INTERFACE_ID, eventcallback=False, systemcallback=False, resolveparamsets=False): LOG.debug("ServerThread.__init__") threading.Thread.__init__(self) # Member self._interface_id = interface_id self._local = local self._localport = int(localport) self._devicefile = devicefile self._paramsetfile = paramsetfile self.remotes = remotes self.eventcallback = eventcallback self.systemcallback = systemcallback self.resolveparamsets = resolveparamsets self.proxies = {} self.failed_inits = [] self.createProxies() if not self.proxies: LOG.warning("No proxies available. Aborting.") raise Exception self._rpcfunctions = RPCFunctions(devicefile=self._devicefile, paramsetfile=self._paramsetfile, proxies=self.proxies, remotes=self.remotes, eventcallback=self.eventcallback, systemcallback=self.systemcallback, resolveparamsets=self.resolveparamsets) # Setup server to handle requests from CCU / Homegear LOG.debug("ServerThread.__init__: Setting up server") # class SimpleThreadedXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer): # pass # self.server = SimpleThreadedXMLRPCServer((self._local, self._localport), # requestHandler=RequestHandler, # logRequests=False) self.server = SimpleXMLRPCServer((self._local, self._localport), requestHandler=RequestHandler, logRequests=False) self._localport = self.server.socket.getsockname()[1] self.server.register_introspection_functions() self.server.register_multicall_functions() LOG.debug("ServerThread.__init__: Registering RPC functions") self.server.register_instance( self._rpcfunctions, allow_dotted_names=True) def run(self): LOG.info("Starting server at http://%s:%i" % (self._local, self._localport)) self.server.serve_forever() def createProxies(self): """Create proxies to interact with CCU / Homegear""" LOG.debug("createProxies: Creating proxies") for remote, host in self.remotes.items(): # Initialize XML-RPC try: socket.gethostbyname(host['ip']) except Exception as err: LOG.warning("Skipping proxy: %s" % str(err)) continue if 'path' not in host: host['path'] = '' LOG.info("Creating proxy %s. Connecting to %s:%i%s" % (remote, host['ip'], host['port'], host['path'])) host['id'] = "%s-%s" % (self._interface_id, remote) try: api_url = build_api_url(host=host['ip'], port=host['port'], path=host['path'], username=host.get('username'), password=host.get('password'), ssl=host.get('ssl')) self.proxies[host['id']] = LockingServerProxy( api_url, remote=remote, callbackip=host.get('callbackip', None), callbackport=host.get('callbackport', None), skipinit=not host.get('connect', True), ssl=host.get('ssl', False), verify_ssl=host.get('verify_ssl', True)) except Exception as err: LOG.warning("Failed connecting to proxy at http://%s:%i%s" % (host['ip'], host['port'], host['path'])) LOG.debug("__init__: Exception: %s" % str(err)) # pylint: disable=raise-missing-from raise Exception try: host['type'] = BACKEND_UNKNOWN #if "Homegear" in self.proxies[host['id']].getVersion(): # LOG.debug("__init__: Host is Homegear") # host['type'] = BACKEND_HOMEGEAR #else: # LOG.debug("__init__: Host is CCU") # host['type'] = BACKEND_CCU except Exception as err: LOG.warning("__init__: Failed to detect backend type: %s" % str(err)) host['type'] = BACKEND_UNKNOWN def clearProxies(self): """Remove existing proxy objects.""" LOG.debug("clearProxies: Clearing proxies") self.proxies.clear() def proxyInit(self): """ To receive events the proxy has to tell the CCU / Homegear where to send the events. For that we call the init-method. """ # Call init() with local XML RPC config and interface_id (the name of # the receiver) to receive events. XML RPC server has to be running. for interface_id, proxy in self.proxies.items(): if proxy._skipinit: LOG.warning("Skipping init for %s", interface_id) continue if proxy._callbackip and proxy._callbackport: callbackip = proxy._callbackip callbackport = proxy._callbackport else: callbackip = proxy._localip callbackport = self._localport LOG.debug("ServerThread.proxyInit: init('http://%s:%i', '%s')" % (callbackip, callbackport, interface_id)) try: # For HomeMatic IP, init is not working correctly. We fetch the device list and create # the device objects before the init is performed. if proxy._remoteport in [2010, 32010, 42010]: dev_list = proxy.listDevices(interface_id) self._rpcfunctions.newDevices(interface_id=interface_id, dev_descriptions=dev_list) proxy.init("http://%s:%i" % (callbackip, callbackport), interface_id) LOG.info("Proxy for %s initialized", interface_id) except Exception as err: LOG.debug("proxyInit: Exception: %s" % str(err)) LOG.warning("Failed to initialize proxy for %s", interface_id) self.failed_inits.append(interface_id) def proxyDeInit(self): """De-Init from the proxies.""" stopped = [] for interface_id, proxy in self.proxies.items(): if interface_id in self.failed_inits: LOG.warning("ServerThread.proxyDeInit: Not performing de-init for %s", interface_id) continue if proxy._callbackip and proxy._callbackport: callbackip = proxy._callbackip callbackport = proxy._callbackport else: callbackip = proxy._localip callbackport = self._localport remote = "http://%s:%i" % (callbackip, callbackport) LOG.debug("ServerThread.proxyDeInit: init('%s')", remote) if not interface_id in stopped: try: proxy.init(remote) stopped.append(interface_id) LOG.info("proxyDeInit: Proxy for %s de-initialized: %s", interface_id, remote) except Exception as err: LOG.debug("proxyDeInit: Exception: %s", err) LOG.warning("proxyDeInit: Failed to de-initialize proxy") def stop(self): """To stop the server we de-init from the CCU / Homegear, then shut down our XML-RPC server.""" self.proxyDeInit() self.clearProxies() LOG.info("Shutting down server") self.server.shutdown() LOG.debug("ServerThread.stop: Stopping ServerThread") self.server.server_close() LOG.info("HomeMatic XML-RPC Server stopped") def parseCCUSysVar(self, data): """Helper to parse type of system variables of CCU""" if data['type'] == 'LOGIC': return data['name'], data['value'] == 'true' elif data['type'] == 'NUMBER': return data['name'], float(data['value']) elif data['type'] == 'LIST': return data['name'], int(data['value']) else: return data['name'], data['value'] def jsonRpcLogin(self, remote): """Login to CCU and return session""" session = False try: params = {"username": self.remotes[remote][ 'username'], "password": self.remotes[remote]['password']} response = self._rpcfunctions.jsonRpcPost( self.remotes[remote]['ip'], self.remotes[remote].get('jsonport', DEFAULT_JSONPORT), "Session.login", params) if response['error'] is None and response['result']: session = response['result'] if not session: LOG.warning( "ServerThread.jsonRpcLogin: Unable to open session.") except Exception as err: LOG.debug( "ServerThread.jsonRpcLogin: Exception while logging in via JSON-RPC: %s" % str(err)) return session def jsonRpcLogout(self, remote, session): """Logout of CCU""" logout = False try: params = {"_session_id_": session} response = self._rpcfunctions.jsonRpcPost( self.remotes[remote]['ip'], self.remotes[remote].get('jsonport', DEFAULT_JSONPORT), "Session.logout", params) if response['error'] is None and response['result']: logout = response['result'] except Exception as err: LOG.debug( "ServerThread.jsonRpcLogout: Exception while logging in via JSON-RPC: %s" % str(err)) return logout def getAllSystemVariables(self, remote): """Get all system variables from CCU / Homegear""" variables = {} if self.remotes[remote]['username'] and self.remotes[remote]['password']: LOG.debug( "ServerThread.getAllSystemVariables: Getting all System variables via JSON-RPC") session = self.jsonRpcLogin(remote) if not session: return try: params = {"_session_id_": session} response = self._rpcfunctions.jsonRpcPost( self.remotes[remote]['ip'], self.remotes[remote].get('jsonport', DEFAULT_JSONPORT), "SysVar.getAll", params) if response['error'] is None and response['result']: for var in response['result']: key, value = self.parseCCUSysVar(var) variables[key] = value self.jsonRpcLogout(remote, session) except Exception as err: self.jsonRpcLogout(remote, session) LOG.warning( "ServerThread.getAllSystemVariables: Exception: %s" % str(err)) else: try: variables = self.proxies[ "%s-%s" % (self._interface_id, remote)].getAllSystemVariables() except Exception as err: LOG.debug( "ServerThread.getAllSystemVariables: Exception: %s" % str(err)) return variables def getSystemVariable(self, remote, name): """Get single system variable from CCU / Homegear""" var = None if self.remotes[remote]['username'] and self.remotes[remote]['password']: LOG.debug( "ServerThread.getSystemVariable: Getting System variable via JSON-RPC") session = self.jsonRpcLogin(remote) if not session: return try: params = {"_session_id_": session, "name": name} response = self._rpcfunctions.jsonRpcPost( self.remotes[remote]['ip'], self.remotes[remote].get('jsonport', DEFAULT_JSONPORT), "SysVar.getValueByName", params) if response['error'] is None and response['result']: try: var = float(response['result']) except Exception as err: var = response['result'] == 'true' self.jsonRpcLogout(remote, session) except Exception as err: self.jsonRpcLogout(remote, session) LOG.warning( "ServerThread.getSystemVariable: Exception: %s" % str(err)) else: try: var = self.proxies[ "%s-%s" % (self._interface_id, remote)].getSystemVariable(name) except Exception as err: LOG.debug( "ServerThread.getSystemVariable: Exception: %s" % str(err)) return var def deleteSystemVariable(self, remote, name): """Delete a system variable from CCU / Homegear""" if self.remotes[remote]['username'] and self.remotes[remote]['password']: LOG.debug( "ServerThread.deleteSystemVariable: Getting System variable via JSON-RPC") session = self.jsonRpcLogin(remote) if not session: return try: params = {"_session_id_": session, "name": name} response = self._rpcfunctions.jsonRpcPost( self.remotes[remote]['ip'], self.remotes[remote].get('jsonport', DEFAULT_JSONPORT), "SysVar.deleteSysVarByName", params) if response['error'] is None and response['result']: deleted = response['result'] LOG.warning( "ServerThread.deleteSystemVariable: Deleted: %s" % str(deleted)) self.jsonRpcLogout(remote, session) except Exception as err: self.jsonRpcLogout(remote, session) LOG.warning( "ServerThread.deleteSystemVariable: Exception: %s" % str(err)) else: try: return self.proxies["%s-%s" % (self._interface_id, remote)].deleteSystemVariable(name) except Exception as err: LOG.debug( "ServerThread.deleteSystemVariable: Exception: %s" % str(err)) def setSystemVariable(self, remote, name, value): """Set a system variable on CCU / Homegear""" if self.remotes[remote]['username'] and self.remotes[remote]['password']: LOG.debug( "ServerThread.setSystemVariable: Setting System variable via JSON-RPC") session = self.jsonRpcLogin(remote) if not session: return try: params = {"_session_id_": session, "name": name, "value": value} if value is True or value is False: params['value'] = int(value) response = self._rpcfunctions.jsonRpcPost( self.remotes[remote]['ip'], self.remotes[remote].get('jsonport', DEFAULT_JSONPORT), "SysVar.setBool", params) else: response = self._rpcfunctions.jsonRpcPost( self.remotes[remote]['ip'], self.remotes[remote].get('jsonport', DEFAULT_JSONPORT), "SysVar.setFloat", params) if response['error'] is None and response['result']: res = response['result'] LOG.debug( "ServerThread.setSystemVariable: Result while setting variable: %s" % str(res)) else: if response['error']: LOG.debug("ServerThread.setSystemVariable: Error while setting variable: %s" % str( response['error'])) self.jsonRpcLogout(remote, session) except Exception as err: self.jsonRpcLogout(remote, session) LOG.warning( "ServerThread.setSystemVariable: Exception: %s" % str(err)) else: try: return self.proxies["%s-%s" % (self._interface_id, remote)].setSystemVariable(name, value) except Exception as err: LOG.debug( "ServerThread.setSystemVariable: Exception: %s" % str(err)) def getServiceMessages(self, remote): """Get service messages from CCU / Homegear""" try: return self.proxies["%s-%s" % (self._interface_id, remote)].getServiceMessages() except Exception as err: LOG.debug("ServerThread.getServiceMessages: Exception: %s" % str(err)) def rssiInfo(self, remote): """Get RSSI information for all devices from CCU / Homegear""" try: return self.proxies["%s-%s" % (self._interface_id, remote)].rssiInfo() except Exception as err: LOG.debug("ServerThread.rssiInfo: Exception: %s" % str(err)) def setInstallMode(self, remote, on=True, t=60, mode=1, address=None): """Activate or deactivate installmode on CCU / Homegear""" try: args = [on] if on and t: args.append(t) if address: args.append(address) else: args.append(mode) return self.proxies["%s-%s" % (self._interface_id, remote)].setInstallMode(*args) except Exception as err: LOG.debug("ServerThread.setInstallMode: Exception: %s" % str(err)) def getInstallMode(self, remote): """Get remaining time in seconds install mode is active from CCU / Homegear""" try: return self.proxies["%s-%s" % (self._interface_id, remote)].getInstallMode() except Exception as err: LOG.debug("ServerThread.getInstallMode: Exception: %s" % str(err)) def getAllMetadata(self, remote, address): """Get all metadata of device""" try: return self.proxies["%s-%s" % (self._interface_id, remote)].getAllMetadata(address) except Exception as err: LOG.debug("ServerThread.getAllMetadata: Exception: %s" % str(err)) def getMetadata(self, remote, address, key): """Get metadata of device""" try: return self.proxies["%s-%s" % (self._interface_id, remote)].getMetadata(address, key) except Exception as err: LOG.debug("ServerThread.getMetadata: Exception: %s" % str(err)) def setMetadata(self, remote, address, key, value): """Set metadata of device""" try: return self.proxies["%s-%s" % (self._interface_id, remote)].setMetadata(address, key, value) except Exception as err: LOG.debug("ServerThread.setMetadata: Exception: %s" % str(err)) def deleteMetadata(self, remote, address, key): """Delete metadata of device""" try: return self.proxies["%s-%s" % (self._interface_id, remote)].deleteMetadata(address, key) except Exception as err: LOG.debug("ServerThread.deleteMetadata: Exception: %s" % str(err)) def listBidcosInterfaces(self, remote): """Return all available BidCos Interfaces""" try: return self.proxies["%s-%s" % (self._interface_id, remote)].listBidcosInterfaces() except Exception as err: LOG.debug( "ServerThread.listBidcosInterfaces: Exception: %s" % str(err)) def ping(self, remote): """Send ping to CCU/Homegear to generate PONG event""" try: self.proxies["%s-%s" % (self._interface_id, remote)].ping("%s-%s" % (self._interface_id, remote)) except Exception as err: LOG.warning("ServerThread.ping: Exception: %s" % str(err)) def homegearCheckInit(self, remote): """Check if proxy is still initialized""" rdict = self.remotes.get(remote) if not rdict: return False if rdict.get('type') != BACKEND_HOMEGEAR: return False try: interface_id = "%s-%s" % (self._interface_id, remote) return self.proxies[interface_id].clientServerInitialized(interface_id) except Exception as err: LOG.debug( "ServerThread.homegearCheckInit: Exception: %s" % str(err)) return False def putParamset(self, remote, address, paramset, value, rx_mode=None): """Set paramsets manually""" try: proxy = self.proxies["%s-%s" % (self._interface_id, remote)] if rx_mode is None: return proxy.putParamset(address, paramset, value) else: return proxy.putParamset(address, paramset, value, rx_mode) except Exception as err: LOG.debug("ServerThread.putParamset: Exception: %s" % str(err))
server.serve_forever() if __name__ == "__main__": server = SimpleXMLRPCServer(("localhost", 4711), logRequests=False) server.register_function(handle_reply_mail) if config.OFFLINE_MODE: sprint("Starting in offline mode") else: bot = telepot.Bot(config.BOT_TOKEN) bot.message_loop(handle_bot_message) sprint("Starting", config.BOT_NAME) # print(bot.getMe()) sprint("Starting email worker thread") worker = threading.Thread(target=xmlrpc_worker) worker.start() sprint("Waiting for messages...") while True: try: time.sleep(10) except KeyboardInterrupt as ex: sprint("Shutting down...") server.shutdown() worker.join() sys.exit(0)
class DroidMaster(object): """ The main class of droidmaster DroidMaster currently supports QEMU instance pool only """ # this is a single instance class instance = None POLL_INTERVAL = 1 def __init__(self, app_path=None, is_emulator=False, output_dir=None, env_policy=None, policy_name=None, random_input=False, script_path=None, event_count=None, event_interval=None, timeout=None, keep_app=None, keep_env=False, cv_mode=False, debug_mode=False, profiling_method=None, grant_perm=False, enable_accessibility_hard=False, qemu_hda=None, qemu_no_graphic=False, humanoid=None): """ initiate droidmaster, and initiate droidbot's with configurations :return: """ logging.basicConfig(level=logging.DEBUG if debug_mode else logging.INFO) self.logger = logging.getLogger('DroidMaster') DroidMaster.instance = self # 1. Save DroidBot Parameters self.app_path = app_path self.is_emulator = is_emulator self.output_dir = output_dir if not os.path.isdir(output_dir): os.makedirs(output_dir) self.env_policy = env_policy self.policy_name = policy_name self.random_input = random_input self.script_path = script_path self.event_count = event_count self.event_interval = event_interval self.timeout = timeout self.keep_app = keep_app self.keep_env = keep_env self.cv_mode = cv_mode self.debug_mode = debug_mode self.profiling_method = profiling_method self.grant_perm = grant_perm self.enable_accessibility_hard = enable_accessibility_hard self.humanoid = humanoid # 2. Initiate Device Pool self.domain = "localhost" self.rpc_port = Device(device_serial="").get_random_port() self.qemu_hda = qemu_hda self.qemu_no_graphic = qemu_no_graphic self.device_pool_capacity = 6 self.device_pool = {} self.device_unique_id = 0 self.app = App(app_path, output_dir=self.output_dir) self.qemu_app_hda = "%s_%s" % (self.qemu_hda, self.app.get_package_name()) for i in range(self.device_pool_capacity): adb_port = Device(device_serial="").get_random_port() device_serial = "%s:%s" % (self.domain, adb_port) qemu_port = Device(device_serial="").get_random_port() device = Device( device_serial=device_serial, is_emulator=self.is_emulator, output_dir=self.output_dir, cv_mode=self.cv_mode, grant_perm=self.grant_perm, enable_accessibility_hard=self.enable_accessibility_hard) self.device_pool[device_serial] = { "domain": self.domain, "adb_port": adb_port, "qemu_port": qemu_port, # droidbot is indexed by device_serial # qemu is indexed by droidbot "droidbot": None, "qemu": None, "id": None, "device": device } self.logger.info(self.device_pool) # 2. This Server's Parameter self.timer = None self.enabled = True self.successful_spawn_events = set() @staticmethod def get_instance(): if DroidMaster.instance is None: print("Error: DroidMaster is not initiated!") sys.exit(-1) return DroidMaster.instance def get_available_devices(self): return sorted([self.device_pool[x] for x in self.device_pool if self.device_pool[x]["droidbot"] is None and \ self.device_pool[x]["qemu"] is None], key=lambda x: x["adb_port"]) def get_running_devices(self): return sorted([self.device_pool[x] for x in self.device_pool if self.device_pool[x]["droidbot"] is not None and \ self.device_pool[x]["qemu"] is not None], key=lambda x: x["adb_port"]) def start_device(self, device, hda, from_snapshot=False, init_script_path=None): # 1. get device ID device["id"] = self.device_unique_id # 2. new QEMU adapter device["qemu"] = QEMUConn(hda, device["qemu_port"], device["adb_port"], self.qemu_no_graphic) device["qemu"].set_up() device["qemu"].connect(from_snapshot) # 3. new DroidWorker adapter script_path = init_script_path if init_script_path else self.script_path device["droidbot"] = DroidBotConn(device["id"], app_path=self.app_path, device_serial=device["device"].serial, is_emulator=self.is_emulator, output_dir=self.output_dir, env_policy=self.env_policy, policy_name=self.policy_name, random_input=self.random_input, script_path=script_path, event_count=self.event_count, event_interval=self.event_interval, timeout=self.timeout, keep_app=self.keep_app, keep_env=self.keep_env, cv_mode=self.cv_mode, debug_mode=self.debug_mode, profiling_method=self.profiling_method, grant_perm=self.grant_perm, enable_accessibility_hard=self.enable_accessibility_hard, master="http://%s:%d/" % (self.domain, self.rpc_port), humanoid=self.humanoid) device["droidbot"].set_up() self.logger.info("Worker: DOMAIN[%s], ADB[%s], QEMU[%d], ID[%d]" % (device["domain"], device["adb_port"], device["qemu_port"], device["id"])) self.device_unique_id += 1 def stop_device(self, device): device["droidbot"].tear_down() device["droidbot"].disconnect() device["droidbot"] = None device["qemu"].disconnect() device["qemu"].tear_down() device["qemu"] = None def qemu_create_img(self, new_hda, back_hda): self.logger.info("%s -> %s" % (back_hda, new_hda)) p = subprocess.Popen(["qemu-img", "create", "-f", "qcow2", new_hda, "-o", "backing_file=%s" % back_hda, "8G"]) p.wait() def spawn(self, device_serial, init_script_json): """ A worker requests to spawn a new worker based on its current state """ if init_script_json in self.successful_spawn_events: self.logger.warning("Event spawned already") return False available_devices = self.get_available_devices() if not len(available_devices): self.logger.warning("No available device slot") return False calling_device = self.device_pool[device_serial] calling_device["qemu"].send_command("stop") calling_device["qemu"].send_command("savevm spawn") # copy qemu image file (almost RAM image size only) new_hda = "%s.%d" % (self.qemu_app_hda, self.device_unique_id) shutil.copyfile(calling_device["qemu"].hda, new_hda) # prepare init script file init_script_path = os.path.join(self.output_dir, "%d.json" % self.device_unique_id) with open(init_script_path, "w") as init_script_file: init_script_file.write(init_script_json) self.start_device(available_devices[0], new_hda, from_snapshot=True, init_script_path=init_script_path) calling_device["qemu"].send_command("delvm spawn") calling_device["qemu"].send_command("cont") self.successful_spawn_events.add(init_script_json) self.logger.info("Spawning worker") return True def start_worker(self): """ Start the first worker (with device 0), used by DroidMaster itself """ available_devices = self.get_available_devices() if not len(available_devices): self.logger.warning("No available device slot") return False device = available_devices[0] # if app image doesn't exist, create it first if not os.path.exists(self.qemu_app_hda): self.qemu_create_img(self.qemu_app_hda, self.qemu_hda) app_install_qemu = QEMUConn(self.qemu_app_hda, device["qemu_port"], device["adb_port"], self.qemu_no_graphic) app_install_qemu.set_up() app_install_qemu.connect() device["device"].wait_for_device() device["device"].install_app(self.app) app_install_qemu.disconnect() device["device"].shutdown() app_install_qemu.tear_down() new_hda = "%s.%d" % (self.qemu_app_hda, self.device_unique_id) self.qemu_create_img(new_hda, self.qemu_app_hda) self.start_device(available_devices[0], new_hda) return True def stop_worker(self, device_serial): self.stop_device(self.device_pool[device_serial]) def start_daemon(self): self.server = SimpleXMLRPCServer((self.domain, self.rpc_port), RPCHandler) print("Listening on port %s..." % self.rpc_port) self.server.register_function(self.spawn, "spawn") self.server.register_function(self.start_worker, "start_worker") self.server.register_function(self.stop_worker, "stop_worker") self.server.serve_forever() def stop_daemon(self): print("Shutting down DroidMaster server...") self.server.shutdown() self.server_thread.join(0) def start(self): """ start interacting :return: """ if not self.enabled: return self.logger.info("Starting DroidMaster") try: if self.timeout > 0: self.timer = threading.Timer(self.timeout, self.stop) self.timer.start() if not self.enabled: return # enable server listening workers self.server_thread = threading.Thread(target=self.start_daemon) self.server_thread.daemon = True self.server_thread.start() time.sleep(1) # wait server to start # create first droidbot instance proxy = ServerProxy("http://%s:%d/" % (self.domain, self.rpc_port)) proxy.start_worker() while len(self.get_running_devices()): time.sleep(self.POLL_INTERVAL) except KeyboardInterrupt: self.logger.info("Keyboard interrupt.") pass except Exception: import traceback traceback.print_exc() self.stop() sys.exit(-1) self.stop() self.logger.info("DroidMaster Stopped") def stop(self): self.enabled = False if self.timer and self.timer.isAlive(): self.timer.cancel() # stop listening server self.stop_daemon() # stop all workers running_devices = self.get_running_devices() for device in running_devices: self.stop_device(device)
class ServerThread(threading.Thread): """XML-RPC server thread to handle messages from CCU / Homegear""" def __init__( self, local = LOCAL, localport = LOCALPORT, remote = REMOTE, remoteport = REMOTEPORT, devicefile = DEVICEFILE, interface_id = INTERFACE_ID, eventcallback = False, systemcallback = False): global LOCAL, LOCALPORT, REMOTE, REMOTEPORT, DEVICEFILE, INTERFACE_ID LOG.debug("ServerThread.__init__") threading.Thread.__init__(self) INTERFACE_ID = interface_id LOCAL = local LOCALPORT = localport REMOTE = remote REMOTEPORT = remoteport DEVICEFILE = devicefile self.eventcallback = eventcallback self.systemcallback = systemcallback self.proxy = False # Setup server to handle requests from CCU / Homegear LOG.debug("ServerThread.__init__: Setting up server") self.server = SimpleXMLRPCServer( (LOCAL, int(LOCALPORT)), requestHandler=RequestHandler ) self.server.register_introspection_functions() self.server.register_multicall_functions() LOG.debug("ServerThread.__init__: Registering RPC functions") self.server.register_instance(RPCFunctions(devicefile = DEVICEFILE, proxy = self.proxy, eventcallback = self.eventcallback, systemcallback = self.systemcallback)) def run(self): LOG.info("Starting server at http://%s:%i" % (LOCAL, int(LOCALPORT))) self.server.serve_forever() def connect(self): # Create proxy to interact with CCU / Homegear LOG.info("Creating proxy. Connecting to http://%s:%i" % (REMOTE, int(REMOTEPORT))) try: self.proxy = xmlrpc.client.ServerProxy("http://%s:%i" % (REMOTE, int(REMOTEPORT))) except: LOG.warning("Failed connecting to proxy at http://%s:%i" % (REMOTE, int(REMOTEPORT))) raise Exception def proxyInit(self): """To receive events the proxy has to tell the CCU / Homegear where to send the events. For that we call the init-method.""" # Call init() with local XML RPC config and interface_id (the name of the receiver) to receive events. XML RPC server has to be running. LOG.debug("ServerThread.proxyInit: init(http://%s:%i, '%s')" % (LOCAL, int(LOCALPORT), INTERFACE_ID) ) try: self.proxy.init("http://%s:%i" % (LOCAL, int(LOCALPORT)), INTERFACE_ID) LOG.info("Proxy initialized") except: LOG.warning("Failed to initialize proxy") raise Exception def stop(self): """To stop the server we de-init from the CCU / Homegear, then shut down our XML-RPC server.""" if self.proxy: LOG.debug("ServerThread.stop: Deregistering proxy") try: self.proxy.init("http://%s:%i" % (LOCAL, int(LOCALPORT))) except: LOG.warning("Failed to deregister proxy") LOG.info("Shutting down server") self.server.shutdown() LOG.debug("ServerThread.stop: Stopping ServerThread") self.server.server_close() LOG.info("Server stopped")
class ProntRPC: server = None def __init__(self, pronsole, port = RPC_PORT): self.pronsole = pronsole used_port = port while True: try: self.server = SimpleXMLRPCServer(("localhost", used_port), allow_none = True, logRequests = False) if used_port != port: logging.warning(_("RPC server bound on non-default port %d") % used_port) break except socket.error as e: if e.errno == 98: used_port += 1 continue else: raise self.server.register_function(self.get_status, 'status') self.server.register_function(self.set_extruder_temperature,'settemp') self.server.register_function(self.set_bed_temperature,'setbedtemp') self.server.register_function(self.load_file,'load_file') self.server.register_function(self.startprint,'startprint') self.server.register_function(self.pauseprint,'pauseprint') self.server.register_function(self.resumeprint,'resumeprint') self.server.register_function(self.sendhome,'sendhome') self.server.register_function(self.connect,'connect') self.server.register_function(self.disconnect, 'disconnect') self.server.register_function(self.send, 'send') self.thread = Thread(target = self.run_server) self.thread.start() def run_server(self): self.server.serve_forever() def shutdown(self): self.server.shutdown() self.thread.join() def get_status(self): if self.pronsole.p.printing: progress = 100 * float(self.pronsole.p.queueindex) / len(self.pronsole.p.mainqueue) elif self.pronsole.sdprinting: progress = self.pronsole.percentdone else: progress = None if self.pronsole.p.printing or self.pronsole.sdprinting: eta = self.pronsole.get_eta() else: eta = None if self.pronsole.tempreadings: temps = parse_temperature_report(self.pronsole.tempreadings) else: temps = None z = self.pronsole.curlayer return {"filename": self.pronsole.filename, "progress": progress, "eta": eta, "temps": temps, "z": z, } def set_extruder_temperature(self, targettemp): if self.pronsole.p.online: self.pronsole.p.send_now("M104 S" + targettemp) def set_bed_temperature(self,targettemp): if self.pronsole.p.online: self.pronsole.p.send_now("M140 S" + targettemp) def load_file(self,filename): self.pronsole.do_load(filename) def startprint(self): self.pronsole.do_print("") def pauseprint(self): self.pronsole.do_pause("") def resumeprint(self): self.pronsole.do_resume("") def sendhome(self): self.pronsole.do_home("") def connect(self): self.pronsole.do_connect("") def disconnect(self): self.pronsole.do_disconnect("") def send(self, command): self.pronsole.p.send_now(command)
class ProntRPC: server = None def __init__(self, pronsole, port=RPC_PORT): self.pronsole = pronsole used_port = port while True: try: self.server = SimpleXMLRPCServer(("localhost", used_port), allow_none=True, logRequests=False) if used_port != port: logging.warning( _("RPC server bound on non-default port %d") % used_port) break except socket.error as e: if e.errno == 98: used_port += 1 continue else: raise self.server.register_function(self.get_status, 'status') self.server.register_function(self.set_extruder_temperature, 'settemp') self.server.register_function(self.set_bed_temperature, 'setbedtemp') self.server.register_function(self.load_file, 'load_file') self.server.register_function(self.startprint, 'startprint') self.server.register_function(self.pauseprint, 'pauseprint') self.server.register_function(self.resumeprint, 'resumeprint') self.server.register_function(self.sendhome, 'sendhome') self.server.register_function(self.connect, 'connect') self.server.register_function(self.disconnect, 'disconnect') self.server.register_function(self.send, 'send') self.thread = Thread(target=self.run_server) self.thread.start() def run_server(self): self.server.serve_forever() def shutdown(self): self.server.shutdown() self.thread.join() def get_status(self): if self.pronsole.p.printing: progress = 100 * float(self.pronsole.p.queueindex) / len( self.pronsole.p.mainqueue) elif self.pronsole.sdprinting: progress = self.pronsole.percentdone else: progress = None if self.pronsole.p.printing or self.pronsole.sdprinting: eta = self.pronsole.get_eta() else: eta = None if self.pronsole.tempreadings: temps = parse_temperature_report(self.pronsole.tempreadings) else: temps = None z = self.pronsole.curlayer return { "filename": self.pronsole.filename, "progress": progress, "eta": eta, "temps": temps, "z": z, } def set_extruder_temperature(self, targettemp): if self.pronsole.p.online: self.pronsole.p.send_now("M104 S" + targettemp) def set_bed_temperature(self, targettemp): if self.pronsole.p.online: self.pronsole.p.send_now("M140 S" + targettemp) def load_file(self, filename): self.pronsole.do_load(filename) def startprint(self): self.pronsole.do_print("") def pauseprint(self): self.pronsole.do_pause("") def resumeprint(self): self.pronsole.do_resume("") def sendhome(self): self.pronsole.do_home("") def connect(self): self.pronsole.do_connect("") def disconnect(self): self.pronsole.do_disconnect("") def send(self, command): self.pronsole.p.send_now(command)
class RPCUtilities: """Useful functions exposed to RPC server""" server: Optional[SimpleXMLRPCServer] = None def __init__(self, channel: 'TelegramChannel'): self.channel = channel rpc_config = self.channel.config.get('rpc') if not rpc_config: return # Restrict to a particular path. class RequestHandler(SimpleXMLRPCRequestHandler): rpc_paths = ('/RPC2', ) server_addr = rpc_config['server'] port = rpc_config['port'] self.server = SimpleXMLRPCServer((server_addr, port), requestHandler=RequestHandler) self.server.register_introspection_functions() self.server.register_multicall_functions() self.server.register_instance(self.channel.db) self.server.register_function(self.get_slave_channels_id) self.server.register_function(self.get_slave_channel_by_id) self.server.register_function(self.get_chats_from_channel_by_id) threading.Thread(target=self.server.serve_forever) def shutdown(self): """Shutdown RPC server if running.""" if self.server: self.server.shutdown() @staticmethod def get_slave_channels_id() -> KeysView[str]: """Get the collection of slave channel IDs in current instance""" return coordinator.slaves.keys() @staticmethod def get_slave_channel_by_id(channel_id: ModuleID) -> Optional[EFBChannel]: """ Get the slave channel instance if available. Otherwise return None. Args: channel_id: ID of the slave channel. """ if channel_id in coordinator.slaves: return coordinator.slaves[channel_id] return None @staticmethod def get_chats_from_channel_by_id( channel_id: ModuleID) -> Optional[Iterable[EFBChat]]: """ Get a list of chats from a specific slave channel if available. Otherwise return None. Args: channel_id: ID of the slave channel. """ channel = RPCUtilities.get_slave_channel_by_id(channel_id) if channel: return channel.get_chats() return None
class World(object): tile_size = 50 def __init__(self, n_agents=10, width=800, height=600): self.running = False self.width = width self.height = height self.brain = Brain() self.server = SimpleXMLRPCServer(("localhost", 8000), logRequests=False, allow_none=True) self.server.register_introspection_functions() self.server.register_function(self.get_agents) self.server.register_function(self.get_tiles) self.server.register_function(self.stop) self.server_thread = threading.Thread(target=self.server.serve_forever) self.tiles_x = math.ceil(self.width / self.tile_size) self.tiles_y = math.ceil(self.height / self.tile_size) self.tiles = [[ Tile(self, x * self.tile_size, y * self.tile_size, self.tile_size, self.tile_size, self.tile_size) for y in range(self.tiles_y) ] for x in range(self.tiles_x)] self.agents = [] for i in range(n_agents): agent = Agent(self) self.agents.append(agent) self.agent_threads = [ threading.Thread(target=agent.run) for agent in self.agents ] def get_tiles(self): tiles = [] for tile in itertools.chain.from_iterable(self.tiles): tiles.append(tile.to_dict()) return tiles def get_agents(self): agents = [] for agent in self.agents: agents.append(agent.to_dict()) return agents def run(self): self.server_thread.start() try: self.running = True for t in self.agent_threads: t.start() while True: time.sleep(1) except KeyboardInterrupt: print("Canceled by user") self.running = False finally: self.server.shutdown() self.server.server_close() self.server_thread.join() for t in self.agent_threads: t.join() def stop(self): self.running = False
class XmlRpcServer(object): rob = Robot() def __init__(self): self.puerto = 8000 # Creacion del servidor indicando el puerto deseado self.server = SimpleXMLRPCServer(('localhost', self.puerto), logRequests=False) # Se registra cada funcion self.server.register_function(self.do_saludar, 'saludar') self.server.register_function(self.do_despedir, 'despedir') self.server.register_function(self.do_RotarArticulacion1, 'RotarArticulacion1') self.server.register_function(self.do_RotarArticulacion2, 'RotarArticulacion2') self.server.register_function(self.do_RotarArticulacion3, 'RotarArticulacion3') self.server.register_function(self.do_ActivarEfector, 'ActivarEfector') # Se lanza el servidor self.thread = Thread(target=self.run_server) self.thread.start() print('Servidor XML-RPC iniciado en [' + str(self.server.server_address[0]) + '], puerto [' + str(self.server.server_address[1]) + ']') def run_server(self): self.server.serve_forever() def shutdown(self): self.server.shutdown() self.thread.join() def do_saludar(self): m1 = '*' + '-' * 70 + '*' + '\n' m2 = '|' + '{:^70}'.format( 'Programación Orientada a Objetos 2020') + '|' + '\n' #m3 = '|' + '{:^70}'.format('Intefaz de control servidor Robot-RRR') + '|' + '\n' m4 = '|' + '{:^70}'.format('') + '|' + '\n' m5 = '|' + '{:^70}'.format( 'Wieckowski, Martín - Silva, Germán') + '|' + '\n' m6 = '|' + '{:^70}'.format('') + '|' + '\n' m7 = '|' + '{:<70}'.format( ' Bienvenido al programa Cliente ') + '|' + '\n' m8 = '*' + '-' * 70 + '*\n' + '\n' mensaje = m1 + m2 + m4 + m5 + m6 + m7 + m8 return mensaje def do_despedir(self): mensaje = '\n\n******************Programa finalizado***********************\n\n' return mensaje def do_RotarArticulacion1(self, Angulo, Velocidad, Sentido): return 0 def do_RotarArticulacion2(self, Angulo, Velocidad, Sentido): return 0 def do_RotarArticulacion3(self, Angulo, Velocidad, Sentido): return 0 def do_ActivarEfector(self, tiempo): return 0
class AppsRegister: _instance = None __accessories = {} def init(self): self.__startXMLRPCServer() def uninit(self): self.__stopXMLRPCServer() @property def accessories(self): """List of registered accessory applications.""" return self.__accessories.values() def add(self, name, accessory): self.__accessories[name] = accessory def remove(self, name): self.__accessories.pop(name) def removeAll(self): self.__accessories = {} def get(self, name): return self.__accessories[name] def kill(self, name): accessory = self.__accessories[name] if accessory: accessory.kill() def killAll(self): for accessory in self.__accessories.values(): accessory.kill() def start(self, name, args): accessory = self.__accessories[name] if accessory: # The args param comes directly from the sys.argv[1:] of Start.py and should contain a list of strings in # key-value pair, e.g. [option1, value1, option2, value2, ...] options = self.__createCommandLineOptions(args) return accessory.start(options) return False def stop(self, name): accessory = self.__accessories[name] if accessory: return accessory.stop() return False def reboot(self, name): accessory = self.__accessories[name] if accessory: return accessory.stop() and accessory.start() return False def factoryResetAll(self): for accessory in self.__accessories.values(): accessory.factoryReset() def factoryReset(self, name): accessory = self.__accessories[name] if accessory: return accessory.factoryReset() return False def waitForCommissionableAdvertisement(self, name): accessory = self.__accessories[name] if accessory: return accessory.waitForCommissionableAdvertisement() return False def waitForOperationalAdvertisement(self, name): accessory = self.__accessories[name] if accessory: return accessory.waitForOperationalAdvertisement() return False def __startXMLRPCServer(self): self.server = SimpleXMLRPCServer((IP, PORT)) self.server.register_function(self.start, 'start') self.server.register_function(self.stop, 'stop') self.server.register_function(self.reboot, 'reboot') self.server.register_function(self.factoryReset, 'factoryReset') self.server.register_function( self.waitForCommissionableAdvertisement, 'waitForCommissionableAdvertisement') self.server.register_function( self.waitForOperationalAdvertisement, 'waitForOperationalAdvertisement') self.server_thread = threading.Thread(target=self.server.serve_forever) self.server_thread.start() def __stopXMLRPCServer(self): self.server.shutdown() def __createCommandLineOptions(self, args): if not args: return {} # args should contain a list of strings in key-value pair, e.g. [option1, value1, option2, value2, ...] if (len(args) % 2) != 0: logging.warning("Unexpected command line options %r - not key/value pairs (odd length)" % (args,)) return {} # Create a dictionary from the key-value pair list options = {args[i]: args[i+1] for i in range(0, len(args), 2)} return options
class ServerThread(threading.Thread): """XML-RPC server thread to handle messages from CCU / Homegear""" def __init__(self, local=LOCAL, localport=LOCALPORT, remotes=REMOTES, devicefile=DEVICEFILE, interface_id=INTERFACE_ID, eventcallback=False, systemcallback=False, resolveparamsets=False): LOG.debug("ServerThread.__init__") threading.Thread.__init__(self) # Member self._interface_id = interface_id self._local = local self._localport = int(localport) self._devicefile = devicefile self.remotes = remotes self.eventcallback = eventcallback self.systemcallback = systemcallback self.resolveparamsets = resolveparamsets self.proxies = {} # Create proxies to interact with CCU / Homegear LOG.debug("__init__: Creating proxies") for remote, host in self.remotes.items(): try: socket.inet_pton(socket.AF_INET, host['ip']) except Exception as err: LOG.warning("Skipping proxy: %s" % str(err)) continue LOG.info("Creating proxy %s. Connecting to http://%s:%i" % (remote, host['ip'], host['port'])) try: self.proxies["%s-%s" % (self._interface_id, remote)] = LockingServerProxy("http://%s:%i" % (host['ip'], host['port'])) except Exception as err: LOG.warning("Failed connecting to proxy at http://%s:%i" % (host['ip'], host['port'])) LOG.debug("__init__: Exception: %s" % str(err)) raise Exception if not self.proxies: LOG.warning("No proxies available. Aborting.") raise Exception self._rpcfunctions = RPCFunctions(devicefile=self._devicefile, proxies=self.proxies, remotes=self.remotes, eventcallback=self.eventcallback, systemcallback=self.systemcallback, resolveparamsets=self.resolveparamsets) # Setup server to handle requests from CCU / Homegear LOG.debug("ServerThread.__init__: Setting up server") self.server = SimpleXMLRPCServer((self._local, self._localport), requestHandler=RequestHandler, logRequests=False) self._localport = self.server.socket.getsockname()[1] self.server.register_introspection_functions() self.server.register_multicall_functions() LOG.debug("ServerThread.__init__: Registering RPC functions") self.server.register_instance(self._rpcfunctions, allow_dotted_names=True) def run(self): LOG.info("Starting server at http://%s:%i" % (self._local, self._localport)) self.server.serve_forever() def proxyInit(self): """ To receive events the proxy has to tell the CCU / Homegear where to send the events. For that we call the init-method. """ # Call init() with local XML RPC config and interface_id (the name of the receiver) to receive events. XML RPC server has to be running. for interface_id, proxy in self.proxies.items(): LOG.debug("ServerThread.proxyInit: init('http://%s:%i', '%s')" % (proxy._localip, self._localport, interface_id)) try: proxy.init("http://%s:%i" % (proxy._localip, self._localport), interface_id) LOG.info("Proxy initialized") except Exception as err: LOG.debug("proxyInit: Exception: %s" % str(err)) LOG.warning("Failed to initialize proxy") raise Exception def stop(self): """To stop the server we de-init from the CCU / Homegear, then shut down our XML-RPC server.""" stopped = [] for interface_id in self.proxies: if not self.proxies[interface_id]._localip in stopped: LOG.debug("ServerThread.stop: Deregistering proxy for server %s" % self.proxies[interface_id]._localip) try: self.proxies[interface_id].init("http://%s:%i" % (self.proxies[interface_id]._localip, self._localport)) stopped.append(self.proxies[interface_id]._localip) except Exception as err: LOG.warning("Failed to deregister proxy") LOG.debug("stop: Exception: %s" % str(err)) del self.proxies[:] LOG.info("Shutting down server") self.server.shutdown() LOG.debug("ServerThread.stop: Stopping ServerThread") self.server.server_close() LOG.info("Server stopped") def parseCCUSysVar(self, data): if data['type'] == 'LOGIC': return data['name'], data['value'] == 'true' elif data['type'] == 'NUMBER': return data['name'], float(data['value']) elif data['type'] == 'LIST': return data['name'], int(data['value']) else: return data['name'], data['value'] def jsonRpcLogin(self, remote): session = False try: params = {"username": self.remotes[remote]['username'], "password": self.remotes[remote]['password']} response = self._rpcfunctions.jsonRpcPost(self.remotes[remote]['ip'], "Session.login", params) if response['error'] is None and response['result']: session = response['result'] if not session: LOG.warning("ServerThread.jsonRpcLogin: Unable to open session.") except Exception as err: LOG.debug("ServerThread.jsonRpcLogin: Exception while logging in via JSON-RPC: %s" % str(err)) return session def jsonRpcLogout(self, remote, session): logout = False try: params = {"_session_id_": session} response = self._rpcfunctions.jsonRpcPost(self.remotes[remote]['ip'], "Session.logout", params) if response['error'] is None and response['result']: logout = response['result'] except Exception as err: LOG.debug("ServerThread.jsonRpcLogout: Exception while logging in via JSON-RPC: %s" % str(err)) return logout def getAllSystemVariables(self, remote): """Get all system variables from CCU / Homegear""" variables = {} if self.remotes[remote]['username'] and self.remotes[remote]['password']: LOG.debug("ServerThread.getAllSystemVariables: Getting all System variables via JSON-RPC") session = self.jsonRpcLogin(remote) if not session: return try: params = {"_session_id_": session} response = self._rpcfunctions.jsonRpcPost(self.remotes[remote]['ip'], "SysVar.getAll", params) if response['error'] is None and response['result']: for var in response['result']: key, value = self.parseCCUSysVar(var) variables[key] = value self.jsonRpcLogout(remote, session) except Exception as err: self.jsonRpcLogout(remote, session) LOG.warning("ServerThread.getAllSystemVariables: Exception: %s" % str(err)) else: try: variables = self.proxies["%s-%s" % (self._interface_id, remote)].getAllSystemVariables() except Exception as err: LOG.debug("ServerThread.getAllSystemVariables: Exception: %s" % str(err)) return variables def getSystemVariable(self, remote, name): """Get single system variable from CCU / Homegear""" var = None if self.remotes[remote]['username'] and self.remotes[remote]['password']: LOG.debug("ServerThread.getSystemVariable: Getting System variable via JSON-RPC") session = self.jsonRpcLogin(remote) if not session: return try: params = {"_session_id_": session, "name": name} response = self._rpcfunctions.jsonRpcPost(self.remotes[remote]['ip'], "SysVar.getValueByName", params) if response['error'] is None and response['result']: try: var = float(response['result']) except: if response['result'] == 'true': var = True else: var = False self.jsonRpcLogout(remote, session) except Exception as err: self.jsonRpcLogout(remote, session) LOG.warning("ServerThread.getSystemVariable: Exception: %s" % str(err)) else: try: var = self.proxies["%s-%s" % (self._interface_id, remote)].getSystemVariable(name) except Exception as err: LOG.debug("ServerThread.getSystemVariable: Exception: %s" % str(err)) return var def deleteSystemVariable(self, remote, name): """Delete a system variable from CCU / Homegear""" if self.remotes[remote]['username'] and self.remotes[remote]['password']: LOG.debug("ServerThread.deleteSystemVariable: Getting System variable via JSON-RPC") session = self.jsonRpcLogin(remote) if not session: return try: params = {"_session_id_": session, "name": name} response = self._rpcfunctions.jsonRpcPost(self.remotes[remote]['ip'], "SysVar.deleteSysVarByName", params) if response['error'] is None and response['result']: deleted = response['result'] LOG.warning("ServerThread.deleteSystemVariable: Deleted: %s" % str(deleted)) self.jsonRpcLogout(remote, session) except Exception as err: self.jsonRpcLogout(remote, session) LOG.warning("ServerThread.deleteSystemVariable: Exception: %s" % str(err)) else: try: return self.proxies["%s-%s" % (self._interface_id, remote)].deleteSystemVariable(name) except Exception as err: LOG.debug("ServerThread.deleteSystemVariable: Exception: %s" % str(err)) def setSystemVariable(self, remote, name, value): """Set a system variable on CCU / Homegear""" if self.remotes[remote]['username'] and self.remotes[remote]['password']: LOG.debug("ServerThread.setSystemVariable: Setting System variable via JSON-RPC") session = self.jsonRpcLogin(remote) if not session: return try: params = {"_session_id_": session, "name": name, "value": value} if value is True or value is False: response = self._rpcfunctions.jsonRpcPost(self.remotes[remote]['ip'], "SysVar.setBool", params) else: response = self._rpcfunctions.jsonRpcPost(self.remotes[remote]['ip'], "SysVar.setFloat", params) if response['error'] is None and response['result']: res = response['result'] LOG.debug("ServerThread.setSystemVariable: Result while setting variable: %s" % str(res)) else: if response['error']: LOG.debug("ServerThread.setSystemVariable: Error while setting variable: %s" % str(response['error'])) self.jsonRpcLogout(remote, session) except Exception as err: self.jsonRpcLogout(remote, session) LOG.warning("ServerThread.setSystemVariable: Exception: %s" % str(err)) else: try: return self.proxies["%s-%s" % (self._interface_id, remote)].setSystemVariable(name, value) except Exception as err: LOG.debug("ServerThread.setSystemVariable: Exception: %s" % str(err)) def getServiceMessages(self, remote): """Get service messages from CCU / Homegear""" try: return self.proxies["%s-%s" % (self._interface_id, remote)].getServiceMessages() except Exception as err: LOG.debug("ServerThread.getServiceMessages: Exception: %s" % str(err)) def rssiInfo(self, remote): """Get RSSI information for all devices from CCU / Homegear""" try: return self.proxies["%s-%s" % (self._interface_id, remote)].rssiInfo() except Exception as err: LOG.debug("ServerThread.rssiInfo: Exception: %s" % str(err)) def setInstallMode(self, remote, on=True, t=60, mode=1, address=None): """Activate or deactivate installmode on CCU / Homegear""" try: args = [on] if on and t: args.append(t) if address: args.append(address) else: args.append(mode) return self.proxies["%s-%s" % (self._interface_id, remote)].setInstallMode(*args) except Exception as err: LOG.debug("ServerThread.setInstallMode: Exception: %s" % str(err)) def getInstallMode(self, remote): """Get remaining time in seconds install mode is active from CCU / Homegear""" try: return self.proxies["%s-%s" % (self._interface_id, remote)].getInstallMode() except Exception as err: LOG.debug("ServerThread.getInstallMode: Exception: %s" % str(err)) def getAllMetadata(self, remote, address): """Get all metadata of device""" try: return self.proxies["%s-%s" % (self._interface_id, remote)].getAllMetadata(address) except Exception as err: LOG.debug("ServerThread.getAllMetadata: Exception: %s" % str(err)) def getMetadata(self, remote, address, key): """Get metadata of device""" try: return self.proxies["%s-%s" % (self._interface_id, remote)].getMetadata(address, key) except Exception as err: LOG.debug("ServerThread.getMetadata: Exception: %s" % str(err)) def setMetadata(self, remote, address, key, value): """Set metadata of device""" try: return self.proxies["%s-%s" % (self._interface_id, remote)].setMetadata(address, key, value) except Exception as err: LOG.debug("ServerThread.setMetadata: Exception: %s" % str(err)) def deleteMetadata(self, remote, address, key): """Delete metadata of device""" try: return self.proxies["%s-%s" % (self._interface_id, remote)].deleteMetadata(address, key) except Exception as err: LOG.debug("ServerThread.deleteMetadata: Exception: %s" % str(err)) def listBidcosInterfaces(self, remote): """Return all available BidCos Interfaces""" try: return self.proxies["%s-%s" % (self._interface_id, remote)].listBidcosInterfaces() except Exception as err: LOG.debug("ServerThread.listBidcosInterfaces: Exception: %s" % str(err))
class server(): def __init__(self, address, port, n_readers, n_writers, access): self.address = address self.port = int(port) self.n_clients = int(n_readers) + int(n_writers) self.n_access = int(access) self.oval = -1 self.sseq = 0 self.r_ids = [] self.w_id = -1 self.rnum = 0 self.read_log = "Readers: \n\nsSeq oVal rID rNum \n\n" self.write_log = "Writers: \n\nsSeq oVal wID \n\n" self.mutex = threading.Lock() self.seqmutex = threading.Lock() self.rlogmutex = threading.Lock() self.wlogmutex = threading.Lock() # Start running the server def run(self): threading.Thread(target=self.check_server).start() #with SimpleXMLRPCServer((self.address, self.port)) as self.server: self.server = SimpleXMLRPCServer((self.address, self.port)) self.sock = self.server.socket self.server.register_introspection_functions() self.server.register_function(self.read) self.server.register_function(self.write) try: self.server.serve_forever() except KeyboardInterrupt: exit(0) fo = open("log", "w") fo.write(self.read_log + "\n\n" + self.write_log) fo.close() def stop_server(self): self.server.shutdown() self.server.server_close() def check_server(self): while self.n_clients > self.sseq + 1: pass time.sleep(180) self.stop_server() def read(self, rid): seq = -1 with self.seqmutex: self.sseq += 1 seq = self.sseq if rid not in self.r_ids: self.r_ids.append(rid) secs = random.randint(0, 10) time.sleep(secs) with self.rlogmutex: self.read_log += str(seq) + " " + str( self.oval) + " " + str(rid) + " " + str(len( self.r_ids)) + "\n" self.r_ids.remove(rid) return self.oval, seq def write(self, wid): seq = -1 with self.seqmutex: self.sseq += 1 seq = self.sseq with self.mutex: self.oval = wid secs = random.randint(0, 10) time.sleep(secs) with self.wlogmutex: self.write_log += str(seq) + " " + str( self.oval) + " " + str(wid) + "\n" return seq
class FakeXMLRPCServer(object): def __init__(self, port=TCP_PORT): self.server = SimpleXMLRPCServer(("localhost", port)) self.server.register_function(self.applications_gettable, 'nb.Applications.getTable') self.server.register_function(self.applications_set_loglevel, 'nb.Applications.set.logLevel') self.server.register_function(self.applications_get_size, 'nb.Applications.size') self.server.register_function(self.applications_find, 'nb.Applications.find') self.server.register_function(self.applications_exists, 'nb.Applications.exists') self.server.register_function(self.system_tables_ready, 'system.tablesReady') self.server.register_function(self.platform_get_row, 'nb.Platform.getRow') # self.server.register_function(self.platform_get_table, 'nb.Platform.getTable') self.server.register_function(self.platform_get_size, 'nb.Platform.size') self.server.register_function(self.ports_get_name, 'nb.Ports.get.name') self.server.register_function(self.ports_get_size, 'nb.Ports.size') self.server.register_function(self.ports_get_info, 'nb.Ports.getInfo') self.server.register_function(self.ports_get_info_name, 'nb.Ports.getInfo.name') self.server.register_function(self.method_help, 'system.methodHelp') self.server.register_function(self.ports_add_row, 'nb.Ports.addRow') self.server.register_function(self.ports_del_row, 'nb.Ports.delRow') self.server.register_function(self.system_multicall, 'system.multicall') self.server.register_function(self.ports_lags_get_table, 'nb.Ports2LagAdmin.getTable') self.server.register_function(self.ports_lags_get_size, 'nb.Ports2LagAdmin.size') self.server.register_function(self.lags_get_table, 'nb.LagsAdmin.getTable') self.server.register_function(self.lags_get_size, 'nb.LagsAdmin.size') self.server.register_function(self.lags_add_row, 'nb.LagsAdmin.addRow') self.server.register_function(self.ports_lag_add_row, 'nb.Ports2LagAdmin.addRow') self.applications = [ {'name': 'ONSApplicationServer', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'SimSwitchApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'ONSCoreServer', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'ONSNorthboundServer', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'L3DhcpRelayControlApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'L2MirrorControlApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'L2QosControlApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'L2StormControlApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'L2StatsControlApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'ONSOpenVSwitchApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'L1SfpControlApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'L2VlanControlApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'L1PortControlApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'L2QinqControlApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'L2FdbControlApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'L2AclControlApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'L1SwitchControlApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'L2MulticastControlApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'L2LagControlApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'L3ControlApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'L2LldpControlApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, {'name': 'L2StpControlApp', 'logLevel': 'test level', 'adminState': 'Run', 'appId': 1, 'operationalState': 'Run'}, ] self.platform = [{'ethernetSwitchType': 'SimSwitch Switch', 'name': 'ONS CoreSwitch', 'cpuArchitecture': 'x86_64', 'chipVersion': '2.0', 'chipSubType': 'simswitch', 'apiVersion': 'SimSwitch 2.0.0', 'switchppVersion': '1.2.0.1405-1', 'chipName': 'SimSwitch', 'osType': 'Linux', 'model': 'ONS', 'osVersion': '3.2.0-61-generic', 'cpu': 'x86_64', 'serialNumber': ''}] self.ports = [ {'portId': 1, 'adminMode': 'Up', 'pvid': 1, 'type': 'Physical', 'operationalStatus': 'Up', 'speed': 10000, 'name': 'xe1'}, {'portId': 2, 'adminMode': 'Up', 'pvid': 1, 'type': 'Physical', 'operationalStatus': 'Up', 'speed': 10000, 'name': 'xe2'}, {'portId': 3, 'adminMode': 'Up', 'pvid': 1, 'type': 'Physical', 'operationalStatus': 'Down', 'speed': 10000, 'name': 'xe3'}, {'portId': 4, 'adminMode': 'Up', 'pvid': 1, 'type': 'Physical', 'operationalStatus': 'Down', 'speed': 10000, 'name': 'xe4'}, {'portId': 5, 'adminMode': 'Up', 'pvid': 1, 'type': 'Physical', 'operationalStatus': 'Down', 'speed': 10000, 'name': 'xe5'}, {'portId': 6, 'adminMode': 'Up', 'pvid': 1, 'type': 'Physical', 'operationalStatus': 'Down', 'speed': 10000, 'name': 'xe6'}, {'portId': 7, 'adminMode': 'Up', 'pvid': 1, 'type': 'Physical', 'operationalStatus': 'Down', 'speed': 10000, 'name': 'xe7'}, {'portId': 8, 'adminMode': 'Up', 'pvid': 1, 'type': 'Physical', 'operationalStatus': 'Down', 'speed': 10000, 'name': 'xe8'}, {'portId': 9, 'adminMode': 'Up', 'pvid': 1, 'type': 'Physical', 'operationalStatus': 'Down', 'speed': 10000, 'name': 'xe9'}, {'portId': 10, 'adminMode': 'Up', 'pvid': 1, 'type': 'Physical', 'operationalStatus': 'Down', 'speed': 10000, 'name': 'xe10'}] self.ports_info = {'primary_key': ['portId'], 'persistent': 'True', 'description': 'Ports table includes all type of ports in a single table.', 'columns': ['portId', 'adminMode', 'name', 'pvid', 'speed', 'operationalStatus', 'type'], 'mode': 'rw'} self.ports_name_info = {'restrictions': {'size': '32'}, 'type': 'string', 'description': 'This ports name (a 32-byte string).', 'mode': 'ro'} self.ports_get_row_help = 'Method for getting variable from table Ports' self.error_multicall = False self.lags = [] self.ports_to_lags = [] self.th = None def start(self): self.th = threading.Thread(target=self.server.serve_forever) self.th.start() def stop(self): if self.th.is_alive(): self.server.shutdown() self.server.server_close() self.th.join() def applications_gettable(self): return self.applications def applications_set_loglevel(self, app_id, loglevel): if loglevel == 'error': raise SwitchException("Error loglevel") for row in self.applications: if row['appId'] == app_id: row['logLevel'] = loglevel return 0 def applications_find(self, app_id, pid_id, app_name): index = 0 for row in self.applications: index += 1 if row['appId'] == app_id and row['name'] == app_name: return index return -1 def applications_get_size(self): return len(self.applications) def applications_exists(self, app_id, pid_id, app_name): return self.applications_find(app_id, pid_id, app_name) def system_tables_ready(self): return 0 def platform_get_row(self, row): row = row - 1 return self.platform[row] def platform_get_table(self): return self.platform def platform_get_size(self): return len(self.platform) def ports_gettable(self): return self.ports def ports_get_name(self, row_id): row_id = row_id - 1 return self.ports[row_id]['name'] def ports_get_size(self): return len(self.ports) def ports_get_info(self): return self.ports_info def ports_get_info_name(self): return self.ports_name_info def ports_add_row(self, *row): port = { 'portId': row[0], 'adminMode': row[1], 'pvid': row[2], 'type': row[3], 'operationalStatus': row[4], 'speed': row[5], 'name': row[6], } self.ports.append(port) return 0 def ports_del_row(self, row_id): self.ports.remove(self.ports[row_id - 1]) return 0 def clear_config(self): return 0 def method_help(self, method): if method == 'nb.Ports.getRow': return self.ports_get_row_help raise SwitchException('Method %s does not exist' % (method, )) def system_multicall(self, *calls): res = [] for _ in calls[0]: res.append(0) if self.error_multicall: return res[: -1] return res def ports_lags_get_table(self): return self.ports_to_lags def ports_lags_get_size(self): return len(self.ports_to_lags) def lags_get_table(self): return self.lags def lags_get_size(self): return len(self.lags) def lags_add_row(self, *row): lag = { 'lagId': row[0], 'name': row[1], 'lagControlType': row[3], 'actorAdminLagKey': row[2], 'hashMode': row[4], } port = { 'portId': row[0], 'adminMode': 'Up', 'pvid': 1, 'type': 'LAG', 'operationalStatus': 'Down', 'speed': 10000, 'name': row[1], } self.lags.append(lag) self.ports.append(port) return 0 def ports_lag_add_row(self, *row): port_lag = { 'lagId': row[1], 'portId': row[0], 'actorPortPriority': row[2], 'actorAdminPortKey': row[3], 'adminAggregation': row[4], 'adminActive': row[5], 'adminTimeout': row[6], 'adminSynchronization': row[7], 'adminCollecting': row[8], 'adminDistributing': row[9], 'adminDefaulted': row[10], 'adminExpired': row[11], } port = [x for x in self.ports if x['portId'] == row[0]][0] port['type'] = 'LagMember' self.ports_to_lags.append(port_lag) return 0
class ServerThread(threading.Thread): """XML-RPC server thread to handle messages from CCU / Homegear""" def __init__(self, addr=(const.IP_LOCALHOST_V4, const.PORT_RF), devices=None, persistance=False, logic=False): LOG.debug("ServerThread.__init__") threading.Thread.__init__(self) self.addr = addr LOG.debug("__init__: Registering RPC methods") self._rpcfunctions = RPCFunctions(devices, persistance, logic) LOG.debug("ServerThread.__init__: Setting up server") self.server = SimpleXMLRPCServer(addr, requestHandler=RequestHandler, logRequests=False, allow_none=True) self.server.register_introspection_functions() self.server.register_multicall_functions() LOG.debug("ServerThread.__init__: Registering RPC functions") self.server.register_instance(self._rpcfunctions, allow_dotted_names=True) def run(self): LOG.info("Starting server at http://%s:%i", self.addr[0], self.addr[1]) self._rpcfunctions.active = True self.server.serve_forever() def stop(self): """Shut down our XML-RPC server.""" self._rpcfunctions.active = False for logic_device in self._rpcfunctions.logic_devices: logic_device.active = False self._rpcfunctions._saveParamsets() LOG.info("Shutting down server") self.server.shutdown() LOG.debug("ServerThread.stop: Stopping ServerThread") self.server.server_close() LOG.info("Server stopped") # Convenience methods at server scope def setValue(self, address, value_key, value, force=False): return self._rpcfunctions.setValue(address, value_key, value, force) def getValue(self, address, value_key): return self._rpcfunctions.getValue(address, value_key) def getDeviceDescription(self, address): return self._rpcfunctions.getDeviceDescription(address) def getParamsetDescription(self, address, paramset): return self._rpcfunctions.getParamsetDescription(address, paramset) def getParamset(self, address, paramset): return self._rpcfunctions.getParamset(address, paramset) def putParamset(self, address, paramset_key, paramset, force=False): return self._rpcfunctions.putParamset(address, paramset_key, paramset, force) def listDevices(self): return self._rpcfunctions.listDevices() def getServiceMessages(self): return self._rpcfunctions.getServiceMessages() def supportedDevices(self): return self._rpcfunctions.supported_devices def addDevices(self, devices=None): devices = self._rpcfunctions._loadDevices(devices=devices) for interface_id, proxy in self._rpcfunctions.remotes.items(): LOG.debug("addDevices: Pushing new devices to %s", interface_id) proxy.newDevices(interface_id, devices) def removeDevices(self, devices=None): self._rpcfunctions._removeDevices(devices)