示例#1
0
 def _sock_send(self, data):
     target_size = len(data)
     sent_size = 0
     while sent_size < target_size:
         try:
             pack_size = self._sock.send(data[sent_size:])
         except socket.error:
             raise exceptions.TransportError(
                 'Failed to send request to server %s:%d.' %
                 (self._host, self._port))
         if pack_size == 0:
             raise exceptions.TransportError(
                 'Failed to send request to server %s:%d.' %
                 (self._host, self._port))
         sent_size += pack_size
示例#2
0
    def _connect(self):
        """Connect to the server and send "Hello" message.

        # Message consists of three components:
        # 1) b'HBas\x00\x50'.
        # 2) Big-endian uint32 indicating length of serialized ConnectionHeader.
        # 3) Serialized ConnectionHeader.

        Raises:
            exceptions.TransportError: Failed to connect or send messages.

        """
        try:
            self._sock.connect((self._host, self._port))
        except socket.error:
            raise exceptions.TransportError(
                'Failed to connect to server %s:%d.' %
                (self._host, self._port))

        header = pb.ConnectionHeader()
        header.user_info.effective_user = '******'
        header.service_name = self._service_name
        header_bytes = header.SerializeToString()

        message = b'HBas\x00\x50' + struct.pack(
            '>I', len(header_bytes)) + header_bytes
        self._sock.settimeout(60)
        self._sock_send(message)
示例#3
0
 def _sock_recv(self, n):
     buffer = io.BytesIO()
     received = 0
     while received < n:
         try:
             data = self._sock.recv(n - received)
         except socket.error:
             raise exceptions.TransportError(
                 'Failed to receive response to server %s:%d.' %
                 (self._host, self._port))
         if not data:
             raise exceptions.TransportError(
                 'Failed to receive response to server %s:%d.' %
                 (self._host, self._port))
         received += len(data)
         buffer.write(data)
     return buffer.getvalue()
示例#4
0
 def _get_response(self, call_id):
     with self._resp_lock:
         if call_id not in self._resp_dict:
             raise exceptions.TransportError(
                 'FATAL ERROR: Response for call [%d] does not exist.' %
                 call_id)
         resp = self._resp_dict[call_id]
         del self._resp_dict[call_id]
         return resp
示例#5
0
def _get_address(zkquorum, path, timeout=9, retries=3):
    """Get specific server address.

    Args:
        zkquorum (str):
        path (str):
        timeout (int):
        retries (int):

    Returns:
        tuple: (hostname, port)

    Raises:
        exceptions.TransportError: Failed to connect.
        exceptions.NoSuchZookeeperNodeError: The required node not found.
        exceptions.ZookeeperProtocolError: Invalid response.

    """
    zk_client = KazooClient(hosts=zkquorum)
    try:
        zk_client.start(timeout=timeout)
    except KazooTimeoutError:
        raise exceptions.TransportError(
            'Failed to connect to zookeeper at %s.' % zkquorum)
    response, znodestat = None, None
    for _ in range(retries + 1):
        try:
            response, znodestat = zk_client.get(path)
        except NoNodeError:
            time.sleep(3.0)
            continue
        else:
            break
    if response is None:
        raise exceptions.NoSuchZookeeperNodeError(
            'ZooKeeper does not contain a %s node.' % path)
    zk_client.stop()

    # the message contains at least 5 bytes with the following structure:
    # (1B)(4B)... => (b'\xff')(meta_size)...
    if len(response) < 5:
        raise exceptions.ZookeeperProtocolError(
            'ZooKeeper returned too few response. Response size: %d.' %
            len(response))
    tag, meta_size = struct.unpack('>cI', response[:5])
    if tag != b'\xff':
        raise exceptions.ZookeeperProtocolError(
            'ZooKeeper returned an invalid response. b\'\\xff\' expected, got %s'
            % tag)
    if meta_size <= 0 or meta_size > 65000:
        raise exceptions.ZookeeperProtocolError(
            'ZooKeeper returned an invalid meta size %d.' % meta_size)

    # (meta_size B)(4B)... => (meta)(b'PBUF')...
    magic = struct.unpack('>4s', response[meta_size + 5:meta_size + 9])[0]
    if magic != b'PBUF':
        raise exceptions.ZookeeperProtocolError(
            'ZooKeeper returned an invalid response. b\'PBUF\' expected, got %s.'
            % magic)

    meta = pb.MetaRegionServer()
    try:
        meta.ParseFromString(response[meta_size + 9:])
    except DecodeError:
        raise exceptions.ZookeeperProtocolError(
            'Failed to parse MetaRegionServer from response.')
    return meta.server.host_name, meta.server.port
示例#6
0
 def _put_response(self, call_id, header, data, error):
     with self._resp_lock:
         if call_id in self._resp_dict:
             raise exceptions.TransportError(
                 'FATAL ERROR: Response for call [%d] exists.' % call_id)
         self._resp_dict[call_id] = (header, data, error)