]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6383 add method to list downloaded plugins as PluginMetadata
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Fri, 17 Apr 2015 20:04:30 +0000 (22:04 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Tue, 21 Apr 2015 07:26:34 +0000 (09:26 +0200)
server/sonar-server/src/main/java/org/sonar/server/plugins/PluginDownloader.java
server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingPluginsWsAction.java
server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
server/sonar-server/src/test/java/org/sonar/server/plugins/PluginDownloaderTest.java
server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingPluginsWsActionTest.java
server/sonar-server/src/test/resources/org/sonar/server/plugins/PluginDownloaderTest/foo-plugin-1.0.jar [new file with mode: 0644]

index 295a58a916a6a336683c9aac1e802119e8d1b2aa..860ad0f53af97a3d73f65b7e1557dea8b20e06d4 100644 (file)
 package org.sonar.server.plugins;
 
 import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
 import org.picocontainer.Startable;
+import org.sonar.api.utils.HttpDownloader;
 import org.sonar.api.utils.SonarException;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
-import org.sonar.api.utils.HttpDownloader;
+import org.sonar.core.plugins.DefaultPluginMetadata;
 import org.sonar.server.platform.DefaultServerFileSystem;
 import org.sonar.updatecenter.common.Release;
 import org.sonar.updatecenter.common.Version;
@@ -38,6 +38,16 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
+import static com.google.common.collect.Iterables.transform;
+import static com.google.common.collect.Lists.newArrayList;
+import static org.apache.commons.io.FileUtils.cleanDirectory;
+import static org.apache.commons.io.FileUtils.copyFile;
+import static org.apache.commons.io.FileUtils.copyFileToDirectory;
+import static org.apache.commons.io.FileUtils.deleteQuietly;
+import static org.apache.commons.io.FileUtils.forceMkdir;
+import static org.apache.commons.io.FileUtils.toFile;
+import static org.apache.commons.lang.StringUtils.substringAfterLast;
+
 public class PluginDownloader implements Startable {
 
   private static final Logger LOG = Loggers.get(PluginDownloader.class);
@@ -46,12 +56,14 @@ public class PluginDownloader implements Startable {
 
   private final UpdateCenterMatrixFactory updateCenterMatrixFactory;
   private final HttpDownloader downloader;
+  private final ServerPluginJarInstaller installer;
   private final File downloadDir;
 
   public PluginDownloader(UpdateCenterMatrixFactory updateCenterMatrixFactory, HttpDownloader downloader,
-    DefaultServerFileSystem fileSystem) {
+                          DefaultServerFileSystem fileSystem, ServerPluginJarInstaller installer) {
     this.updateCenterMatrixFactory = updateCenterMatrixFactory;
     this.downloader = downloader;
+    this.installer = installer;
     this.downloadDir = fileSystem.getDownloadedPluginsDir();
   }
 
@@ -63,12 +75,10 @@ public class PluginDownloader implements Startable {
   @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);
+      forceMkdir(downloadDir);
+      for (File tempFile : listTempFile(this.downloadDir)) {
+        deleteQuietly(tempFile);
       }
-
     } catch (IOException e) {
       throw new IllegalStateException("Fail to create the directory: " + downloadDir, e);
     }
@@ -82,7 +92,7 @@ public class PluginDownloader implements Startable {
   public void cancelDownloads() {
     try {
       if (downloadDir.exists()) {
-        FileUtils.cleanDirectory(downloadDir);
+        cleanDirectory(downloadDir);
       }
     } catch (IOException e) {
       throw new IllegalStateException("Fail to clean the plugin downloads directory: " + downloadDir, e);
@@ -90,18 +100,24 @@ public class PluginDownloader implements Startable {
   }
 
   public boolean hasDownloads() {
-    return !getDownloads().isEmpty();
+    return !getDownloadedPluginFilenames().isEmpty();
   }
 
-  public List<String> getDownloads() {
-    List<String> names = new ArrayList<String>();
-    List<File> files = (List<File>) FileUtils.listFiles(downloadDir, new String[] {PLUGIN_EXTENSION}, false);
-    for (File file : files) {
+  public List<String> getDownloadedPluginFilenames() {
+    List<String> names = new ArrayList<>();
+    for (File file : listPlugins(this.downloadDir)) {
       names.add(file.getName());
     }
     return names;
   }
 
+  /**
+   * @return the list of download plugins as {@link DefaultPluginMetadata} instances
+   */
+  public Collection<DefaultPluginMetadata> getDownloadedPlugins() {
+    return newArrayList(transform(listPlugins(this.downloadDir), installer.fileToPlugin(false)));
+  }
+
   public void download(String pluginKey, Version version) {
     for (Release release : updateCenterMatrixFactory.getUpdateCenter(true).findInstallablePlugins(pluginKey, version)) {
       try {
@@ -122,18 +138,26 @@ public class PluginDownloader implements Startable {
     URI uri = new URI(url);
     if (url.startsWith("file:")) {
       // used for tests
-      File file = FileUtils.toFile(uri.toURL());
-      FileUtils.copyFileToDirectory(file, downloadDir);
+      File file = toFile(uri.toURL());
+      copyFileToDirectory(file, downloadDir);
     } else {
-      String filename = StringUtils.substringAfterLast(uri.getPath(), "/");
+      String filename = substringAfterLast(uri.getPath(), "/");
       if (!filename.endsWith("." + PLUGIN_EXTENSION)) {
         filename = release.getKey() + "-" + release.getVersion() + "." + PLUGIN_EXTENSION;
       }
       File targetFile = new File(downloadDir, filename);
       File tempFile = new File(downloadDir, filename + "." + TMP_SUFFIX);
       downloader.download(uri, tempFile);
-      FileUtils.copyFile(tempFile, targetFile);
-      FileUtils.deleteQuietly(tempFile);
+      copyFile(tempFile, targetFile);
+      deleteQuietly(tempFile);
     }
   }
+
+  private static Collection<File> listTempFile(File dir) {
+    return FileUtils.listFiles(dir, new String[]{TMP_SUFFIX}, false);
+  }
+
+  private static Collection<File> listPlugins(File dir) {
+    return FileUtils.listFiles(dir, new String[]{PLUGIN_EXTENSION}, false);
+  }
 }
index eaf8d6eb2d44522df8eca0d8b14ddcf8e6189fa7..9c9d6be3f4a313b1bb00cc1f9b7530e86b54ba7f 100644 (file)
@@ -74,7 +74,7 @@ public class PendingPluginsWsAction implements PluginsWsAction {
   private void writeInstalling(JsonWriter jsonWriter) {
     jsonWriter.name(ARRAY_INSTALLING);
     jsonWriter.beginArray();
-    for (String fileName : copyOf(CASE_INSENSITIVE_ORDER, pluginDownloader.getDownloads())) {
+    for (String fileName : copyOf(CASE_INSENSITIVE_ORDER, pluginDownloader.getDownloadedPluginFilenames())) {
       writeArchive(jsonWriter, fileName);
     }
     jsonWriter.endArray();
index f8ea22a46c7de1bf28b21b304be9dc5ec9d334b7..eceb52ec6d39ccc2df453339c3320481126205e5 100644 (file)
@@ -141,7 +141,7 @@ public final class JRubyFacade {
   }
 
   public List<String> getPluginDownloads() {
-    return get(PluginDownloader.class).getDownloads();
+    return get(PluginDownloader.class).getDownloadedPluginFilenames();
   }
 
   public void uninstallPlugin(String pluginKey) {
index f98c49dd844d30f7fcd41999f09f29ca160c91ee..b5e92448752dcf4378e4c81406a780f32e7c4613 100644 (file)
@@ -19,8 +19,6 @@
  */
 package org.sonar.server.plugins;
 
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.FilenameUtils;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -31,16 +29,21 @@ import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 import org.sonar.api.utils.HttpDownloader;
 import org.sonar.api.utils.SonarException;
+import org.sonar.core.plugins.DefaultPluginMetadata;
 import org.sonar.server.platform.DefaultServerFileSystem;
 import org.sonar.updatecenter.common.Plugin;
 import org.sonar.updatecenter.common.Release;
 import org.sonar.updatecenter.common.UpdateCenter;
-import org.sonar.updatecenter.common.Version;
 
 import java.io.File;
 import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
 
 import static com.google.common.collect.Lists.newArrayList;
+import static org.apache.commons.io.FileUtils.copyFileToDirectory;
+import static org.apache.commons.io.FileUtils.touch;
+import static org.apache.commons.io.FilenameUtils.separatorsToUnix;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.fail;
 import static org.mockito.Matchers.any;
@@ -52,6 +55,7 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+import static org.sonar.updatecenter.common.Version.create;
 
 public class PluginDownloaderTest {
 
@@ -62,6 +66,7 @@ public class PluginDownloaderTest {
   UpdateCenter updateCenter;
   HttpDownloader httpDownloader;
   PluginDownloader pluginDownloader;
+  ServerPluginJarInstaller installer;
 
   @Before
   public void before() throws Exception {
@@ -74,7 +79,7 @@ public class PluginDownloaderTest {
       @Override
       public Object answer(InvocationOnMock inv) throws Throwable {
         File toFile = (File) inv.getArguments()[1];
-        FileUtils.touch(toFile);
+        touch(toFile);
         return null;
       }
     }).when(httpDownloader).download(any(URI.class), any(File.class));
@@ -83,7 +88,8 @@ public class PluginDownloaderTest {
     downloadDir = testFolder.newFolder("downloads");
     when(defaultServerFileSystem.getDownloadedPluginsDir()).thenReturn(downloadDir);
 
-    pluginDownloader = new PluginDownloader(updateCenterMatrixFactory, httpDownloader, defaultServerFileSystem);
+    installer = new ServerPluginJarInstaller();
+    pluginDownloader = new PluginDownloader(updateCenterMatrixFactory, httpDownloader, defaultServerFileSystem, installer);
   }
 
   @After
@@ -93,8 +99,8 @@ public class PluginDownloaderTest {
 
   @Test
   public void clean_temporary_files_at_startup() throws Exception {
-    FileUtils.touch(new File(downloadDir, "sonar-php.jar"));
-    FileUtils.touch(new File(downloadDir, "sonar-js.jar.tmp"));
+    touch(new File(downloadDir, "sonar-php.jar"));
+    touch(new File(downloadDir, "sonar-js.jar.tmp"));
     assertThat(downloadDir.listFiles()).hasSize(2);
     pluginDownloader.start();
 
@@ -109,10 +115,10 @@ public class PluginDownloaderTest {
     Release test10 = new Release(test, "1.0").setDownloadUrl("http://server/test-1.0.jar");
     test.addRelease(test10);
 
-    when(updateCenter.findInstallablePlugins("foo", Version.create("1.0"))).thenReturn(newArrayList(test10));
+    when(updateCenter.findInstallablePlugins("foo", create("1.0"))).thenReturn(newArrayList(test10));
 
     pluginDownloader.start();
-    pluginDownloader.download("foo", Version.create("1.0"));
+    pluginDownloader.download("foo", create("1.0"));
 
     // SONAR-4523: do not corrupt JAR files when restarting the server while a plugin is being downloaded.
     // The JAR file is downloaded in a temp file
@@ -130,10 +136,10 @@ public class PluginDownloaderTest {
     Release test10 = new Release(test, "1.0").setDownloadUrl("http://server/redirect?r=release&g=test&a=test&v=1.0&e=jar");
     test.addRelease(test10);
 
-    when(updateCenter.findInstallablePlugins("foo", Version.create("1.0"))).thenReturn(newArrayList(test10));
+    when(updateCenter.findInstallablePlugins("foo", create("1.0"))).thenReturn(newArrayList(test10));
 
     pluginDownloader.start();
-    pluginDownloader.download("foo", Version.create("1.0"));
+    pluginDownloader.download("foo", create("1.0"));
 
     // SONAR-4523: do not corrupt JAR files when restarting the server while a plugin is being downloaded.
     // The JAR file is downloaded in a temp file
@@ -149,7 +155,7 @@ public class PluginDownloaderTest {
     File downloadDir = testFolder.newFile();
     when(defaultServerFileSystem.getDownloadedPluginsDir()).thenReturn(downloadDir);
 
-    pluginDownloader = new PluginDownloader(updateCenterMatrixFactory, httpDownloader, defaultServerFileSystem);
+    pluginDownloader = new PluginDownloader(updateCenterMatrixFactory, httpDownloader, defaultServerFileSystem, installer);
     try {
       pluginDownloader.start();
       fail();
@@ -163,13 +169,13 @@ public class PluginDownloaderTest {
     Plugin test = new Plugin("test");
     File file = testFolder.newFile("test-1.0.jar");
     file.createNewFile();
-    Release test10 = new Release(test, "1.0").setDownloadUrl("file://" + FilenameUtils.separatorsToUnix(file.getCanonicalPath()));
+    Release test10 = new Release(test, "1.0").setDownloadUrl("file://" + separatorsToUnix(file.getCanonicalPath()));
     test.addRelease(test10);
 
-    when(updateCenter.findInstallablePlugins("foo", Version.create("1.0"))).thenReturn(newArrayList(test10));
+    when(updateCenter.findInstallablePlugins("foo", create("1.0"))).thenReturn(newArrayList(test10));
 
     pluginDownloader.start();
-    pluginDownloader.download("foo", Version.create("1.0"));
+    pluginDownloader.download("foo", create("1.0"));
     verify(httpDownloader, never()).download(any(URI.class), any(File.class));
     assertThat(pluginDownloader.hasDownloads()).isTrue();
   }
@@ -180,11 +186,11 @@ public class PluginDownloaderTest {
     Release test10 = new Release(test, "1.0").setDownloadUrl("file://not_found");
     test.addRelease(test10);
 
-    when(updateCenter.findInstallablePlugins("foo", Version.create("1.0"))).thenReturn(newArrayList(test10));
+    when(updateCenter.findInstallablePlugins("foo", create("1.0"))).thenReturn(newArrayList(test10));
 
     pluginDownloader.start();
     try {
-      pluginDownloader.download("foo", Version.create("1.0"));
+      pluginDownloader.download("foo", create("1.0"));
       fail();
     } catch (SonarException e) {
       // ok
@@ -196,13 +202,13 @@ public class PluginDownloaderTest {
     Plugin test = new Plugin("test");
     Release test10 = new Release(test, "1.0").setDownloadUrl("http://server/test-1.0.jar");
     test.addRelease(test10);
-    when(updateCenter.findInstallablePlugins("foo", Version.create("1.0"))).thenReturn(newArrayList(test10));
+    when(updateCenter.findInstallablePlugins("foo", create("1.0"))).thenReturn(newArrayList(test10));
 
     doThrow(new RuntimeException()).when(httpDownloader).download(any(URI.class), any(File.class));
 
     pluginDownloader.start();
     try {
-      pluginDownloader.download("foo", Version.create("1.0"));
+      pluginDownloader.download("foo", create("1.0"));
       fail();
     } catch (SonarException e) {
       // ok
@@ -212,14 +218,37 @@ public class PluginDownloaderTest {
   @Test
   public void read_download_folder() throws Exception {
     pluginDownloader.start();
-    assertThat(pluginDownloader.getDownloads()).hasSize(0);
+    assertThat(pluginDownloader.getDownloadedPluginFilenames()).hasSize(0);
+
+    copyFileToDirectory(new File(resource("foo-plugin-1.0.jar")), downloadDir);
+
+    assertThat(pluginDownloader.getDownloadedPlugins()).hasSize(1);
+    DefaultPluginMetadata metadata = pluginDownloader.getDownloadedPlugins().iterator().next();
+    assertThat(metadata.getKey()).isEqualTo("foo");
+    assertThat(metadata.getName()).isEqualTo("Foo");
+    assertThat(metadata.getVersion()).isEqualTo("1.0");
+    assertThat(metadata.getOrganization()).isEqualTo("SonarSource");
+    assertThat(metadata.getOrganizationUrl()).isEqualTo("http://www.sonarsource.org");
+    assertThat(metadata.getLicense()).isEqualTo("LGPL 3");
+    assertThat(metadata.getMainClass()).isEqualTo("foo.Main");
+  }
+
+  private URI resource(String fileName) throws URISyntaxException {
+    URL resource = getClass().getResource(getClass().getSimpleName() + "/" + fileName);
+    return resource.toURI();
+  }
+
+  @Test
+  public void getDownloadedPluginFilenames_reads_plugin_metadata_of_files_in_download_folder() throws Exception {
+    pluginDownloader.start();
+    assertThat(pluginDownloader.getDownloadedPlugins()).hasSize(0);
 
     File file1 = new File(downloadDir, "file1.jar");
     file1.createNewFile();
     File file2 = new File(downloadDir, "file2.jar");
     file2.createNewFile();
 
-    assertThat(pluginDownloader.getDownloads()).hasSize(2);
+    assertThat(pluginDownloader.getDownloadedPluginFilenames()).hasSize(2);
   }
 
   @Test
@@ -250,12 +279,12 @@ public class PluginDownloaderTest {
     Release testDepR = new Release(testDep, "1.0").setDownloadUrl("http://server/testdep-1.0.jar");
     testDep.addRelease(testDepR);
 
-    when(updateCenter.findInstallablePlugins("test1", Version.create("1.0"))).thenReturn(newArrayList(test1R, testDepR));
-    when(updateCenter.findInstallablePlugins("test2", Version.create("1.0"))).thenReturn(newArrayList(test2R, testDepR));
+    when(updateCenter.findInstallablePlugins("test1", create("1.0"))).thenReturn(newArrayList(test1R, testDepR));
+    when(updateCenter.findInstallablePlugins("test2", create("1.0"))).thenReturn(newArrayList(test2R, testDepR));
 
     pluginDownloader.start();
-    pluginDownloader.download("test1", Version.create("1.0"));
-    pluginDownloader.download("test2", Version.create("1.0"));
+    pluginDownloader.download("test1", create("1.0"));
+    pluginDownloader.download("test2", create("1.0"));
 
     assertThat(new File(downloadDir, "test1-1.0.jar")).exists();
     assertThat(new File(downloadDir, "test2-1.0.jar")).exists();
index 5a9fb7c4b312f4dd3b23254654ddf8fe7886f0cd..240c6a566218c39ece205eaa582f136ed18796b2 100644 (file)
@@ -74,7 +74,7 @@ public class PendingPluginsWsActionTest {
 
   @Test
   public void verify_properties_displayed_in_json_per_installing_plugin() throws Exception {
-    when(pluginDownloader.getDownloads()).thenReturn(of("installed_file.jar"));
+    when(pluginDownloader.getDownloadedPluginFilenames()).thenReturn(of("installed_file.jar"));
 
     underTest.handle(request, response);
 
@@ -116,7 +116,7 @@ public class PendingPluginsWsActionTest {
 
   @Test
   public void installing_plugin_are_sorted_and_unique() throws Exception {
-    when(pluginDownloader.getDownloads()).thenReturn(of("file2.jar", "file0.jar", "file0.jar", "file1.jar"));
+    when(pluginDownloader.getDownloadedPluginFilenames()).thenReturn(of("file2.jar", "file0.jar", "file0.jar", "file1.jar"));
 
     underTest.handle(request, response);
 
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/plugins/PluginDownloaderTest/foo-plugin-1.0.jar b/server/sonar-server/src/test/resources/org/sonar/server/plugins/PluginDownloaderTest/foo-plugin-1.0.jar
new file mode 100644 (file)
index 0000000..3b3ed4b
Binary files /dev/null and b/server/sonar-server/src/test/resources/org/sonar/server/plugins/PluginDownloaderTest/foo-plugin-1.0.jar differ