def wait_for_commands(self): logger.info("Python Server ready to receive messages") try: while True: command = smart_decode(self.stream.readline())[:-1] obj_id = smart_decode(self.stream.readline())[:-1] logger.info( "Received command {0} on object id {1}". format(command, obj_id)) if obj_id is None or len(obj_id.strip()) == 0: break if command == proto.CALL_PROXY_COMMAND_NAME: return_message = self._call_proxy(obj_id, self.stream) self.socket.sendall(return_message.encode("utf-8")) elif command == proto.GARBAGE_COLLECT_PROXY_COMMAND_NAME: self.stream.readline() del(self.pool[obj_id]) self.socket.sendall( proto.SUCCESS_RETURN_MESSAGE.encode("utf-8")) else: logger.error("Unknown command {0}".format(command)) # We're sending something to prevent blocking, but at this # point, the protocol is broken. self.socket.sendall( proto.ERROR_RETURN_MESSAGE.encode("utf-8")) except Exception: # This is a normal exception... logger.info( "Error while python server was waiting for" "a message", exc_info=True) self.close()
def _get_params(self, input): params = [] temp = smart_decode(input.readline())[:-1] while temp != proto.END: param = get_return_value("y" + temp, self.java_client) params.append(param) temp = smart_decode(input.readline())[:-1] return params
def wait_for_commands(self): logger.info("Python Server ready to receive messages") reset = False authenticated = self.python_parameters.auth_token is None try: while True: command = smart_decode(self.stream.readline())[:-1] if not authenticated: # Will raise an exception if auth fails in any way. authenticated = do_client_auth( command, self.stream, self.socket, self.python_parameters.auth_token) continue obj_id = smart_decode(self.stream.readline())[:-1] logger.info( "Received command {0} on object id {1}". format(command, obj_id)) if obj_id is None or len(obj_id.strip()) == 0: break if command == proto.CALL_PROXY_COMMAND_NAME: return_message = self._call_proxy(obj_id, self.stream) self.socket.sendall(return_message.encode("utf-8")) elif command == proto.GARBAGE_COLLECT_PROXY_COMMAND_NAME: self.stream.readline() _garbage_collect_proxy(self.pool, obj_id) self.socket.sendall( proto.SUCCESS_RETURN_MESSAGE.encode("utf-8")) else: logger.error("Unknown command {0}".format(command)) # We're sending something to prevent blocking, but at this # point, the protocol is broken. self.socket.sendall( proto.ERROR_RETURN_MESSAGE.encode("utf-8")) except Py4JAuthenticationError: reset = True logger.exception("Could not authenticate connection.") except socket.timeout: reset = True logger.info( "Timeout while python server was waiting for" "a message", exc_info=True) except Exception: # This is a normal exception... logger.info( "Error while python server was waiting for" "a message", exc_info=True) self.close(reset)
def send_command(self, command): # TODO At some point extract common code from wait_for_commands logger.debug("Command to send: {0}".format(command)) try: self.socket.sendall(command.encode("utf-8")) except Exception as e: logger.info("Error while sending or receiving.", exc_info=True) raise Py4JNetworkError( "Error while sending", e, proto.ERROR_ON_SEND) try: while True: answer = smart_decode(self.stream.readline()[:-1]) logger.debug("Answer received: {0}".format(answer)) # Happens when a the other end is dead. There might be an empty # answer before the socket raises an error. if answer.strip() == "": raise Py4JNetworkError("Answer from Java side is empty") if answer.startswith(proto.RETURN_MESSAGE): return answer[1:] else: command = answer obj_id = smart_decode(self.stream.readline())[:-1] if command == proto.CALL_PROXY_COMMAND_NAME: return_message = self._call_proxy(obj_id, self.stream) self.socket.sendall(return_message.encode("utf-8")) elif command == proto.GARBAGE_COLLECT_PROXY_COMMAND_NAME: self.stream.readline() _garbage_collect_proxy(self.pool, obj_id) self.socket.sendall( proto.SUCCESS_RETURN_MESSAGE.encode("utf-8")) else: logger.error("Unknown command {0}".format(command)) # We're sending something to prevent blocking, # but at this point, the protocol is broken. self.socket.sendall( proto.ERROR_RETURN_MESSAGE.encode("utf-8")) except Exception as e: logger.info("Error while receiving.", exc_info=True) raise Py4JNetworkError( "Error while sending or receiving", e, proto.ERROR_ON_RECEIVE)
def testByteString(self): # NOTE: this is only a byte string if executed by Python 2. ex = self.gateway.jvm.py4j.examples.UTFExample() s1 = 'allo' s2 = smart_decode('alloé') array1 = ex.getUtfValue(s1) array2 = ex.getUtfValue(s2) self.assertEqual(len(s1), len(array1)) self.assertEqual(len(s2), len(array2)) self.assertEqual(ord(s1[0]), array1[0]) self.assertEqual(ord(s2[4]), array2[4])
def _call_proxy(self, obj_id, input): return_message = proto.ERROR_RETURN_MESSAGE if obj_id in self.pool: try: method = smart_decode(input.readline())[:-1] params = self._get_params(input) return_value = getattr(self.pool[obj_id], method)(*params) return_message = proto.RETURN_MESSAGE + proto.SUCCESS + get_command_part(return_value, self.pool) except Exception: logger.exception("There was an exception while executing the " "Python Proxy on the Python Side.") return return_message
def testBinarySuccess(self): e = self.gateway.getNewExample() # not binary - just get the Java object v1 = e.getStream() self.assertTrue(is_instance_of(self.gateway, v1, "java.nio.channels.ReadableByteChannel")) # pull it as a binary stream with e.getStream.stream() as conn: self.assertTrue(isinstance(conn, GatewayConnectionGuard)) expected = "Lorem ipsum dolor sit amet, consectetur adipiscing elit." self.assertEqual(expected, smart_decode(conn.read(len(expected))))
def testStream(self): with clientserver_example_app_process(): client_server = ClientServer(JavaParameters(), PythonParameters()) e = client_server.entry_point.getNewExample() # not binary - just get the Java object v1 = e.getStream() self.assertTrue( is_instance_of(client_server, v1, "java.nio.channels.ReadableByteChannel")) # pull it as a binary stream with e.getStream.stream() as conn: self.assertTrue(isinstance(conn, GatewayConnectionGuard)) expected =\ u"Lorem ipsum dolor sit amet, consectetur adipiscing elit." self.assertEqual(expected, smart_decode(conn.read(len(expected)))) client_server.shutdown()
def testStream(self): with clientserver_example_app_process(): client_server = ClientServer( JavaParameters(), PythonParameters()) e = client_server.entry_point.getNewExample() # not binary - just get the Java object v1 = e.getStream() self.assertTrue( is_instance_of( client_server, v1, "java.nio.channels.ReadableByteChannel")) # pull it as a binary stream with e.getStream.stream() as conn: self.assertTrue(isinstance(conn, GatewayConnectionGuard)) expected =\ u"Lorem ipsum dolor sit amet, consectetur adipiscing elit." self.assertEqual( expected, smart_decode(conn.read(len(expected)))) client_server.shutdown()
def _call_proxy(self, obj_id, input): if obj_id not in self.pool: return proto.RETURN_MESSAGE + proto.ERROR +\ get_command_part('Object ID unknown', self.pool) try: method = smart_decode(input.readline())[:-1] params = self._get_params(input) return_value = getattr(self.pool[obj_id], method)(*params) return proto.RETURN_MESSAGE + proto.SUCCESS +\ get_command_part(return_value, self.pool) except Exception as e: logger.exception("There was an exception while executing the " "Python Proxy on the Python Side.") if self.python_parameters.propagate_java_exceptions and\ isinstance(e, proto.Py4JJavaError): java_exception = e.java_exception else: java_exception = traceback.format_exc() return proto.RETURN_MESSAGE + proto.ERROR +\ get_command_part(java_exception, self.pool)