From 1006c3556b73e8f07a4446bf9626a866c6f8fa9a Mon Sep 17 00:00:00 2001 From: Godin Date: Thu, 23 Sep 2010 16:18:26 +0000 Subject: [PATCH] SONAR-1780: * An exception should be thrown in case when two Sonar plugins try to use the same key * Add message to log, when file with plugin was deleted --- .../sonar/server/plugins/PluginDeployer.java | 69 ++++++++++++------ .../server/plugins/PluginDeployerTest.java | 26 +++++-- .../sonar-build-breaker-plugin-0.1.jar | Bin 0 -> 5033 bytes .../sonar-build-breaker-plugin-0.2.jar | Bin 0 -> 5033 bytes .../extensions/plugins/foo-plugin1.jar | Bin 0 -> 1460 bytes .../extensions/plugins/foo-plugin2.jar | Bin 0 -> 1460 bytes 6 files changed, 64 insertions(+), 31 deletions(-) create mode 100644 sonar-server/src/test/resources/org/sonar/server/plugins/PluginDeployerTest/failIfTwoDeprecatedPluginsWithSameKey/extensions/plugins/sonar-build-breaker-plugin-0.1.jar create mode 100644 sonar-server/src/test/resources/org/sonar/server/plugins/PluginDeployerTest/failIfTwoDeprecatedPluginsWithSameKey/extensions/plugins/sonar-build-breaker-plugin-0.2.jar create mode 100644 sonar-server/src/test/resources/org/sonar/server/plugins/PluginDeployerTest/failIfTwoPluginsWithSameKey/extensions/plugins/foo-plugin1.jar create mode 100644 sonar-server/src/test/resources/org/sonar/server/plugins/PluginDeployerTest/failIfTwoPluginsWithSameKey/extensions/plugins/foo-plugin2.jar diff --git a/sonar-server/src/main/java/org/sonar/server/plugins/PluginDeployer.java b/sonar-server/src/main/java/org/sonar/server/plugins/PluginDeployer.java index 4cfb69828d7..9da1dd0aa11 100644 --- a/sonar-server/src/main/java/org/sonar/server/plugins/PluginDeployer.java +++ b/sonar-server/src/main/java/org/sonar/server/plugins/PluginDeployer.java @@ -32,12 +32,18 @@ import org.sonar.api.utils.ZipUtils; import org.sonar.core.plugin.JpaPlugin; import org.sonar.core.plugin.JpaPluginDao; import org.sonar.server.platform.DefaultServerFileSystem; +import org.sonar.server.platform.ServerStartException; + +import com.google.common.collect.Maps; import java.io.File; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; public final class PluginDeployer implements ServerComponent { @@ -47,8 +53,8 @@ public final class PluginDeployer implements ServerComponent { private DefaultServerFileSystem fileSystem; private JpaPluginDao dao; private PluginClassLoaders classloaders; - private Map pluginByKeys = new HashMap(); - private List deprecatedPlugins = new ArrayList(); + private Map pluginByKeys = Maps.newHashMap(); + private Map deprecatedPlugins = Maps.newHashMap(); public PluginDeployer(Server server, DefaultServerFileSystem fileSystem, JpaPluginDao dao, PluginClassLoaders classloaders) { this.server = server; @@ -105,13 +111,14 @@ public final class PluginDeployer implements ServerComponent { } private void deployDeprecatedPlugins() throws IOException { - for (PluginMetadata deprecatedPlugin : deprecatedPlugins) { - if (deprecatedPlugin.getKey() != null && !pluginByKeys.containsKey(deprecatedPlugin.getKey())) { + for (PluginMetadata deprecatedPlugin : deprecatedPlugins.values()) { + PluginMetadata metadata = pluginByKeys.get(deprecatedPlugin.getKey()); + if (metadata != null) { + FileUtils.deleteQuietly(deprecatedPlugin.getSourceFile()); + Logs.INFO.info("Old plugin " + deprecatedPlugin.getFilename() + " replaced by new " + metadata.getFilename()); + } else { pluginByKeys.put(deprecatedPlugin.getKey(), deprecatedPlugin); deploy(deprecatedPlugin); - - } else { - FileUtils.deleteQuietly(deprecatedPlugin.getSourceFile()); } } } @@ -153,22 +160,22 @@ public final class PluginDeployer implements ServerComponent { private void loadCorePlugins() throws IOException { for (File file : fileSystem.getCorePlugins()) { - registerPluginMetadata(file, true); + registerPluginMetadata(file, true, false); } } private void loadUserPlugins() throws IOException { for (File file : fileSystem.getUserPlugins()) { - registerPluginMetadata(file, false); + registerPluginMetadata(file, false, false); } } private void moveAndLoadDownloadedPlugins() throws IOException { if (fileSystem.getDownloadedPluginsDir().exists()) { - Collection jars = FileUtils.listFiles(fileSystem.getDownloadedPluginsDir(), new String[]{"jar"}, false); + Collection jars = FileUtils.listFiles(fileSystem.getDownloadedPluginsDir(), new String[] { "jar" }, false); for (File jar : jars) { File movedJar = moveDownloadedFile(jar); - registerPluginMetadata(movedJar, false); + registerPluginMetadata(movedJar, false, true); } } } @@ -179,28 +186,39 @@ public final class PluginDeployer implements ServerComponent { return new File(fileSystem.getUserPluginsDir(), jar.getName()); } catch (IOException e) { - LOG.error("Fail to move the downloaded file:" + jar.getAbsolutePath(), e); + LOG.error("Fail to move the downloaded file: " + jar.getAbsolutePath(), e); return null; } } - private void registerPluginMetadata(File file, boolean corePlugin) throws IOException { + private void registerPluginMetadata(File file, boolean corePlugin, boolean canDeleteOld) throws IOException { PluginMetadata metadata = PluginMetadata.createFromJar(file, corePlugin); String pluginKey = metadata.getKey(); if (pluginKey != null) { - PluginMetadata existing = pluginByKeys.get(pluginKey); - if (existing != null) { - FileUtils.deleteQuietly(existing.getSourceFile()); - pluginByKeys.remove(pluginKey); - } - pluginByKeys.put(pluginKey, metadata); - + registerPluginMetadata(pluginByKeys, file, metadata, canDeleteOld); } else if (metadata.isOldManifest()) { loadDeprecatedPlugin(metadata); - deprecatedPlugins.add(metadata); + registerPluginMetadata(deprecatedPlugins, file, metadata, canDeleteOld); } } + private void registerPluginMetadata(Map map, File file, PluginMetadata metadata, boolean canDeleteOld) { + String pluginKey = metadata.getKey(); + PluginMetadata existing = map.get(pluginKey); + if (existing != null) { + if (canDeleteOld) { + FileUtils.deleteQuietly(existing.getSourceFile()); + map.remove(pluginKey); + Logs.INFO.info("Old plugin " + existing.getFilename() + " replaced by new " + metadata.getFilename()); + } else { + throw new ServerStartException("Found two plugins with the same key '" + pluginKey + "': " + + metadata.getFilename() + " and " + + existing.getFilename()); + } + } + map.put(metadata.getKey(), metadata); + } + private void loadDeprecatedPlugin(PluginMetadata plugin) throws IOException { // URLClassLoader locks files on Windows // => copy the file before in a temp directory @@ -209,7 +227,7 @@ public final class PluginDeployer implements ServerComponent { String mainClass = plugin.getMainClass(); try { - URLClassLoader pluginClassLoader = URLClassLoader.newInstance(new URL[]{tempFile.toURI().toURL()}, getClass().getClassLoader()); + URLClassLoader pluginClassLoader = URLClassLoader.newInstance(new URL[] { tempFile.toURI().toURL() }, getClass().getClassLoader()); Plugin pluginInstance = (Plugin) pluginClassLoader.loadClass(mainClass).newInstance(); plugin.setKey(pluginInstance.getKey()); plugin.setDescription(pluginInstance.getDescription()); @@ -218,6 +236,9 @@ public final class PluginDeployer implements ServerComponent { } catch (Exception e) { throw new RuntimeException("The plugin main class can not be created: plugin=" + plugin.getFilename() + ", class=" + mainClass, e); } - } + if (StringUtils.isBlank(plugin.getKey())) { + throw new ServerStartException("Found plugin with empty key: " + plugin.getFilename()); + } + } } diff --git a/sonar-server/src/test/java/org/sonar/server/plugins/PluginDeployerTest.java b/sonar-server/src/test/java/org/sonar/server/plugins/PluginDeployerTest.java index 2b4d6753623..4087029435a 100644 --- a/sonar-server/src/test/java/org/sonar/server/plugins/PluginDeployerTest.java +++ b/sonar-server/src/test/java/org/sonar/server/plugins/PluginDeployerTest.java @@ -31,6 +31,7 @@ import org.sonar.core.plugin.JpaPluginFile; import org.sonar.jpa.test.AbstractDbUnitTestCase; import org.sonar.server.platform.DefaultServerFileSystem; import org.sonar.server.platform.ServerImpl; +import org.sonar.server.platform.ServerStartException; import org.sonar.test.TestUtils; import java.io.File; @@ -39,8 +40,8 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.List; -import static junit.framework.Assert.assertNotNull; import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; public class PluginDeployerTest extends AbstractDbUnitTestCase { @@ -55,7 +56,7 @@ public class PluginDeployerTest extends AbstractDbUnitTestCase { @Rule public TestName name = new TestName(); - + @Before public void start() throws ParseException { server = new ServerImpl("1", "2.2", new SimpleDateFormat("yyyy-MM-dd").parse("2010-05-18")); @@ -67,7 +68,6 @@ public class PluginDeployerTest extends AbstractDbUnitTestCase { deployer = new PluginDeployer(server, fileSystem, dao, classloaders); } - @Test public void deployPlugin() throws IOException { setupData("shared"); @@ -75,7 +75,7 @@ public class PluginDeployerTest extends AbstractDbUnitTestCase { // check that the plugin is registered in database List plugins = dao.getPlugins(); - assertThat(plugins.size(), is(1)); // no more checkstyle + assertThat(plugins.size(), is(1)); // no more checkstyle JpaPlugin plugin = plugins.get(0); assertThat(plugin.getName(), is("Foo")); assertThat(plugin.getFiles().size(), is(1)); @@ -101,7 +101,7 @@ public class PluginDeployerTest extends AbstractDbUnitTestCase { // check that the plugin is registered in database List plugins = dao.getPlugins(); - assertThat(plugins.size(), is(1)); // no more checkstyle + assertThat(plugins.size(), is(1)); // no more checkstyle JpaPlugin plugin = plugins.get(0); assertThat(plugin.getKey(), is("build-breaker")); assertThat(plugin.getFiles().size(), is(1)); @@ -128,7 +128,7 @@ public class PluginDeployerTest extends AbstractDbUnitTestCase { // check that the plugin is registered in database List plugins = dao.getPlugins(); - assertThat(plugins.size(), is(1)); // no more checkstyle + assertThat(plugins.size(), is(1)); // no more checkstyle JpaPlugin plugin = plugins.get(0); assertThat(plugin.getFiles().size(), is(2)); JpaPluginFile pluginFile = plugin.getFiles().get(1); @@ -153,7 +153,19 @@ public class PluginDeployerTest extends AbstractDbUnitTestCase { // check that the plugin is registered in database List plugins = dao.getPlugins(); - assertThat(plugins.size(), is(0)); + assertThat(plugins.size(), is(0)); + } + + @Test(expected = ServerStartException.class) + public void failIfTwoPluginsWithSameKey() throws IOException { + setupData("shared"); + deployer.start(); + } + + @Test(expected = ServerStartException.class) + public void failIfTwoDeprecatedPluginsWithSameKey() throws IOException { + setupData("shared"); + deployer.start(); } } diff --git a/sonar-server/src/test/resources/org/sonar/server/plugins/PluginDeployerTest/failIfTwoDeprecatedPluginsWithSameKey/extensions/plugins/sonar-build-breaker-plugin-0.1.jar b/sonar-server/src/test/resources/org/sonar/server/plugins/PluginDeployerTest/failIfTwoDeprecatedPluginsWithSameKey/extensions/plugins/sonar-build-breaker-plugin-0.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..862614d26c7df2fb0d288e41f39e97d368ea06a5 GIT binary patch literal 5033 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 IJCus#f4{e|X#fBK literal 0 HcmV?d00001 diff --git a/sonar-server/src/test/resources/org/sonar/server/plugins/PluginDeployerTest/failIfTwoDeprecatedPluginsWithSameKey/extensions/plugins/sonar-build-breaker-plugin-0.2.jar b/sonar-server/src/test/resources/org/sonar/server/plugins/PluginDeployerTest/failIfTwoDeprecatedPluginsWithSameKey/extensions/plugins/sonar-build-breaker-plugin-0.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..862614d26c7df2fb0d288e41f39e97d368ea06a5 GIT binary patch literal 5033 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 IJCus#f4{e|X#fBK literal 0 HcmV?d00001 diff --git a/sonar-server/src/test/resources/org/sonar/server/plugins/PluginDeployerTest/failIfTwoPluginsWithSameKey/extensions/plugins/foo-plugin1.jar b/sonar-server/src/test/resources/org/sonar/server/plugins/PluginDeployerTest/failIfTwoPluginsWithSameKey/extensions/plugins/foo-plugin1.jar new file mode 100644 index 0000000000000000000000000000000000000000..7bcf027151a0535acc23461c714b73e66685f7b5 GIT binary patch literal 1460 zcmWIWW@Zs#-~d9ux=l6=NPwL|fFUhEU$3O1Bs7ADL2vdaZ)G6<&M3m*efs=)c7_0N zc8>ZFubkO{npl810B95!*nnU(qd0*^#mDHIle!`vGfdMQk{uv z4@cq0Cx2r09%*Wt6S8;0l`f&{d!GE6a%NA-f|N|pS?gN2F5K8TapBITt(;(A=B$#` ziwF8_HHt5Tu=vu~HN;WZ)6Wg;%bHoAytOfW`LY%@oJD}XglqG4^z(Fc4Gz)sb%TXd zD$o>AIF(K~>vz~dpymCvKYVqJyX`#`eohl%Y+BMQ@}NtndUC{)*C)!PPFjQ z*V#8`UVO%t%c}UP{KG-3DLKm5rl`c3e`ERA)h)K~*MYRgNpsmn4}SQf6M0GVF2m`o zoD(K(*`7P6BD0?_c>M*Fb-zS;>dod)pBBCG-;FzgL0f8bC%%soZAzJ1tQ0OLUiaav z#mDHQg-2)St7a#?d6H$y)6Bs)m4DrLsg}=Q=bJz7=w3Z1ru#ALx!~(e?-nwfG~7D0 zBWYQ6Da%Q@IkO$pOcNv`zeS|HX`7_^=hxD;H$D~37kPU5Vd=?#?n|GrgVNR0HS9BA z0z})o0GMlvK_LT^rr&ocK86%S@Ga_FgXEb&O z9-s;^a9Gj^qTyMC1D;O%w%8v*G{yKUC4M57B5F_Er{)H;J1!~+0=_^Dn1 literal 0 HcmV?d00001 diff --git a/sonar-server/src/test/resources/org/sonar/server/plugins/PluginDeployerTest/failIfTwoPluginsWithSameKey/extensions/plugins/foo-plugin2.jar b/sonar-server/src/test/resources/org/sonar/server/plugins/PluginDeployerTest/failIfTwoPluginsWithSameKey/extensions/plugins/foo-plugin2.jar new file mode 100644 index 0000000000000000000000000000000000000000..7bcf027151a0535acc23461c714b73e66685f7b5 GIT binary patch literal 1460 zcmWIWW@Zs#-~d9ux=l6=NPwL|fFUhEU$3O1Bs7ADL2vdaZ)G6<&M3m*efs=)c7_0N zc8>ZFubkO{npl810B95!*nnU(qd0*^#mDHIle!`vGfdMQk{uv z4@cq0Cx2r09%*Wt6S8;0l`f&{d!GE6a%NA-f|N|pS?gN2F5K8TapBITt(;(A=B$#` ziwF8_HHt5Tu=vu~HN;WZ)6Wg;%bHoAytOfW`LY%@oJD}XglqG4^z(Fc4Gz)sb%TXd zD$o>AIF(K~>vz~dpymCvKYVqJyX`#`eohl%Y+BMQ@}NtndUC{)*C)!PPFjQ z*V#8`UVO%t%c}UP{KG-3DLKm5rl`c3e`ERA)h)K~*MYRgNpsmn4}SQf6M0GVF2m`o zoD(K(*`7P6BD0?_c>M*Fb-zS;>dod)pBBCG-;FzgL0f8bC%%soZAzJ1tQ0OLUiaav z#mDHQg-2)St7a#?d6H$y)6Bs)m4DrLsg}=Q=bJz7=w3Z1ru#ALx!~(e?-nwfG~7D0 zBWYQ6Da%Q@IkO$pOcNv`zeS|HX`7_^=hxD;H$D~37kPU5Vd=?#?n|GrgVNR0HS9BA z0z})o0GMlvK_LT^rr&ocK86%S@Ga_FgXEb&O z9-s;^a9Gj^qTyMC1D;O%w%8v*G{yKUC4M57B5F_Er{)H;J1!~+0=_^Dn1 literal 0 HcmV?d00001 -- 2.39.5