From d4acdfa1b64d285587aa6678579d96333ce4a146 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Mon, 9 May 2016 16:09:02 +0200 Subject: [PATCH] SONAR-7422 do not delete sharememory file in tempDir --- .../org/sonar/application/AppFileSystem.java | 52 +++++++++++++++++-- .../sonar/application/AppFileSystemTest.java | 25 +++++++++ 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/sonar-application/src/main/java/org/sonar/application/AppFileSystem.java b/sonar-application/src/main/java/org/sonar/application/AppFileSystem.java index c195008a638..13201793b89 100644 --- a/sonar-application/src/main/java/org/sonar/application/AppFileSystem.java +++ b/sonar-application/src/main/java/org/sonar/application/AppFileSystem.java @@ -21,13 +21,22 @@ package org.sonar.application; import java.io.File; import java.io.IOException; +import java.nio.file.FileVisitOption; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.EnumSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.process.Props; import org.sonar.process.monitor.FileSystem; +import static java.nio.file.FileVisitResult.CONTINUE; import static org.apache.commons.io.FileUtils.forceMkdir; -import static org.sonar.process.FileUtils.cleanDirectory; +import static org.sonar.process.FileUtils.deleteDirectory; import static org.sonar.process.ProcessProperties.PATH_DATA; import static org.sonar.process.ProcessProperties.PATH_HOME; import static org.sonar.process.ProcessProperties.PATH_LOGS; @@ -70,7 +79,7 @@ public class AppFileSystem implements FileSystem { createDirectory(props, PATH_DATA); createDirectory(props, PATH_WEB); createDirectory(props, PATH_LOGS); - createOrCleanDirectory(props, PATH_TEMP); + createOrCleanTempDirectory(props, PATH_TEMP); } @Override @@ -109,11 +118,46 @@ public class AppFileSystem implements FileSystem { } } - private static void createOrCleanDirectory(Props props, String propKey) throws IOException { + private static final EnumSet FOLLOW_LINKS = EnumSet.of(FileVisitOption.FOLLOW_LINKS); + + private static void createOrCleanTempDirectory(Props props, String propKey) throws IOException { File dir = props.nonNullValueAsFile(propKey); LOG.info("Cleaning or creating temp directory {}", dir.getAbsolutePath()); if (!createDirectory(props, propKey)) { - cleanDirectory(dir); + Files.walkFileTree(dir.toPath(), FOLLOW_LINKS, CleanTempDirFileVisitor.VISIT_MAX_DEPTH, new CleanTempDirFileVisitor(dir.toPath())); + } + } + + private static class CleanTempDirFileVisitor extends SimpleFileVisitor { + private static final Path SHAREDMEMORY_FILE = Paths.get("sharedmemory"); + public static final int VISIT_MAX_DEPTH = 1; + + private final Path path; + private final boolean symLink; + + public CleanTempDirFileVisitor(Path path) { + this.path = path; + this.symLink = Files.isSymbolicLink(path); + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if (Files.isDirectory(file)) { + deleteDirectory(file.toFile()); + } else if (file.getFileName().equals(SHAREDMEMORY_FILE)) { + return CONTINUE; + } else if (!symLink || !file.equals(path)) { + Files.delete(file); + } + return CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + if (!dir.equals(path)) { + deleteDirectory(dir.toFile()); + } + return CONTINUE; } } diff --git a/sonar-application/src/test/java/org/sonar/application/AppFileSystemTest.java b/sonar-application/src/test/java/org/sonar/application/AppFileSystemTest.java index 62c9725d68d..aaed934963c 100644 --- a/sonar-application/src/test/java/org/sonar/application/AppFileSystemTest.java +++ b/sonar-application/src/test/java/org/sonar/application/AppFileSystemTest.java @@ -27,6 +27,7 @@ import java.nio.file.Paths; import java.nio.file.attribute.BasicFileAttributes; import java.util.Properties; import javax.annotation.CheckForNull; +import org.apache.commons.io.FileUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -156,6 +157,30 @@ public class AppFileSystemTest { assertThat(getFileKey(tempDir)).isEqualTo(tempDirKey); } + @Test + public void reset_deletes_content_of_temp_dir_but_not_sharedmemory_file() throws Exception { + File tempDir = new File(homeDir, DEFAULT_TEMP_DIR_NAME); + assertThat(tempDir.mkdir()).isTrue(); + File sharedmemory = new File(tempDir, "sharedmemory"); + assertThat(sharedmemory.createNewFile()).isTrue(); + FileUtils.write(sharedmemory, "toto"); + Object fileKey = getFileKey(sharedmemory); + + Object tempDirKey = getFileKey(tempDir); + File fileInTempDir = new File(tempDir, "someFile.txt"); + assertThat(fileInTempDir.createNewFile()).isTrue(); + + AppFileSystem underTest = new AppFileSystem(new Props(properties)); + underTest.verifyProps(); + underTest.reset(); + + assertThat(tempDir).exists(); + assertThat(fileInTempDir).doesNotExist(); + assertThat(getFileKey(tempDir)).isEqualTo(tempDirKey); + assertThat(getFileKey(sharedmemory)).isEqualTo(fileKey); + assertThat(FileUtils.readFileToString(sharedmemory)).isEqualTo("toto"); + } + @CheckForNull private static Object getFileKey(File fileInTempDir) throws IOException { Path path = Paths.get(fileInTempDir.toURI()); -- 2.39.5