Uses a GCS API command to copy the object and then deletes the old one.
| 1619 | |
| 1620 | // Uses a GCS API command to copy the object and then deletes the old one. |
| 1621 | Status GcsFileSystem::RenameObject(const string& src, const string& target) { |
| 1622 | string src_bucket, src_object, target_bucket, target_object; |
| 1623 | TF_RETURN_IF_ERROR(ParseGcsPath(src, false, &src_bucket, &src_object)); |
| 1624 | TF_RETURN_IF_ERROR( |
| 1625 | ParseGcsPath(target, false, &target_bucket, &target_object)); |
| 1626 | |
| 1627 | std::unique_ptr<HttpRequest> request; |
| 1628 | TF_RETURN_IF_ERROR(CreateHttpRequest(&request)); |
| 1629 | request->SetUri(strings::StrCat(kGcsUriBase, "b/", src_bucket, "/o/", |
| 1630 | request->EscapeString(src_object), |
| 1631 | "/rewriteTo/b/", target_bucket, "/o/", |
| 1632 | request->EscapeString(target_object))); |
| 1633 | request->SetPostEmptyBody(); |
| 1634 | request->SetTimeouts(timeouts_.connect, timeouts_.idle, timeouts_.metadata); |
| 1635 | std::vector<char> output_buffer; |
| 1636 | request->SetResultBuffer(&output_buffer); |
| 1637 | TF_RETURN_WITH_CONTEXT_IF_ERROR(request->Send(), " when renaming ", src, |
| 1638 | " to ", target); |
| 1639 | // Flush the target from the caches. The source will be flushed in the |
| 1640 | // DeleteFile call below. |
| 1641 | ClearFileCaches(target); |
| 1642 | Json::Value root; |
| 1643 | TF_RETURN_IF_ERROR(ParseJson(output_buffer, &root)); |
| 1644 | bool done; |
| 1645 | TF_RETURN_IF_ERROR(GetBoolValue(root, "done", &done)); |
| 1646 | if (!done) { |
| 1647 | // If GCS didn't complete rewrite in one call, this means that a large file |
| 1648 | // is being copied to a bucket with a different storage class or location, |
| 1649 | // which requires multiple rewrite calls. |
| 1650 | // TODO(surkov): implement multi-step rewrites. |
| 1651 | return errors::Unimplemented( |
| 1652 | "Couldn't rename ", src, " to ", target, |
| 1653 | ": moving large files between buckets with different " |
| 1654 | "locations or storage classes is not supported."); |
| 1655 | } |
| 1656 | |
| 1657 | // In case the delete API call failed, but the deletion actually happened |
| 1658 | // on the server side, we can't just retry the whole RenameFile operation |
| 1659 | // because the source object is already gone. |
| 1660 | return RetryingUtils::DeleteWithRetries( |
| 1661 | [this, &src]() { return DeleteFile(src); }, retry_config_); |
| 1662 | } |
| 1663 | |
| 1664 | Status GcsFileSystem::IsDirectory(const string& fname) { |
| 1665 | string bucket, object; |
nothing calls this directly
no test coverage detected