Skip to content

Commit 461276a

Browse files
authored
HADOOP-19393. [ABFS] Return FileAlreadyExistsException for UnauthorizedBlobOverwrite Rename Errors (#7312) (#7403)
Contributed by Manika Joshi. Signed off by Anuj Modi
1 parent 30eb66e commit 461276a

File tree

4 files changed

+28
-0
lines changed

4 files changed

+28
-0
lines changed

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/contracts/services/AzureServiceErrorCode.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ public enum AzureServiceErrorCode {
6565
COPY_BLOB_ABORTED("CopyBlobAborted", HttpURLConnection.HTTP_INTERNAL_ERROR, null),
6666
BLOB_OPERATION_NOT_SUPPORTED("BlobOperationNotSupported", HttpURLConnection.HTTP_CONFLICT, null),
6767
INVALID_APPEND_OPERATION("InvalidAppendOperation", HttpURLConnection.HTTP_CONFLICT, null),
68+
UNAUTHORIZED_BLOB_OVERWRITE("UnauthorizedBlobOverwrite", HttpURLConnection.HTTP_FORBIDDEN,
69+
"This request is not authorized to perform blob overwrites."),
6870
UNKNOWN(null, -1, null);
6971

7072
private final String errorCode;

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/services/AbfsDfsClient.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
import org.apache.hadoop.fs.FileSystem;
4444
import org.apache.hadoop.fs.Path;
45+
import org.apache.hadoop.fs.FileAlreadyExistsException;
4546
import org.apache.hadoop.fs.azurebfs.AbfsConfiguration;
4647
import org.apache.hadoop.fs.azurebfs.AzureBlobFileSystemStore;
4748
import org.apache.hadoop.fs.azurebfs.constants.AbfsHttpConstants;
@@ -132,6 +133,8 @@
132133
import static org.apache.hadoop.fs.azurebfs.constants.HttpQueryParams.QUERY_PARAM_RETAIN_UNCOMMITTED_DATA;
133134
import static org.apache.hadoop.fs.azurebfs.contracts.services.AzureServiceErrorCode.RENAME_DESTINATION_PARENT_PATH_NOT_FOUND;
134135
import static org.apache.hadoop.fs.azurebfs.contracts.services.AzureServiceErrorCode.SOURCE_PATH_NOT_FOUND;
136+
import static org.apache.hadoop.fs.azurebfs.contracts.services.AzureServiceErrorCode.UNAUTHORIZED_BLOB_OVERWRITE;
137+
import static org.apache.hadoop.fs.azurebfs.services.AbfsErrors.ERR_FILE_ALREADY_EXISTS;
135138

136139
/**
137140
* AbfsClient interacting with the DFS Endpoint.
@@ -702,6 +705,14 @@ public AbfsClientRenameResult renamePath(
702705
throw e;
703706
}
704707

708+
// ref: HADOOP-19393. Write permission checks can occur before validating
709+
// rename operation's validity. If there is an existing destination path, it may be rejected
710+
// with an authorization error. Catching and throwing FileAlreadyExistsException instead.
711+
if (op.getResult().getStorageErrorCode()
712+
.equals(UNAUTHORIZED_BLOB_OVERWRITE.getErrorCode())){
713+
throw new FileAlreadyExistsException(ERR_FILE_ALREADY_EXISTS);
714+
}
715+
705716
// ref: HADOOP-18242. Rename failure occurring due to a rare case of
706717
// tracking metadata being in incomplete state.
707718
if (op.getResult().getStorageErrorCode()

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/services/AbfsErrors.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
@InterfaceAudience.Public
2929
@InterfaceStability.Evolving
3030
public final class AbfsErrors {
31+
public static final String ERR_FILE_ALREADY_EXISTS = "File already exists.";
3132
public static final String ERR_WRITE_WITHOUT_LEASE = "Attempted to write to file without lease";
3233
public static final String ERR_LEASE_EXPIRED = "A lease ID was specified, but the lease for the resource has expired.";
3334
public static final String ERR_LEASE_EXPIRED_BLOB = "A lease ID was specified, but the lease for the blob has expired.";

hadoop-tools/hadoop-azure/src/test/java/org/apache/hadoop/fs/azurebfs/ITestAzureBlobFileSystemDelegationSAS.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
import org.apache.hadoop.fs.FSDataInputStream;
3636
import org.apache.hadoop.fs.FSDataOutputStream;
37+
import org.apache.hadoop.fs.FileAlreadyExistsException;
3738
import org.apache.hadoop.fs.FileStatus;
3839
import org.apache.hadoop.fs.FileSystem;
3940
import org.apache.hadoop.fs.Path;
@@ -52,6 +53,7 @@
5253

5354
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.FS_AZURE_SAS_TOKEN_PROVIDER_TYPE;
5455
import static org.apache.hadoop.fs.azurebfs.contracts.services.AzureServiceErrorCode.AUTHORIZATION_PERMISSION_MISS_MATCH;
56+
import static org.apache.hadoop.fs.azurebfs.services.AbfsErrors.ERR_FILE_ALREADY_EXISTS;
5557
import static org.apache.hadoop.fs.azurebfs.utils.AclTestHelpers.aclEntry;
5658
import static org.apache.hadoop.fs.contract.ContractTestUtils.assertPathDoesNotExist;
5759
import static org.apache.hadoop.fs.contract.ContractTestUtils.assertPathExists;
@@ -213,6 +215,18 @@ public void testReadAndWrite() throws Exception {
213215
}
214216
}
215217

218+
@Test
219+
public void checkExceptionForRenameOverwrites() throws Exception {
220+
final AzureBlobFileSystem fs = getFileSystem();
221+
222+
Path src = new Path("a/b/f1.txt");
223+
Path dest = new Path("a/b/f2.txt");
224+
touch(src);
225+
touch(dest);
226+
227+
intercept(FileAlreadyExistsException.class, ERR_FILE_ALREADY_EXISTS, () -> fs.rename(src, dest));
228+
}
229+
216230
@Test
217231
// Test rename file and rename folder
218232
public void testRename() throws Exception {

0 commit comments

Comments
 (0)