Skip to content

Commit

Permalink
HADOOP-19393. [ABFS] Return FileAlreadyExistsException for Unauthoriz…
Browse files Browse the repository at this point in the history
…edBlobOverwrite Rename Errors (apache#7312)

Contributed by Manika Joshi.
  • Loading branch information
manika137 authored Feb 17, 2025
1 parent c42469e commit f1df748
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ public enum AzureServiceErrorCode {
COPY_BLOB_ABORTED("CopyBlobAborted", HttpURLConnection.HTTP_INTERNAL_ERROR, null),
BLOB_OPERATION_NOT_SUPPORTED("BlobOperationNotSupported", HttpURLConnection.HTTP_CONFLICT, null),
INVALID_APPEND_OPERATION("InvalidAppendOperation", HttpURLConnection.HTTP_CONFLICT, null),
UNAUTHORIZED_BLOB_OVERWRITE("UnauthorizedBlobOverwrite", HttpURLConnection.HTTP_FORBIDDEN,
"This request is not authorized to perform blob overwrites."),
UNKNOWN(null, -1, null);

private final String errorCode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.FileAlreadyExistsException;
import org.apache.hadoop.fs.azurebfs.AbfsConfiguration;
import org.apache.hadoop.fs.azurebfs.AzureBlobFileSystemStore;
import org.apache.hadoop.fs.azurebfs.constants.AbfsHttpConstants;
Expand Down Expand Up @@ -132,6 +133,8 @@
import static org.apache.hadoop.fs.azurebfs.constants.HttpQueryParams.QUERY_PARAM_RETAIN_UNCOMMITTED_DATA;
import static org.apache.hadoop.fs.azurebfs.contracts.services.AzureServiceErrorCode.RENAME_DESTINATION_PARENT_PATH_NOT_FOUND;
import static org.apache.hadoop.fs.azurebfs.contracts.services.AzureServiceErrorCode.SOURCE_PATH_NOT_FOUND;
import static org.apache.hadoop.fs.azurebfs.contracts.services.AzureServiceErrorCode.UNAUTHORIZED_BLOB_OVERWRITE;
import static org.apache.hadoop.fs.azurebfs.services.AbfsErrors.ERR_FILE_ALREADY_EXISTS;

/**
* AbfsClient interacting with the DFS Endpoint.
Expand Down Expand Up @@ -702,6 +705,14 @@ public AbfsClientRenameResult renamePath(
throw e;
}

// ref: HADOOP-19393. Write permission checks can occur before validating
// rename operation's validity. If there is an existing destination path, it may be rejected
// with an authorization error. Catching and throwing FileAlreadyExistsException instead.
if (op.getResult().getStorageErrorCode()
.equals(UNAUTHORIZED_BLOB_OVERWRITE.getErrorCode())){
throw new FileAlreadyExistsException(ERR_FILE_ALREADY_EXISTS);
}

// ref: HADOOP-18242. Rename failure occurring due to a rare case of
// tracking metadata being in incomplete state.
if (op.getResult().getStorageErrorCode()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
@InterfaceAudience.Public
@InterfaceStability.Evolving
public final class AbfsErrors {
public static final String ERR_FILE_ALREADY_EXISTS = "File already exists.";
public static final String ERR_WRITE_WITHOUT_LEASE = "Attempted to write to file without lease";
public static final String ERR_LEASE_EXPIRED = "A lease ID was specified, but the lease for the resource has expired.";
public static final String ERR_LEASE_EXPIRED_BLOB = "A lease ID was specified, but the lease for the blob has expired.";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileAlreadyExistsException;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
Expand All @@ -52,6 +53,7 @@

import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.FS_AZURE_SAS_TOKEN_PROVIDER_TYPE;
import static org.apache.hadoop.fs.azurebfs.contracts.services.AzureServiceErrorCode.AUTHORIZATION_PERMISSION_MISS_MATCH;
import static org.apache.hadoop.fs.azurebfs.services.AbfsErrors.ERR_FILE_ALREADY_EXISTS;
import static org.apache.hadoop.fs.azurebfs.utils.AclTestHelpers.aclEntry;
import static org.apache.hadoop.fs.contract.ContractTestUtils.assertPathDoesNotExist;
import static org.apache.hadoop.fs.contract.ContractTestUtils.assertPathExists;
Expand Down Expand Up @@ -213,6 +215,18 @@ public void testReadAndWrite() throws Exception {
}
}

@Test
public void checkExceptionForRenameOverwrites() throws Exception {
final AzureBlobFileSystem fs = getFileSystem();

Path src = new Path("a/b/f1.txt");
Path dest = new Path("a/b/f2.txt");
touch(src);
touch(dest);

intercept(FileAlreadyExistsException.class, ERR_FILE_ALREADY_EXISTS, () -> fs.rename(src, dest));
}

@Test
// Test rename file and rename folder
public void testRename() throws Exception {
Expand Down

0 comments on commit f1df748

Please sign in to comment.