Exemple #1
0
    def test_write_connect_errors(self):
        test_cases = [
            {
                'error': green.ConnectionTimeout(1.0),
                'msg': 'connect: Connection timeout 1.0 second'
            },
            {
                'error': Exception('failure'),
                'msg': 'connect: failure'
            },
        ]
        for test in test_cases:
            checksum = self.checksum()
            source = empty_stream()
            size = CHUNK_SIZE * self.storage_method.ec_nb_data
            nb = self.storage_method.ec_nb_data + \
                self.storage_method.ec_nb_parity
            resps = [201] * (nb - 1)
            # Put the error in the middle to mess with chunk indices
            err_pos = random.randint(0, nb)
            resps.insert(err_pos, test['error'])
            with set_http_connect(*resps):
                handler = EcMetachunkWriter(self.sysmeta,
                                            self.meta_chunk_copy(), checksum,
                                            self.storage_method)
                bytes_transferred, checksum, chunks = handler.stream(
                    source, size)

            self.assertEqual(len(chunks), nb)
            for i in range(nb - 1):
                self.assertEqual(chunks[i].get('error'), None)
            self.assertEqual(chunks[nb - 1].get('error'), test['msg'])

            self.assertEqual(bytes_transferred, 0)
            self.assertEqual(checksum, EMPTY_MD5)
Exemple #2
0
    def connect(cls, chunk, sysmeta, reqid=None,
                connection_timeout=None, write_timeout=None, **kwargs):
        raw_url = chunk.get("real_url", chunk["url"])
        parsed = urlparse(raw_url)
        chunk_path = parsed.path.split('/')[-1]
        hdrs = headers_from_object_metadata(sysmeta)
        if reqid:
            hdrs['X-oio-req-id'] = reqid

        hdrs[CHUNK_HEADERS["chunk_pos"]] = chunk["pos"]
        hdrs[CHUNK_HEADERS["chunk_id"]] = chunk_path

        # in the trailer
        # metachunk_size & metachunk_hash
        trailers = (CHUNK_HEADERS["metachunk_size"],
                    CHUNK_HEADERS["metachunk_hash"])
        if kwargs.get('chunk_checksum_algo'):
            trailers = trailers + (CHUNK_HEADERS["chunk_hash"], )
        hdrs["Trailer"] = ', '.join(trailers)
        with green.ConnectionTimeout(
                connection_timeout or io.CONNECTION_TIMEOUT):
            conn = io.http_connect(
                parsed.netloc, 'PUT', parsed.path, hdrs)
            conn.chunk = chunk
        return cls(chunk, conn, write_timeout=write_timeout, **kwargs)
Exemple #3
0
    def connect(cls,
                chunk,
                sysmeta,
                reqid=None,
                connection_timeout=None,
                write_timeout=None,
                **_kwargs):
        raw_url = chunk["url"]
        parsed = urlparse(raw_url)
        chunk_path = parsed.path.split('/')[-1]
        hdrs = headers_from_object_metadata(sysmeta)
        if reqid:
            hdrs['X-oio-req-id'] = reqid

        hdrs[chunk_headers["chunk_pos"]] = chunk["pos"]
        hdrs[chunk_headers["chunk_id"]] = chunk_path

        # in the trailer
        # metachunk_size & metachunk_hash
        hdrs["Trailer"] = ', '.join(
            (chunk_headers["metachunk_size"], chunk_headers["metachunk_hash"],
             chunk_headers["chunk_hash"]))
        with green.ConnectionTimeout(connection_timeout
                                     or io.CONNECTION_TIMEOUT):
            conn = io.http_connect(parsed.netloc, 'PUT', parsed.path, hdrs)
            conn.chunk = chunk
        return cls(chunk, conn, write_timeout=write_timeout)
Exemple #4
0
    def _connect_put(self, chunk):
        """
        Create a connection in order to PUT `chunk`.

        :returns: a tuple with the connection object and `chunk`
        """
        raw_url = chunk["url"]
        parsed = urlparse(raw_url)
        try:
            chunk_path = parsed.path.split('/')[-1]
            hdrs = headers_from_object_metadata(self.sysmeta)
            hdrs[CHUNK_HEADERS["chunk_pos"]] = chunk["pos"]
            hdrs[CHUNK_HEADERS["chunk_id"]] = chunk_path
            hdrs.update(self.headers)

            with green.ConnectionTimeout(self.connection_timeout):
                conn = io.http_connect(
                    parsed.netloc, 'PUT', parsed.path, hdrs)
                conn.chunk = chunk
            return conn, chunk
        except (Exception, Timeout) as err:
            msg = str(err)
            logger.exception("Failed to connect to %s (%s)", chunk, msg)
            chunk['error'] = msg
            return None, chunk
Exemple #5
0
    def _get_request(self, chunk):
        """
        Connect to a chunk, fetch headers but don't read data.
        Save the response object in `self.sources` list.
        """
        try:
            with green.ConnectionTimeout(self.connection_timeout):
                raw_url = chunk["url"]
                parsed = urlparse(raw_url)
                conn = http_connect(parsed.netloc, 'GET', parsed.path,
                                    self.request_headers)
            with green.OioTimeout(self.read_timeout):
                source = conn.getresponse()
                source.conn = conn
        except (Exception, Timeout) as error:
            logger.exception('Connection failed to %s', chunk)
            self._resp_by_chunk[chunk["url"]] = (0, str(error))
            return False

        if source.status in (200, 206):
            self.status = source.status
            self._headers = source.getheaders()
            self.sources.append((source, chunk))
            return True
        else:
            logger.warn("Invalid response from %s: %d %s", chunk,
                        source.status, source.reason)
            self._resp_by_chunk[chunk["url"]] = (source.status,
                                                 str(source.reason))
        return False
Exemple #6
0
    def connect(cls,
                chunk,
                sysmeta,
                reqid=None,
                connection_timeout=None,
                write_timeout=None,
                **_kwargs):
        raw_url = chunk["url"]
        parsed = urlparse(raw_url)
        chunk_path = parsed.path.split('/')[-1]
        h = {}
        h["transfer-encoding"] = "chunked"
        h[chunk_headers["content_id"]] = sysmeta['id']
        h[chunk_headers["content_path"]] = sysmeta['content_path']
        h[chunk_headers["content_chunkmethod"]] = sysmeta['chunk_method']
        h[chunk_headers["container_id"]] = sysmeta['container_id']
        h[chunk_headers["chunk_pos"]] = chunk["pos"]
        h[chunk_headers["chunk_id"]] = chunk_path
        h[chunk_headers["content_policy"]] = sysmeta['policy']
        h[chunk_headers["content_version"]] = sysmeta['version']
        if reqid:
            h['X-oio-req-id'] = reqid

        # in the trailer
        # metachunk_size & metachunk_hash
        h["Trailer"] = (chunk_headers["metachunk_size"],
                        chunk_headers["metachunk_hash"])
        with green.ConnectionTimeout(connection_timeout
                                     or io.CONNECTION_TIMEOUT):
            conn = io.http_connect(parsed.netloc, 'PUT', parsed.path, h)
            conn.chunk = chunk
        return cls(chunk, conn, write_timeout=write_timeout)
Exemple #7
0
    def _get_request(self, chunk):
        """
        Connect to a chunk, fetch headers but don't read data.
        Save the response object in `self.sources` list.
        """
        try:
            with green.ConnectionTimeout(self.connection_timeout):
                raw_url = chunk.get("real_url", chunk["url"])
                parsed = urlparse(raw_url)
                if self.perfdata is not None:
                    connect_start = monotonic_time()
                conn = http_connect(parsed.netloc,
                                    'GET',
                                    parsed.path,
                                    self.request_headers,
                                    scheme=parsed.scheme)
                if self.perfdata is not None:
                    connect_end = monotonic_time()
                    rawx_perfdata = self.perfdata.setdefault('rawx', dict())
                    rawx_perfdata['connect.' + chunk['url']] = \
                        connect_end - connect_start
            with green.OioTimeout(self.read_timeout):
                source = conn.getresponse()
                source.conn = conn
                if self.perfdata is not None:
                    source.download_start = monotonic_time()
        except (SocketError, Timeout) as err:
            self.logger.error('Connection failed to %s (reqid=%s): %s', chunk,
                              self.reqid, err)
            self._resp_by_chunk[chunk["url"]] = (0, text_type(err))
            return False
        except Exception as err:
            self.logger.exception('Connection failed to %s (reqid=%s)', chunk,
                                  self.reqid)
            self._resp_by_chunk[chunk["url"]] = (0, text_type(err))
            return False

        if source.status in (200, 206):
            self.status = source.status
            self._headers = [(k.lower(), v) for k, v in source.getheaders()]
            self.sources.append((source, chunk))
            return True
        else:
            self.logger.warn("Invalid response from %s (reqid=%s): %d %s",
                             chunk, self.reqid, source.status, source.reason)
            self._resp_by_chunk[chunk["url"]] = (source.status,
                                                 text_type(source.reason))
            close_source(source, self.logger)
        return False
Exemple #8
0
    def _get_response(self, chunk, headers):
        resp = None
        parsed = urlparse(chunk['url'])
        try:
            with green.ConnectionTimeout(self.connection_timeout):
                conn = io.http_connect(parsed.netloc, 'GET', parsed.path,
                                       headers)

            with Timeout(self.read_timeout):
                resp = conn.getresponse()
            if resp.status != 200:
                logger.warning('Invalid GET response from %s', chunk)
                resp = None
        except (Exception, Timeout):
            logger.exception('ERROR fetching %s', chunk)
        return resp
Exemple #9
0
    def _get_response(self, chunk, headers):
        resp = None
        parsed = urlparse(chunk.get('real_url', chunk['url']))
        try:
            with green.ConnectionTimeout(self.connection_timeout):
                conn = io.http_connect(
                    parsed.netloc, 'GET', parsed.path, headers)

            with Timeout(self.read_timeout):
                resp = conn.getresponse()
            if resp.status != 200:
                logger.warning('Invalid GET response from %s: %s %s',
                               chunk, resp.status, resp.reason)
                resp = None
        except (SocketError, Timeout) as err:
            logger.error('ERROR fetching %s: %s', chunk, err)
        except Exception:
            logger.exception('ERROR fetching %s', chunk)
        return resp
Exemple #10
0
    def _connect_put(self, chunk):
        """
        Create a connection in order to PUT `chunk`.

        :returns: a tuple with the connection object and `chunk`
        """
        raw_url = chunk.get("real_url", chunk["url"])
        parsed = urlparse(raw_url)
        try:
            chunk_path = parsed.path.split('/')[-1]
            hdrs = headers_from_object_metadata(self.sysmeta)
            hdrs[CHUNK_HEADERS["chunk_pos"]] = chunk["pos"]
            hdrs[CHUNK_HEADERS["chunk_id"]] = chunk_path
            hdrs.update(self.headers)
            hdrs = encode(hdrs)

            with green.ConnectionTimeout(self.connection_timeout):
                if self.perfdata is not None:
                    connect_start = monotonic_time()
                conn = io.http_connect(parsed.netloc,
                                       'PUT',
                                       parsed.path,
                                       hdrs,
                                       scheme=parsed.scheme)
                conn.set_cork(True)
                if self.perfdata is not None:
                    connect_end = monotonic_time()
                    perfdata_rawx = self.perfdata.setdefault('rawx', dict())
                    perfdata_rawx['connect.' + chunk['url']] = \
                        connect_end - connect_start
                conn.chunk = chunk
            return conn, chunk
        except (SocketError, Timeout) as err:
            msg = str(err)
            self.logger.warn("Failed to connect to %s (reqid=%s): %s", chunk,
                             self.reqid, err)
        except Exception as err:
            msg = str(err)
            self.logger.exception("Failed to connect to %s (reqid=%s)", chunk,
                                  self.reqid)
        chunk['error'] = msg
        return None, chunk