From 30d9c961312afbdf1962e3116ee84baf27572a3d Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Mon, 16 Sep 2013 21:26:14 +0200 Subject: [PATCH] SONAR-4523 delete /extensions/downloads/*.tmp files at startup --- .../server/plugins/PluginDownloader.java | 28 +++++++++-- .../server/plugins/PluginDownloaderTest.java | 47 +++++++++++++------ 2 files changed, 56 insertions(+), 19 deletions(-) diff --git a/sonar-server/src/main/java/org/sonar/server/plugins/PluginDownloader.java b/sonar-server/src/main/java/org/sonar/server/plugins/PluginDownloader.java index 89e1992e880..d59164e0e19 100644 --- a/sonar-server/src/main/java/org/sonar/server/plugins/PluginDownloader.java +++ b/sonar-server/src/main/java/org/sonar/server/plugins/PluginDownloader.java @@ -21,6 +21,7 @@ package org.sonar.server.plugins; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; +import org.picocontainer.Startable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.ServerComponent; @@ -35,11 +36,13 @@ import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; +import java.util.Collection; import java.util.List; -public class PluginDownloader implements ServerComponent { +public class PluginDownloader implements ServerComponent, Startable { private static final Logger LOG = LoggerFactory.getLogger(PluginDownloader.class); + private static final String TMP_SUFFIX = "tmp"; private final UpdateCenterMatrixFactory updateCenterMatrixFactory; private final HttpDownloader downloader; @@ -49,22 +52,37 @@ public class PluginDownloader implements ServerComponent { this.updateCenterMatrixFactory = updateCenterMatrixFactory; this.downloader = downloader; this.downloadDir = fileSystem.getDownloadedPluginsDir(); + } + + /** + * Delete the temporary files remaining from previous downloads + * @see #downloadRelease(org.sonar.updatecenter.common.Release) + */ + @Override + public void start() { try { FileUtils.forceMkdir(downloadDir); + Collection tempFiles = FileUtils.listFiles(downloadDir, new String[]{TMP_SUFFIX}, false); + for (File tempFile : tempFiles) { + FileUtils.deleteQuietly(tempFile); + } } catch (IOException e) { - throw new SonarException("Fail to create the plugin downloads directory: " + downloadDir, e); + throw new IllegalStateException("Fail to create the directory: " + downloadDir, e); } } + @Override + public void stop() { + } + public void cancelDownloads() { try { if (downloadDir.exists()) { FileUtils.cleanDirectory(downloadDir); } - } catch (IOException e) { - throw new SonarException("Fail to clean the plugin downloads directory: " + downloadDir, e); + throw new IllegalStateException("Fail to clean the plugin downloads directory: " + downloadDir, e); } } @@ -104,7 +122,7 @@ public class PluginDownloader implements ServerComponent { } else { String filename = StringUtils.substringAfterLast(uri.getPath(), "/"); File targetFile = new File(downloadDir, filename); - File tempFile = new File(downloadDir, filename + ".tmp"); + File tempFile = new File(downloadDir, filename + "." + TMP_SUFFIX); downloader.download(uri, tempFile); FileUtils.moveFile(tempFile, targetFile); } diff --git a/sonar-server/src/test/java/org/sonar/server/plugins/PluginDownloaderTest.java b/sonar-server/src/test/java/org/sonar/server/plugins/PluginDownloaderTest.java index fd6e2df8d77..174ab7a5ab6 100644 --- a/sonar-server/src/test/java/org/sonar/server/plugins/PluginDownloaderTest.java +++ b/sonar-server/src/test/java/org/sonar/server/plugins/PluginDownloaderTest.java @@ -21,10 +21,7 @@ package org.sonar.server.plugins; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; +import org.junit.*; import org.junit.rules.TemporaryFolder; import org.mockito.ArgumentMatcher; import org.mockito.invocation.InvocationOnMock; @@ -38,6 +35,7 @@ import org.sonar.updatecenter.common.UpdateCenter; import org.sonar.updatecenter.common.Version; import java.io.File; +import java.io.FilenameFilter; import java.net.URI; import static com.google.common.collect.Lists.newArrayList; @@ -52,13 +50,11 @@ public class PluginDownloaderTest { @Rule public TemporaryFolder testFolder = new TemporaryFolder(); - private File downloadDir; - - private UpdateCenterMatrixFactory updateCenterMatrixFactory; - private UpdateCenter updateCenter; - private HttpDownloader httpDownloader; - - private PluginDownloader pluginDownloader; + File downloadDir; + UpdateCenterMatrixFactory updateCenterMatrixFactory; + UpdateCenter updateCenter; + HttpDownloader httpDownloader; + PluginDownloader pluginDownloader; @Before public void before() throws Exception { @@ -83,6 +79,23 @@ public class PluginDownloaderTest { pluginDownloader = new PluginDownloader(updateCenterMatrixFactory, httpDownloader, defaultServerFileSystem); } + @After + public void stop() { + pluginDownloader.stop(); + } + + @Test + public void should_clean_temporary_files_at_startup() throws Exception { + FileUtils.touch(new File(downloadDir, "sonar-php.jar")); + FileUtils.touch(new File(downloadDir, "sonar-js.jar.tmp")); + assertThat(downloadDir.listFiles()).hasSize(2); + pluginDownloader.start(); + + File[] files = downloadDir.listFiles(); + assertThat(files).hasSize(1); + assertThat(files[0].getName()).isEqualTo("sonar-php.jar"); + } + @Test public void should_download_from_url() throws Exception { Plugin test = new Plugin("test"); @@ -91,6 +104,7 @@ public class PluginDownloaderTest { when(updateCenter.findInstallablePlugins("foo", Version.create("1.0"))).thenReturn(newArrayList(test10)); + pluginDownloader.start(); pluginDownloader.download("foo", Version.create("1.0")); // SONAR-4523: do not corrupt JAR files when restarting the server while a plugin is being downloaded. @@ -107,10 +121,11 @@ public class PluginDownloaderTest { File downloadDir = testFolder.newFile(); when(defaultServerFileSystem.getDownloadedPluginsDir()).thenReturn(downloadDir); + pluginDownloader = new PluginDownloader(updateCenterMatrixFactory, httpDownloader, defaultServerFileSystem); try { - new PluginDownloader(updateCenterMatrixFactory, httpDownloader, defaultServerFileSystem); + pluginDownloader.start(); fail(); - } catch (SonarException e) { + } catch (IllegalStateException e) { // ok } } @@ -125,6 +140,7 @@ public class PluginDownloaderTest { when(updateCenter.findInstallablePlugins("foo", Version.create("1.0"))).thenReturn(newArrayList(test10)); + pluginDownloader.start(); pluginDownloader.download("foo", Version.create("1.0")); verify(httpDownloader, never()).download(any(URI.class), any(File.class)); assertThat(pluginDownloader.hasDownloads()).isTrue(); @@ -138,6 +154,7 @@ public class PluginDownloaderTest { when(updateCenter.findInstallablePlugins("foo", Version.create("1.0"))).thenReturn(newArrayList(test10)); + pluginDownloader.start(); try { pluginDownloader.download("foo", Version.create("1.0")); fail(); @@ -155,6 +172,7 @@ public class PluginDownloaderTest { doThrow(new RuntimeException()).when(httpDownloader).download(any(URI.class), any(File.class)); + pluginDownloader.start(); try { pluginDownloader.download("foo", Version.create("1.0")); fail(); @@ -165,6 +183,7 @@ public class PluginDownloaderTest { @Test public void should_read_download_folder() throws Exception { + pluginDownloader.start(); assertThat(pluginDownloader.getDownloads()).hasSize(0); File file1 = new File(downloadDir, "file1.jar"); @@ -182,13 +201,13 @@ public class PluginDownloaderTest { File file2 = new File(downloadDir, "file2.jar"); file2.createNewFile(); + pluginDownloader.start(); assertThat(pluginDownloader.hasDownloads()).isTrue(); pluginDownloader.cancelDownloads(); assertThat(pluginDownloader.hasDownloads()).isFalse(); } class HasFileName extends ArgumentMatcher { - private final String name; HasFileName(String name) { -- 2.39.5