summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorValerij Fredriksen <valerijf@oath.com>2018-10-10 11:57:37 +0200
committerValerij Fredriksen <valerijf@oath.com>2018-10-10 11:57:37 +0200
commit84960d571b4603cd420cb7ee57162509d2de73d5 (patch)
treed32dbba40a65170c406f94bd8471c5f7299a0e64
parentbe2e16e9fad51a2a2442087c8df19ddd845d006d (diff)
Move stuff to UnixPath
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileFinder.java52
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPath.java54
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileFinderTest.java7
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPathTest.java16
4 files changed, 71 insertions, 58 deletions
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileFinder.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileFinder.java
index 57c643819dc..c92027a659b 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileFinder.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileFinder.java
@@ -20,8 +20,6 @@ import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Stream;
-import static com.yahoo.vespa.hosted.node.admin.task.util.file.IOExceptionUtil.uncheck;
-
/**
* Helper class to find and list or deleteRecursively files and directories. Follows the general syntax of command line
* tool `find`.
@@ -76,11 +74,15 @@ public class FileFinder {
return this;
}
- /** Recursively deletes all matching elements */
- public int deleteRecursively() {
- int[] numDeletions = { 0 }; // :(
- forEach(attributes -> numDeletions[0] += deleteRecursively(attributes));
- return numDeletions[0];
+ /**
+ * Recursively deletes all matching elements
+ *
+ * @return true iff anything was matched and deleted
+ */
+ public boolean deleteRecursively() {
+ boolean[] deletedAnything = { false }; // :(
+ forEach(attributes -> deletedAnything[0] |= attributes.unixPath().deleteRecursively());
+ return deletedAnything[0];
}
public List<FileAttributes> list() {
@@ -160,17 +162,6 @@ public class FileFinder {
}
}
- private static int deleteRecursively(FileAttributes fileAttributes) {
- int numDeletions = 0;
- if (fileAttributes.isDirectory()) {
- numDeletions = FileFinder.from(fileAttributes.path())
- .match(all())
- .deleteRecursively();
- }
-
- return numDeletions + (deleteIfExists(fileAttributes.path()) ? 1 : 0);
- }
-
// Ideally, we would reuse the FileAttributes in this package, but unfortunately we only get
// BasicFileAttributes and not PosixFileAttributes from FileVisitor
@@ -184,6 +175,7 @@ public class FileFinder {
}
public Path path() { return path; }
+ public UnixPath unixPath() { return new UnixPath(path); }
public String filename() { return path.getFileName().toString(); }
public Instant lastModifiedTime() { return attributes.lastModifiedTime().toInstant(); }
public boolean isRegularFile() { return attributes.isRegularFile(); }
@@ -224,28 +216,4 @@ public class FileFinder {
public static Predicate<FileAttributes> all() {
return attrs -> true;
}
-
-
- // Other helpful methods that no not throw checked exceptions
- public static boolean moveIfExists(Path from, Path to) {
- try {
- Files.move(from, to);
- return true;
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
- }
-
- public static boolean deleteIfExists(Path path) {
- return uncheck(() -> Files.deleteIfExists(path));
- }
-
- public static Path createDirectories(Path path) {
- return uncheck(() -> Files.createDirectories(path));
- }
-
- public static int deleteRecursively(Path path) {
- return deleteRecursively(
- new FileAttributes(path, uncheck(() -> Files.readAttributes(path, BasicFileAttributes.class))));
- }
}
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPath.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPath.java
index 4baba9acb4e..ae5c6f57d4c 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPath.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPath.java
@@ -1,8 +1,11 @@
// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.node.admin.task.util.file;
+import java.io.IOException;
+import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -15,8 +18,12 @@ import java.nio.file.attribute.PosixFilePermissions;
import java.nio.file.attribute.UserPrincipal;
import java.nio.file.attribute.UserPrincipalLookupService;
import java.time.Instant;
+import java.util.Collections;
+import java.util.List;
import java.util.Optional;
import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import static com.yahoo.vespa.hosted.node.admin.task.util.file.IOExceptionUtil.uncheck;
@@ -128,6 +135,53 @@ public class UnixPath {
uncheck(() -> Files.createDirectory(path));
}
+ public boolean isDirectory() {
+ return uncheck(() -> Files.isDirectory(path));
+ }
+
+ /**
+ * Similar to rm -rf file:
+ * - It's not an error if file doesn't exist
+ * - If file is a directory, it and all content is removed
+ * - For symlinks: Only the symlink is removed, not what the symlink points to
+ */
+ public boolean deleteRecursively() {
+ if (isDirectory()) {
+ for (UnixPath path : listContentsOfDirectory()) {
+ path.deleteRecursively();
+ }
+ }
+
+ return deleteIfExists();
+ }
+
+ public boolean deleteIfExists() {
+ return uncheck(() -> Files.deleteIfExists(path));
+ }
+
+ public List<UnixPath> listContentsOfDirectory() {
+ try (Stream<Path> stream = Files.list(path)){
+ return stream
+ .map(UnixPath::new)
+ .collect(Collectors.toList());
+ } catch (NoSuchFileException ignored) {
+ return Collections.emptyList();
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to list contents of directory " + path.toAbsolutePath(), e);
+ }
+ }
+
+ public boolean moveIfExists(Path to) {
+ try {
+ Files.move(path, to);
+ return true;
+ } catch (NoSuchFileException ignored) {
+ return false;
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
@Override
public String toString() {
return path.toString();
diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileFinderTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileFinderTest.java
index a9d47f743e5..ee13de20ee4 100644
--- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileFinderTest.java
+++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileFinderTest.java
@@ -108,13 +108,6 @@ public class FileFinderTest {
assertTrue(Files.exists(testRoot()));
}
- @Test
- public void everything() {
- FileFinder.deleteRecursively(testRoot());
-
- assertFalse(Files.exists(testRoot()));
- }
-
@Before
public void setup() throws IOException {
Path root = testRoot();
diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPathTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPathTest.java
index 8d3d336a4ac..9b80b9a9ca2 100644
--- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPathTest.java
+++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPathTest.java
@@ -17,15 +17,15 @@ import static org.junit.Assert.assertTrue;
* @author hakonhall
*/
public class UnixPathTest {
- final FileSystem fileSystem = TestFileSystem.create();
+ private final FileSystem fs = TestFileSystem.create();
@Test
public void createParents() {
- Path parentDirectory = fileSystem.getPath("/a/b/c");
+ Path parentDirectory = fs.getPath("/a/b/c");
Path filePath = parentDirectory.resolve("bar");
UnixPath path = new UnixPath(filePath);
- assertFalse(Files.exists(fileSystem.getPath("/a")));
+ assertFalse(Files.exists(fs.getPath("/a")));
path.createParents();
assertTrue(Files.exists(parentDirectory));
}
@@ -33,7 +33,7 @@ public class UnixPathTest {
@Test
public void utf8File() {
String original = "foo\nbar\n";
- UnixPath path = new UnixPath(fileSystem.getPath("example.txt"));
+ UnixPath path = new UnixPath(fs.getPath("example.txt"));
path.writeUtf8File(original);
String fromFile = path.readUtf8File();
assertEquals(original, fromFile);
@@ -42,7 +42,7 @@ public class UnixPathTest {
@Test
public void permissions() {
String expectedPermissions = "rwxr-x---";
- UnixPath path = new UnixPath(fileSystem.getPath("file.txt"));
+ UnixPath path = new UnixPath(fs.getPath("file.txt"));
path.writeUtf8File("foo");
path.setPermissions(expectedPermissions);
assertEquals(expectedPermissions, path.getPermissions());
@@ -50,12 +50,11 @@ public class UnixPathTest {
@Test(expected = IllegalArgumentException.class)
public void badPermissionsString() {
- new UnixPath(fileSystem.getPath("file.txt")).setPermissions("abcdefghi");
+ new UnixPath(fs.getPath("file.txt")).setPermissions("abcdefghi");
}
@Test
public void owner() {
- FileSystem fs = TestFileSystem.create();
Path path = fs.getPath("file.txt");
UnixPath unixPath = new UnixPath(path);
unixPath.writeUtf8File("foo");
@@ -69,12 +68,11 @@ public class UnixPathTest {
@Test
public void createDirectoryWithPermissions() {
- FileSystem fs = TestFileSystem.create();
Path path = fs.getPath("dir");
UnixPath unixPath = new UnixPath(path);
String permissions = "rwxr-xr--";
unixPath.createDirectory(permissions);
- assertTrue(Files.isDirectory(path));
+ assertTrue(unixPath.isDirectory());
assertEquals(permissions, unixPath.getPermissions());
}
}