From bd2d97adeea55bf2c7e4ab475bcc90f3a14e751a Mon Sep 17 00:00:00 2001 From: Mingfei Date: Tue, 23 Aug 2016 16:18:34 +0800 Subject: [PATCH] HADOOP-13483. File create should throw error rather than overwrite directories. Contributed by Genmao Yu. --- .../fs/aliyun/oss/AliyunOSSFileSystem.java | 25 ++++++++++++++++--- .../oss/contract/TestOSSContractCreate.java | 6 ----- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/hadoop-tools/hadoop-aliyun/src/main/java/org/apache/hadoop/fs/aliyun/oss/AliyunOSSFileSystem.java b/hadoop-tools/hadoop-aliyun/src/main/java/org/apache/hadoop/fs/aliyun/oss/AliyunOSSFileSystem.java index 6923b9513af..99a60dbf664 100644 --- a/hadoop-tools/hadoop-aliyun/src/main/java/org/apache/hadoop/fs/aliyun/oss/AliyunOSSFileSystem.java +++ b/hadoop-tools/hadoop-aliyun/src/main/java/org/apache/hadoop/fs/aliyun/oss/AliyunOSSFileSystem.java @@ -63,6 +63,8 @@ import com.aliyun.oss.model.ObjectMetadata; import com.aliyun.oss.model.PartETag; import com.aliyun.oss.model.UploadPartCopyRequest; import com.aliyun.oss.model.UploadPartCopyResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Implementation of {@link FileSystem} for @@ -70,6 +72,8 @@ import com.aliyun.oss.model.UploadPartCopyResult; */ public class AliyunOSSFileSystem extends FileSystem { + private static final Logger LOG = + LoggerFactory.getLogger(AliyunOSSFileSystem.class); private URI uri; private Path workingDir; private OSSClient ossClient; @@ -101,9 +105,24 @@ public class AliyunOSSFileSystem extends FileSystem { boolean overwrite, int bufferSize, short replication, long blockSize, Progressable progress) throws IOException { String key = pathToKey(path); + FileStatus status = null; - if (!overwrite && exists(path)) { - throw new FileAlreadyExistsException(path + " already exists"); + try { + // get the status or throw a FNFE + status = getFileStatus(path); + + // if the thread reaches here, there is something at the path + if (status.isDirectory()) { + // path references a directory + throw new FileAlreadyExistsException(path + " is a directory"); + } + if (!overwrite) { + // path references a file and overwrite is disabled + throw new FileAlreadyExistsException(path + " already exists"); + } + LOG.debug("Overwriting file {}", path); + } catch (FileNotFoundException e) { + // this means the file is not found } return new FSDataOutputStream(new AliyunOSSOutputStream(getConf(), @@ -540,7 +559,7 @@ public class AliyunOSSFileSystem extends FileSystem { /** * Used to create an empty file that represents an empty directory. * - * @param bucketName the bucket this directory belongs to + * @param bucket the bucket this directory belongs to * @param objectName directory path * @return true if directory successfully created * @throws IOException diff --git a/hadoop-tools/hadoop-aliyun/src/test/java/org/apache/hadoop/fs/aliyun/oss/contract/TestOSSContractCreate.java b/hadoop-tools/hadoop-aliyun/src/test/java/org/apache/hadoop/fs/aliyun/oss/contract/TestOSSContractCreate.java index cc5a2d17527..ce927a97b39 100644 --- a/hadoop-tools/hadoop-aliyun/src/test/java/org/apache/hadoop/fs/aliyun/oss/contract/TestOSSContractCreate.java +++ b/hadoop-tools/hadoop-aliyun/src/test/java/org/apache/hadoop/fs/aliyun/oss/contract/TestOSSContractCreate.java @@ -21,7 +21,6 @@ package org.apache.hadoop.fs.aliyun.oss.contract; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.contract.AbstractContractCreateTest; import org.apache.hadoop.fs.contract.AbstractFSContract; -import org.apache.hadoop.fs.contract.ContractTestUtils; /** * OSS contract creating tests. @@ -33,9 +32,4 @@ public class TestOSSContractCreate extends AbstractContractCreateTest { return new OSSContract(conf); } - @Override - public void testOverwriteEmptyDirectory() throws Throwable { - ContractTestUtils.skip( - "blobstores can't distinguish empty directories from files"); - } }