Skip to content

Commit 1887f33

Browse files
committed
HADOOP-17227. Marker Tool tuning
* fix checkstyle * use bulder API for passing (Growing) set of params around Change-Id: I1ce980a4d7d4f5e9ad7f1c7b7fa4c6fd9806b8f1
1 parent 5a66f87 commit 1887f33

File tree

4 files changed

+228
-65
lines changed

4 files changed

+228
-65
lines changed

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import java.net.URI;
2626
import java.net.URISyntaxException;
2727
import java.nio.file.AccessDeniedException;
28-
import java.time.Duration;
2928
import java.util.Arrays;
3029
import java.util.Collection;
3130
import java.util.Date;
@@ -760,8 +759,8 @@ public int run(String[] args, PrintStream out) throws Exception {
760759
*/
761760
static class Destroy extends S3GuardTool {
762761
public static final String NAME = "destroy";
763-
public static final String PURPOSE = "destroy the Metadata Store including its contents"
764-
+ DATA_IN_S3_IS_PRESERVED;
762+
public static final String PURPOSE = "destroy the Metadata Store including its"
763+
+ " contents" + DATA_IN_S3_IS_PRESERVED;
765764
private static final String USAGE = NAME + " [OPTIONS] [s3a://BUCKET]\n" +
766765
"\t" + PURPOSE + "\n\n" +
767766
"Common options:\n" +

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

Lines changed: 203 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -280,14 +280,17 @@ public int run(final String[] args, final PrintStream stream)
280280
path = new Path(path, "/");
281281
}
282282
FileSystem fs = path.getFileSystem(getConf());
283+
boolean nonAuth = command.getOpt(OPT_NONAUTH);
283284
ScanResult result = execute(
284-
fs,
285-
path,
286-
clean,
287-
expectedMin,
288-
expectedMax,
289-
limit,
290-
command.getOpt(OPT_NONAUTH));
285+
new ScanArgsBuilder()
286+
.withSourceFS(fs)
287+
.withPath(path)
288+
.withDoPurge(clean)
289+
.withMinMarkerCount(expectedMin)
290+
.withMaxMarkerCount(expectedMax)
291+
.withLimit(limit)
292+
.withNonAuth(nonAuth)
293+
.build());
291294
if (verbose) {
292295
dumpFileSystemStatistics(out);
293296
}
@@ -329,7 +332,8 @@ private int getOptValue(String option, int defVal) {
329332
return Integer.parseInt(value);
330333
} catch (NumberFormatException e) {
331334
throw new ExitUtil.ExitException(EXIT_USAGE,
332-
String.format("Argument for %s is not a number: %s", option, value));
335+
String.format("Argument for %s is not a number: %s",
336+
option, value));
333337
}
334338
} else {
335339
return defVal;
@@ -338,27 +342,14 @@ private int getOptValue(String option, int defVal) {
338342

339343
/**
340344
* Execute the scan/purge.
341-
* @param sourceFS source FS; must be or wrap an S3A FS.
342-
* @param path path to scan.
343-
* @param doPurge purge?
344-
* @param minMarkerCount min marker count (ignored on purge)
345-
* @param maxMarkerCount max marker count (ignored on purge)
346-
* @param limit limit of files to scan; 0 for 'unlimited'
347-
* @param nonAuth consider only markers in nonauth paths as errors
348-
* @return scan+purge result.
345+
*
346+
* @param scanArgs@return scan+purge result.
349347
* @throws IOException failure
350348
*/
351349
@VisibleForTesting
352-
ScanResult execute(
353-
final FileSystem sourceFS,
354-
final Path path,
355-
final boolean doPurge,
356-
final int minMarkerCount,
357-
final int maxMarkerCount,
358-
final int limit,
359-
final boolean nonAuth)
350+
ScanResult execute(final ScanArgs scanArgs)
360351
throws IOException {
361-
S3AFileSystem fs = bindFilesystem(sourceFS);
352+
S3AFileSystem fs = bindFilesystem(scanArgs.getSourceFS());
362353

363354
// extract the callbacks needed for the rest of the work
364355
storeContext = fs.createStoreContext();
@@ -379,6 +370,7 @@ ScanResult execute(
379370
println(out, "Authoritative path list is \"%s\"", authPath);
380371
}
381372
// qualify the path
373+
Path path = scanArgs.getPath();
382374
Path target = path.makeQualified(fs.getUri(), new Path("/"));
383375
// initial safety check: does the path exist?
384376
try {
@@ -396,18 +388,18 @@ ScanResult execute(
396388

397389
// the default filter policy is that all entries should be deleted
398390
DirectoryPolicy filterPolicy;
399-
if (nonAuth) {
391+
if (scanArgs.isNonAuth()) {
400392
filterPolicy = new DirectoryPolicyImpl(
401393
DirectoryPolicy.MarkerPolicy.Authoritative,
402394
fs::allowAuthoritative);
403395
} else {
404396
filterPolicy = null;
405397
}
406398
ScanResult result = scan(target,
407-
doPurge,
408-
maxMarkerCount,
409-
minMarkerCount,
410-
limit,
399+
scanArgs.isDoPurge(),
400+
scanArgs.getMaxMarkerCount(),
401+
scanArgs.getMinMarkerCount(),
402+
scanArgs.getLimit(),
411403
filterPolicy);
412404
return result;
413405
}
@@ -434,7 +426,7 @@ public static final class ScanResult {
434426

435427
/**
436428
* Count of all markers found after excluding
437-
* any from a [-nonauth] qualification;
429+
* any from a [-nonauth] qualification.
438430
*/
439431
private int filteredMarkerCount;
440432

@@ -619,7 +611,11 @@ private ScanResult scan(
619611
* @param args arguments for the error message
620612
* @return scan result
621613
*/
622-
private ScanResult failScan(ScanResult result, int code, String message, Object...args) {
614+
private ScanResult failScan(
615+
ScanResult result,
616+
int code,
617+
String message,
618+
Object...args) {
623619
String text = String.format(message, args);
624620
result.exitCode = code;
625621
result.exitText = text;
@@ -688,7 +684,7 @@ private boolean scanDirectoryTree(
688684
* Result of a call of {@link #purgeMarkers(DirMarkerTracker, int)};
689685
* included in {@link ScanResult} so must share visibility.
690686
*/
691-
static final class MarkerPurgeSummary {
687+
public static final class MarkerPurgeSummary {
692688

693689
/** Number of markers deleted. */
694690
private int markersDeleted;
@@ -714,14 +710,26 @@ public String toString() {
714710
}
715711

716712

713+
/**
714+
* Count of markers deleted.
715+
* @return a number, zero when prune==false.
716+
*/
717717
int getMarkersDeleted() {
718718
return markersDeleted;
719719
}
720720

721+
/**
722+
* Count of bulk delete requests issued.
723+
* @return count of calls made to S3.
724+
*/
721725
int getDeleteRequests() {
722726
return deleteRequests;
723727
}
724728

729+
/**
730+
* Total duration of delete requests.
731+
* @return a time interval in millis.
732+
*/
725733
long getTotalDeleteRequestDuration() {
726734
return totalDeleteRequestDuration;
727735
}
@@ -800,28 +808,173 @@ public void setVerbose(final boolean verbose) {
800808
/**
801809
* Execute the marker tool, with no checks on return codes.
802810
*
803-
* @param sourceFS filesystem to use
804-
* @param path path to scan
805-
* @param doPurge should markers be purged
806-
* @param minMarkerCount min marker count (ignored on purge)
807-
* @param maxMarkerCount max marker count (ignored on purge)
808-
* @param limit limit of files to scan; -1 for 'unlimited'
809-
* @param nonAuth only use nonauth path count for failure rules
811+
* @param scanArgs set of args for the scanner.
810812
* @return the result
811813
*/
812814
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
813815
public static MarkerTool.ScanResult execMarkerTool(
814-
final FileSystem sourceFS,
815-
final Path path,
816-
final boolean doPurge,
817-
final int minMarkerCount,
818-
final int maxMarkerCount,
819-
final int limit,
820-
boolean nonAuth) throws IOException {
821-
MarkerTool tool = new MarkerTool(sourceFS.getConf());
816+
ScanArgs scanArgs) throws IOException {
817+
MarkerTool tool = new MarkerTool(scanArgs.getSourceFS().getConf());
822818
tool.setVerbose(LOG.isDebugEnabled());
823819

824-
return tool.execute(sourceFS, path, doPurge,
825-
minMarkerCount, maxMarkerCount, limit, nonAuth);
820+
return tool.execute(scanArgs);
821+
}
822+
823+
/**
824+
* Arguments for the scan.
825+
* <p></p>
826+
* Uses a builder/argument object because too many arguments were
827+
* being created and it was making maintenance harder.
828+
*/
829+
public static final class ScanArgs {
830+
831+
/** Source FS; must be or wrap an S3A FS. */
832+
private final FileSystem sourceFS;
833+
834+
/** Path to scan. */
835+
private final Path path;
836+
837+
/** Purge? */
838+
private final boolean doPurge;
839+
840+
/** Min marker count (ignored on purge). */
841+
private final int minMarkerCount;
842+
843+
/** Max marker count (ignored on purge). */
844+
private final int maxMarkerCount;
845+
846+
/** Limit of files to scan; 0 for 'unlimited'. */
847+
private final int limit;
848+
849+
/** Consider only markers in nonauth paths as errors. */
850+
private final boolean nonAuth;
851+
852+
/**
853+
* @param sourceFS source FS; must be or wrap an S3A FS.
854+
* @param path path to scan.
855+
* @param doPurge purge?
856+
* @param minMarkerCount min marker count (ignored on purge)
857+
* @param maxMarkerCount max marker count (ignored on purge)
858+
* @param limit limit of files to scan; 0 for 'unlimited'
859+
* @param nonAuth consider only markers in nonauth paths as errors
860+
*/
861+
private ScanArgs(final FileSystem sourceFS,
862+
final Path path,
863+
final boolean doPurge,
864+
final int minMarkerCount,
865+
final int maxMarkerCount,
866+
final int limit,
867+
final boolean nonAuth) {
868+
this.sourceFS = sourceFS;
869+
this.path = path;
870+
this.doPurge = doPurge;
871+
this.minMarkerCount = minMarkerCount;
872+
this.maxMarkerCount = maxMarkerCount;
873+
this.limit = limit;
874+
this.nonAuth = nonAuth;
875+
}
876+
877+
FileSystem getSourceFS() {
878+
return sourceFS;
879+
}
880+
881+
Path getPath() {
882+
return path;
883+
}
884+
885+
boolean isDoPurge() {
886+
return doPurge;
887+
}
888+
889+
int getMinMarkerCount() {
890+
return minMarkerCount;
891+
}
892+
893+
int getMaxMarkerCount() {
894+
return maxMarkerCount;
895+
}
896+
897+
int getLimit() {
898+
return limit;
899+
}
900+
901+
boolean isNonAuth() {
902+
return nonAuth;
903+
}
904+
}
905+
906+
/**
907+
* Builder of the scan arguments.
908+
*/
909+
public static final class ScanArgsBuilder {
910+
911+
/** Source FS; must be or wrap an S3A FS. */
912+
private FileSystem sourceFS;
913+
914+
/** Path to scan. */
915+
private Path path;
916+
917+
/** Purge? */
918+
private boolean doPurge = false;
919+
920+
/** Min marker count (ignored on purge). */
921+
private int minMarkerCount = 0;
922+
923+
/** Max marker count (ignored on purge). */
924+
private int maxMarkerCount = 0;
925+
926+
/** Limit of files to scan; 0 for 'unlimited'. */
927+
private int limit = UNLIMITED_LISTING;
928+
929+
/** Consider only markers in nonauth paths as errors. */
930+
private boolean nonAuth = false;
931+
932+
/** Source FS; must be or wrap an S3A FS. */
933+
public ScanArgsBuilder withSourceFS(final FileSystem sourceFS) {
934+
this.sourceFS = sourceFS;
935+
return this;
936+
}
937+
938+
/** Path to scan. */
939+
public ScanArgsBuilder withPath(final Path path) {
940+
this.path = path;
941+
return this;
942+
}
943+
944+
/** Purge? */
945+
public ScanArgsBuilder withDoPurge(final boolean doPurge) {
946+
this.doPurge = doPurge;
947+
return this;
948+
}
949+
950+
/** Min marker count (ignored on purge). */
951+
public ScanArgsBuilder withMinMarkerCount(final int minMarkerCount) {
952+
this.minMarkerCount = minMarkerCount;
953+
return this;
954+
}
955+
956+
/** Max marker count (ignored on purge). */
957+
public ScanArgsBuilder withMaxMarkerCount(final int maxMarkerCount) {
958+
this.maxMarkerCount = maxMarkerCount;
959+
return this;
960+
}
961+
962+
/** Limit of files to scan; 0 for 'unlimited'. */
963+
public ScanArgsBuilder withLimit(final int limit) {
964+
this.limit = limit;
965+
return this;
966+
}
967+
968+
/** Consider only markers in nonauth paths as errors. */
969+
public ScanArgsBuilder withNonAuth(final boolean nonAuth) {
970+
this.nonAuth = nonAuth;
971+
return this;
972+
}
973+
974+
public ScanArgs build() {
975+
return new ScanArgs(sourceFS, path, doPurge, minMarkerCount,
976+
maxMarkerCount,
977+
limit, nonAuth);
978+
}
826979
}
827980
}

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,22 @@ public void maybeAuditTestPath() {
9090
&& !fs.getDirectoryMarkerPolicy()
9191
.keepDirectoryMarkers(methodPath)
9292
&& fs.isDirectory(methodPath)) {
93-
MarkerTool.ScanResult result = MarkerTool.execMarkerTool(fs,
94-
methodPath, true, 0, 0, UNLIMITED_LISTING, false);
93+
MarkerTool.ScanResult result = MarkerTool.execMarkerTool(
94+
new MarkerTool.ScanArgsBuilder()
95+
.withSourceFS(fs)
96+
.withPath(methodPath)
97+
.withDoPurge(true)
98+
.withMinMarkerCount(0)
99+
.withMaxMarkerCount(0)
100+
.withLimit(UNLIMITED_LISTING)
101+
.withNonAuth(false)
102+
.build());
95103
final String resultStr = result.toString();
96-
assertEquals("Audit of " + methodPath + " failed: " + resultStr,
104+
assertEquals("Audit of " + methodPath + " failed: "
105+
+ resultStr,
97106
0, result.getExitCode());
98-
assertEquals("Marker Count under " + methodPath + " non-zero: " + resultStr,
107+
assertEquals("Marker Count under " + methodPath
108+
+ " non-zero: " + resultStr,
99109
0, result.getFilteredMarkerCount());
100110
}
101111
} catch (FileNotFoundException ignored) {

0 commit comments

Comments
 (0)