Skip to content

Commit 0f96e64

Browse files
author
HarshitGupta11
committed
First Commit
1 parent e09e81a commit 0f96e64

6 files changed

Lines changed: 458 additions & 18 deletions

File tree

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/AbstractFileSystem.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -850,8 +850,23 @@ public void renameInternal(final Path src, final Path dst,
850850
FileAlreadyExistsException, FileNotFoundException,
851851
ParentNotDirectoryException, UnresolvedLinkException, IOException {
852852
// Default implementation deals with overwrite in a non-atomic way
853-
final FileStatus srcStatus = getFileLinkStatus(src);
853+
if (checkIfCanRename(src, dst, overwrite)) {
854+
delete(dst, false);
855+
}
856+
renameInternal(src, dst);
857+
}
854858

859+
/**
860+
* Check if the given rename can proceed and return true if the destination directory or file needs
861+
* to be deleted for the rename to proceed.
862+
* @param src source of the file
863+
* @param dst dst of the rename
864+
* @param overwrite if overwrite is allowed
865+
* @return a boolean reflecting if the dst needs to be deleted
866+
* @throws IOException
867+
*/
868+
public boolean checkIfCanRename(Path src, Path dst, boolean overwrite) throws IOException {
869+
final FileStatus srcStatus = getFileLinkStatus(src);
855870
FileStatus dstStatus;
856871
try {
857872
dstStatus = getFileLinkStatus(dst);
@@ -884,16 +899,15 @@ public void renameInternal(final Path src, final Path dst,
884899
"Rename cannot overwrite non empty destination directory " + dst);
885900
}
886901
}
887-
delete(dst, false);
902+
return true;
888903
} else {
889904
final Path parent = dst.getParent();
890905
final FileStatus parentStatus = getFileStatus(parent);
891906
if (parentStatus.isFile()) {
892-
throw new ParentNotDirectoryException("Rename destination parent "
893-
+ parent + " is a file.");
907+
throw new ParentNotDirectoryException("Rename destination parent " + parent + " is a file.");
894908
}
895909
}
896-
renameInternal(src, dst);
910+
return false;
897911
}
898912

899913
/**

hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/Constants.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,4 +1255,10 @@ private Constants() {
12551255
*/
12561256
public static final String PREFETCH_BLOCK_COUNT_KEY = "fs.s3a.prefetch.block.count";
12571257
public static final int PREFETCH_BLOCK_DEFAULT_COUNT = 8;
1258+
1259+
/**
1260+
* Create a fake parent directory on deletes
1261+
*/
1262+
public static final String CREATE_FAKE_PARENT_DIRECTORY = "fs.s3a.create.fake.parent.directory";
1263+
public static final boolean CREATE_FAKE_PARENT_DIRECTORY_DEFAULT = true;
12581264
}

hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/S3A.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,15 @@
2222
import org.apache.hadoop.classification.InterfaceStability;
2323
import org.apache.hadoop.conf.Configuration;
2424
import org.apache.hadoop.fs.DelegateToFileSystem;
25+
import org.apache.hadoop.fs.FileAlreadyExistsException;
26+
import org.apache.hadoop.fs.ParentNotDirectoryException;
27+
import org.apache.hadoop.fs.Path;
28+
import org.apache.hadoop.fs.UnresolvedLinkException;
29+
import org.apache.hadoop.security.AccessControlException;
30+
import org.slf4j.Logger;
31+
import org.slf4j.LoggerFactory;
2532

33+
import java.io.FileNotFoundException;
2634
import java.io.IOException;
2735
import java.net.URI;
2836
import java.net.URISyntaxException;
@@ -35,6 +43,8 @@
3543
@InterfaceStability.Evolving
3644
public class S3A extends DelegateToFileSystem {
3745

46+
private final Logger LOG = LoggerFactory.getLogger(this.getClass().getName());
47+
3848
public S3A(URI theUri, Configuration conf)
3949
throws IOException, URISyntaxException {
4050
super(theUri, new S3AFileSystem(), conf, "s3a", false);
@@ -55,6 +65,13 @@ public String toString() {
5565
return sb.toString();
5666
}
5767

68+
@Override
69+
public void renameInternal(final Path src, final Path dst,
70+
boolean overwrite) throws IOException {
71+
checkIfCanRename(src, dst, overwrite);
72+
fsImpl.rename(src, dst);
73+
}
74+
5875
/**
5976
* Close the file system; the FileContext API doesn't have an explicit close.
6077
*/

hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/S3AFileSystem.java

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,11 @@ public class S3AFileSystem extends FileSystem implements StreamCapabilities,
420420
*/
421421
private final Set<Path> deleteOnExit = new TreeSet<>();
422422

423+
/**
424+
* Fake parent directory for cleanup
425+
*/
426+
private boolean createFakeParentDirectory;
427+
423428
/** Add any deprecated keys. */
424429
@SuppressWarnings("deprecation")
425430
private static void addDeprecatedKeys() {
@@ -518,6 +523,7 @@ public void initialize(URI name, Configuration originalConf)
518523
MULTIPART_SIZE, DEFAULT_MULTIPART_SIZE);
519524
multiPartThreshold = getMultipartSizeProperty(conf,
520525
MIN_MULTIPART_THRESHOLD, DEFAULT_MIN_MULTIPART_THRESHOLD);
526+
createFakeParentDirectory = conf.getBoolean(CREATE_FAKE_PARENT_DIRECTORY, CREATE_FAKE_PARENT_DIRECTORY_DEFAULT);
521527

522528
//check but do not store the block size
523529
longBytesOption(conf, FS_S3A_BLOCK_SIZE, DEFAULT_BLOCKSIZE, 1);
@@ -2094,7 +2100,7 @@ private Pair<S3AFileStatus, S3AFileStatus> initiateRename(
20942100
// at this point the destination is an empty directory
20952101
} else {
20962102
// source is a file. The destination must be a directory,
2097-
// empty or not
2103+
// empty or not existing
20982104
if (dstStatus.isFile()) {
20992105
throw new FileAlreadyExistsException(
21002106
"Failed to rename " + src + " to " + dst
@@ -2156,22 +2162,28 @@ private long innerRename(Path source, Path dest)
21562162
Path src = qualify(source);
21572163
Path dst = qualify(dest);
21582164

2159-
LOG.debug("Rename path {} to {}", src, dst);
2165+
LOG.warn("Rename path {} to {}", src, dst);
21602166

21612167
String srcKey = pathToKey(src);
21622168
String dstKey = pathToKey(dst);
2163-
2164-
Pair<S3AFileStatus, S3AFileStatus> p = initiateRename(src, dst);
2169+
Pair<S3AFileStatus, S3AFileStatus> p;
2170+
try{
2171+
p = initiateRename(src, dst);
2172+
RenameOperation renameOperation = new RenameOperation(
2173+
createStoreContext(),
2174+
src, srcKey, p.getLeft(),
2175+
dst, dstKey, p.getRight(),
2176+
new OperationCallbacksImpl(),
2177+
pageSize);
2178+
LOG.warn("Please do your thing:");
2179+
return renameOperation.execute();
2180+
} catch (Exception e) {
2181+
LOG.error("This is why it doesn't work", e);
2182+
}
21652183

21662184
// Initiate the rename.
21672185
// this will call back into this class via the rename callbacks
2168-
RenameOperation renameOperation = new RenameOperation(
2169-
createStoreContext(),
2170-
src, srcKey, p.getLeft(),
2171-
dst, dstKey, p.getRight(),
2172-
new OperationCallbacksImpl(),
2173-
pageSize);
2174-
return renameOperation.execute();
2186+
return 0;
21752187
}
21762188

21772189
@Override public Token<? extends TokenIdentifier> getFsDelegationToken()
@@ -3253,7 +3265,7 @@ private void createFakeDirectoryIfNecessary(Path f)
32533265
protected void maybeCreateFakeParentDirectory(Path path)
32543266
throws IOException, AmazonClientException {
32553267
Path parent = path.getParent();
3256-
if (parent != null && !parent.isRoot() && !isUnderMagicCommitPath(parent)) {
3268+
if (parent != null && !parent.isRoot() && !isUnderMagicCommitPath(parent) && createFakeParentDirectory) {
32573269
createFakeDirectoryIfNecessary(parent);
32583270
}
32593271
}

hadoop-tools/hadoop-aws/src/test/java/org/apache/hadoop/fs/s3a/ITestS3AEmptyDirectory.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public void testDirectoryBecomesEmpty() throws Exception {
3838

3939
// 1. set up non-empty dir
4040
Path dir = path("testEmptyDir");
41+
// add a rm of dir to guarantee its not there
4142
Path child = path("testEmptyDir/dir2");
4243
mkdirs(child);
4344

@@ -47,7 +48,7 @@ public void testDirectoryBecomesEmpty() throws Exception {
4748
// 2. Make testEmptyDir empty
4849
assertDeleted(child, false);
4950
status = getS3AFileStatus(fs, dir);
50-
51+
// all parent directories are being created and if not then we expect this to fail
5152
assertEmptyDirectory(true, status);
5253
}
5354

0 commit comments

Comments
 (0)