Skip to content

Commit 5db32b8

Browse files
steveloughranGabor Bota
authored andcommitted
HADOOP-16547. make sure that s3guard prune sets up the FS (#1402). Contributed by Steve Loughran.
Change-Id: Iaf71561cef6c797a3c66fed110faf08da6cac361
1 parent 2c52d00 commit 5db32b8

File tree

2 files changed

+68
-10
lines changed

2 files changed

+68
-10
lines changed

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

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,10 @@ protected S3GuardTool(Configuration conf, String...opts) {
152152
/**
153153
* Parse DynamoDB region from either -m option or a S3 path.
154154
*
155-
* This function should only be called from {@link S3GuardTool.Init} or
156-
* {@link S3GuardTool.Destroy}.
155+
* Note that as a side effect, if the paths included an S3 path,
156+
* and there is no region set on the CLI, then the S3A FS is
157+
* initialized, after which {@link #filesystem} will no longer
158+
* be null.
157159
*
158160
* @param paths remaining parameters from CLI.
159161
* @throws IOException on I/O errors.
@@ -338,6 +340,7 @@ protected MetadataStore initMetadataStore(boolean forceCreate)
338340
* @throws ExitUtil.ExitException if the FS is not an S3A FS
339341
*/
340342
protected void initS3AFileSystem(String path) throws IOException {
343+
LOG.debug("Initializing S3A FS to {}", path);
341344
URI uri = toUri(path);
342345
// Make sure that S3AFileSystem does not hold an actual MetadataStore
343346
// implementation.
@@ -363,6 +366,28 @@ protected void initS3AFileSystem(String path) throws IOException {
363366
filesystem = (S3AFileSystem) fs;
364367
}
365368

369+
/**
370+
* Initialize the filesystem if there is none bonded to already and
371+
* the command line path list is not empty.
372+
* @param paths path list.
373+
* @return true if at the end of the call, getFilesystem() is not null
374+
* @throws IOException failure to instantiate.
375+
*/
376+
@VisibleForTesting
377+
boolean maybeInitFilesystem(final List<String> paths)
378+
throws IOException {
379+
// is there an S3 FS to create?
380+
if (getFilesystem() == null) {
381+
// none yet -create one
382+
if (!paths.isEmpty()) {
383+
initS3AFileSystem(paths.get(0));
384+
} else {
385+
LOG.debug("No path on command line, so not instantiating FS");
386+
}
387+
}
388+
return getFilesystem() != null;
389+
}
390+
366391
/**
367392
* Parse CLI arguments and returns the position arguments.
368393
* The options are stored in {@link #commandFormat}.
@@ -592,6 +617,7 @@ public int run(String[] args, PrintStream out) throws Exception {
592617
// Validate parameters.
593618
try {
594619
parseDynamoDBRegion(paths);
620+
maybeInitFilesystem(paths);
595621
} catch (ExitUtil.ExitException e) {
596622
errorln(USAGE);
597623
throw e;
@@ -644,6 +670,7 @@ public int run(String[] args, PrintStream out) throws Exception {
644670
checkBucketNameOrDDBTableNameProvided(paths);
645671
checkIfS3BucketIsGuarded(paths);
646672
parseDynamoDBRegion(paths);
673+
maybeInitFilesystem(paths);
647674
} catch (ExitUtil.ExitException e) {
648675
errorln(USAGE);
649676
throw e;
@@ -1064,11 +1091,13 @@ public int run(String[] args, PrintStream out) throws
10641091
InterruptedException, IOException {
10651092
List<String> paths = parseArgs(args);
10661093
try {
1094+
checkBucketNameOrDDBTableNameProvided(paths);
10671095
parseDynamoDBRegion(paths);
10681096
} catch (ExitUtil.ExitException e) {
10691097
errorln(USAGE);
10701098
throw e;
10711099
}
1100+
maybeInitFilesystem(paths);
10721101
initMetadataStore(false);
10731102

10741103
Configuration conf = getConf();

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

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@
2727
import java.net.URI;
2828
import java.util.Arrays;
2929
import java.util.Collection;
30+
import java.util.Collections;
3031
import java.util.HashSet;
3132
import java.util.List;
3233
import java.util.Set;
3334
import java.util.UUID;
34-
import java.util.concurrent.Callable;
3535
import java.util.concurrent.TimeUnit;
3636

3737
import org.apache.hadoop.fs.s3a.S3AUtils;
@@ -61,6 +61,7 @@
6161
import static org.apache.hadoop.fs.s3a.Constants.S3_METADATA_STORE_IMPL;
6262
import static org.apache.hadoop.fs.s3a.S3AUtils.clearBucketOption;
6363
import static org.apache.hadoop.fs.s3a.s3guard.S3GuardTool.E_BAD_STATE;
64+
import static org.apache.hadoop.fs.s3a.s3guard.S3GuardTool.INVALID_ARGUMENT;
6465
import static org.apache.hadoop.fs.s3a.s3guard.S3GuardTool.SUCCESS;
6566
import static org.apache.hadoop.fs.s3a.s3guard.S3GuardToolTestHelper.exec;
6667
import static org.apache.hadoop.test.LambdaTestUtils.intercept;
@@ -148,12 +149,7 @@ protected void runToFailure(int status, String... args)
148149
throws Exception {
149150
ExitUtil.ExitException ex =
150151
intercept(ExitUtil.ExitException.class,
151-
new Callable<Integer>() {
152-
@Override
153-
public Integer call() throws Exception {
154-
return run(args);
155-
}
156-
});
152+
() -> run(args));
157153
if (ex.status != status) {
158154
throw ex;
159155
}
@@ -333,6 +329,39 @@ public void testPruneCommandTombstones() throws Exception {
333329
"prune", "-" + S3GuardTool.Prune.TOMBSTONE,
334330
"-seconds", "0",
335331
testPath.toString());
332+
assertNotNull("Command did not create a filesystem",
333+
cmd.getFilesystem());
334+
}
335+
336+
/**
337+
* HADOOP-16457. In certain cases prune doesn't create an FS.
338+
*/
339+
@Test
340+
public void testMaybeInitFilesystem() throws Exception {
341+
Path testPath = path("maybeInitFilesystem");
342+
S3GuardTool.Prune cmd = new S3GuardTool.Prune(getFileSystem().getConf());
343+
cmd.maybeInitFilesystem(Collections.singletonList(testPath.toString()));
344+
assertNotNull("Command did not create a filesystem",
345+
cmd.getFilesystem());
346+
}
347+
348+
/**
349+
* HADOOP-16457. In certain cases prune doesn't create an FS.
350+
*/
351+
@Test
352+
public void testMaybeInitFilesystemNoPath() throws Exception {
353+
S3GuardTool.Prune cmd = new S3GuardTool.Prune(getFileSystem().getConf());
354+
cmd.maybeInitFilesystem(Collections.emptyList());
355+
assertNull("Command should not have created a filesystem",
356+
cmd.getFilesystem());
357+
}
358+
359+
@Test
360+
public void testPruneCommandNoPath() throws Exception {
361+
runToFailure(INVALID_ARGUMENT,
362+
S3GuardTool.Prune.NAME,
363+
"-" + S3GuardTool.Prune.TOMBSTONE,
364+
"-seconds", "0");
336365
}
337366

338367
@Test
@@ -476,7 +505,7 @@ public void testToolsNoArgsForBucket() throws Throwable {
476505
for (Class<? extends S3GuardTool> tool : tools) {
477506
S3GuardTool cmdR = makeBindedTool(tool);
478507
describe("Calling " + cmdR.getName() + " without any arguments.");
479-
assertExitCode(S3GuardTool.INVALID_ARGUMENT,
508+
assertExitCode(INVALID_ARGUMENT,
480509
intercept(ExitUtil.ExitException.class,
481510
() -> cmdR.run(new String[]{tool.getName()})));
482511
}

0 commit comments

Comments
 (0)