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;
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;
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<File> 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);
}
}
} 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);
}
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;
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;
@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 {
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");
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.
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
}
}
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();
when(updateCenter.findInstallablePlugins("foo", Version.create("1.0"))).thenReturn(newArrayList(test10));
+ pluginDownloader.start();
try {
pluginDownloader.download("foo", Version.create("1.0"));
fail();
doThrow(new RuntimeException()).when(httpDownloader).download(any(URI.class), any(File.class));
+ pluginDownloader.start();
try {
pluginDownloader.download("foo", Version.create("1.0"));
fail();
@Test
public void should_read_download_folder() throws Exception {
+ pluginDownloader.start();
assertThat(pluginDownloader.getDownloads()).hasSize(0);
File file1 = new File(downloadDir, "file1.jar");
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<File> {
-
private final String name;
HasFileName(String name) {