aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-server/src/main/java
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@gmail.com>2014-03-16 23:31:18 +0100
committerSimon Brandhof <simon.brandhof@gmail.com>2014-03-16 23:31:18 +0100
commitd7c81d0b83d4e6d852bedace63e8a9db1e40ab46 (patch)
tree25ed1d66b194d108cc88b54096fc10b59f551690 /sonar-server/src/main/java
parentf2b39ccc3223c71b741b443ebc36999352958080 (diff)
downloadsonarqube-d7c81d0b83d4e6d852bedace63e8a9db1e40ab46.tar.gz
sonarqube-d7c81d0b83d4e6d852bedace63e8a9db1e40ab46.zip
SONAR-4843 restart most of components
Diffstat (limited to 'sonar-server/src/main/java')
-rw-r--r--sonar-server/src/main/java/org/sonar/server/platform/Platform.java183
-rw-r--r--sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java (renamed from sonar-server/src/main/java/org/sonar/server/platform/ServerComponentsStarter.java)133
-rw-r--r--sonar-server/src/main/java/org/sonar/server/platform/ws/RestartHandler.java2
-rw-r--r--sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java6
4 files changed, 180 insertions, 144 deletions
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
index ea7ad0bc995..353893e7d0b 100644
--- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
+++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
@@ -19,46 +19,10 @@
*/
package org.sonar.server.platform;
-import org.apache.commons.configuration.BaseConfiguration;
import org.slf4j.LoggerFactory;
import org.sonar.api.platform.ComponentContainer;
import org.sonar.api.platform.Server;
-import org.sonar.api.utils.Durations;
-import org.sonar.api.utils.HttpDownloader;
-import org.sonar.api.utils.TimeProfiler;
-import org.sonar.api.utils.UriReader;
-import org.sonar.api.utils.internal.TempFolderCleaner;
-import org.sonar.core.config.Logback;
-import org.sonar.core.i18n.DefaultI18n;
-import org.sonar.core.i18n.GwtI18n;
-import org.sonar.core.i18n.RuleI18nManager;
-import org.sonar.core.persistence.DaoUtils;
import org.sonar.core.persistence.DatabaseVersion;
-import org.sonar.core.persistence.DefaultDatabase;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.persistence.PreviewDatabaseFactory;
-import org.sonar.core.persistence.SemaphoreUpdater;
-import org.sonar.core.persistence.SemaphoresImpl;
-import org.sonar.core.profiling.Profiling;
-import org.sonar.core.purge.PurgeProfiler;
-import org.sonar.jpa.session.DatabaseSessionProvider;
-import org.sonar.jpa.session.DefaultDatabaseConnector;
-import org.sonar.jpa.session.ThreadLocalDatabaseSessionFactory;
-import org.sonar.server.db.EmbeddedDatabaseFactory;
-import org.sonar.server.db.migrations.DatabaseMigration;
-import org.sonar.server.db.migrations.DatabaseMigrations;
-import org.sonar.server.db.migrations.DatabaseMigrator;
-import org.sonar.server.es.ESNode;
-import org.sonar.server.platform.ws.PlatformWs;
-import org.sonar.server.platform.ws.RestartHandler;
-import org.sonar.server.plugins.ServerPluginJarInstaller;
-import org.sonar.server.plugins.ServerPluginJarsInstaller;
-import org.sonar.server.plugins.ServerPluginRepository;
-import org.sonar.server.plugins.InstalledPluginReferentialFactory;
-import org.sonar.server.plugins.ServerExtensionInstaller;
-import org.sonar.server.startup.ServerMetadataPersister;
-import org.sonar.server.ui.JRubyI18n;
-import org.sonar.server.ui.JRubyProfiling;
import javax.annotation.CheckForNull;
import javax.servlet.ServletContext;
@@ -70,12 +34,10 @@ public class Platform {
private static final Platform INSTANCE = new Platform();
- // level 1 : database stuff, settings
- // level 2 : level 1 + components that are never restarted
- // level 3 : level 2 + all other components, including plugin extensions
- private ComponentContainer level1Container, level2Container, level3Container;
-
- private boolean connected = false;
+ private ServerComponents serverComponents;
+ private ComponentContainer level1Container, level2Container, level3Container, level4Container;
+ private ComponentContainer currentContainer;
+ private boolean dbConnected = false;
private boolean started = false;
private Platform() {
@@ -104,98 +66,70 @@ public class Platform {
}
public void init(ServletContext servletContext) {
- if (!connected) {
- startLevel1Container(servletContext);
- connected = true;
+ serverComponents = new ServerComponents(this, servletContext);
+ if (!dbConnected) {
+ startLevel1Container();
+ startLevel2Container();
+ dbConnected = true;
}
}
- // Platform is injected in Pico, so do not rename "start"
+ // Platform is injected in Pico, so do not rename this method "start"
public void doStart() {
if (!started && getDatabaseStatus() == DatabaseVersion.Status.UP_TO_DATE) {
- TimeProfiler profiler = new TimeProfiler().start("Start components");
- startLevel2Container();
+ startLevel34Containers();
started = true;
- profiler.stop();
}
}
- private void startLevel1Container(ServletContext servletContext) {
+ /**
+ * Start level 1 only
+ */
+ private void startLevel1Container() {
level1Container = new ComponentContainer();
- level1Container.addSingleton(this);
- level1Container.addSingleton(servletContext);
- level1Container.addSingleton(new BaseConfiguration());
- level1Container.addSingleton(ServerSettings.class);
- level1Container.addSingleton(ServerImpl.class);
- level1Container.addSingleton(Logback.class);
- level1Container.addSingleton(Profiling.class);
- level1Container.addSingleton(JRubyProfiling.class);
- level1Container.addSingleton(EmbeddedDatabaseFactory.class);
- level1Container.addSingleton(DefaultDatabase.class);
- level1Container.addSingleton(MyBatis.class);
- level1Container.addSingleton(DefaultServerUpgradeStatus.class);
- level1Container.addSingleton(DatabaseServerCompatibility.class);
- for (Class<? extends DatabaseMigration> migrationClass : DatabaseMigrations.CLASSES) {
- level1Container.addSingleton(migrationClass);
- }
- level1Container.addSingleton(DatabaseMigrator.class);
- level1Container.addSingleton(DatabaseVersion.class);
- for (Class daoClass : DaoUtils.getDaoClasses()) {
- level1Container.addSingleton(daoClass);
- }
- level1Container.addSingleton(PurgeProfiler.class);
- level1Container.addSingleton(DefaultServerFileSystem.class);
- level1Container.addSingleton(PreviewDatabaseFactory.class);
- level1Container.addSingleton(SemaphoreUpdater.class);
- level1Container.addSingleton(SemaphoresImpl.class);
- level1Container.addPicoAdapter(new TempFolderProvider());
- level1Container.addSingleton(TempFolderCleaner.class);
-
-
- // plugins
- level1Container.addSingleton(ServerPluginJarsInstaller.class);
- level1Container.addSingleton(ServerPluginJarInstaller.class);
- level1Container.addSingleton(InstalledPluginReferentialFactory.class);
- level1Container.addSingleton(ServerPluginRepository.class);
- level1Container.addSingleton(ServerExtensionInstaller.class);
-
- // depends on plugins
- level1Container.addSingleton(RailsAppsDeployer.class);
- level1Container.addSingleton(JRubyI18n.class);
- level1Container.addSingleton(DefaultI18n.class);
- level1Container.addSingleton(RuleI18nManager.class);
- level1Container.addSingleton(GwtI18n.class);
- level1Container.addSingleton(Durations.class);
+ level1Container.addSingletons(serverComponents.level1Components());
level1Container.startComponents();
- }
-
- private DatabaseVersion.Status getDatabaseStatus() {
- DatabaseVersion version = getContainer().getComponentByType(DatabaseVersion.class);
- return version.getStatus();
+ currentContainer = level1Container;
}
/**
- * Components listed here are never restarted
+ * Start level 2 only
*/
private void startLevel2Container() {
level2Container = level1Container.createChild();
- level2Container.addSingleton(PersistentSettings.class);
- level2Container.addSingleton(DefaultDatabaseConnector.class);
- level2Container.addSingleton(ThreadLocalDatabaseSessionFactory.class);
- level2Container.addPicoAdapter(new DatabaseSessionProvider());
- level2Container.addSingleton(ServerMetadataPersister.class);
- level2Container.addSingleton(ESNode.class);
- level2Container.addSingleton(HttpDownloader.class);
- level2Container.addSingleton(UriReader.class);
- level2Container.addSingleton(ServerIdGenerator.class);
-
- // ws
- level2Container.addSingleton(RestartHandler.class);
- level2Container.addSingleton(PlatformWs.class);
-
+ level2Container.addSingletons(serverComponents.level2Components());
level2Container.startComponents();
+ currentContainer = level2Container;
+ }
+
+ /**
+ * Start level 3 and greater
+ */
+ private void startLevel34Containers() {
+ level3Container = level2Container.createChild();
+ level3Container.addSingletons(serverComponents.level3Components());
+ level3Container.startComponents();
+ currentContainer = level3Container;
- restartLevel3Container();
+ level4Container = level3Container.createChild();
+ serverComponents.startLevel4Components(level4Container);
+ currentContainer = level4Container;
+
+ }
+
+ public void restart() {
+ // Do not need to initialize database connection, so level 1 is skipped
+ if (level2Container != null) {
+ level2Container.stopComponents();
+ currentContainer = level1Container;
+ }
+ startLevel2Container();
+ startLevel34Containers();
+ }
+
+ private DatabaseVersion.Status getDatabaseStatus() {
+ DatabaseVersion version = getContainer().getComponentByType(DatabaseVersion.class);
+ return version.getStatus();
}
// Do not rename "stop"
@@ -204,7 +138,8 @@ public class Platform {
try {
level1Container.stopComponents();
level1Container = null;
- connected = false;
+ currentContainer = null;
+ dbConnected = false;
started = false;
} catch (Exception e) {
LoggerFactory.getLogger(getClass()).debug("Fail to stop server - ignored", e);
@@ -212,22 +147,8 @@ public class Platform {
}
}
- public void restartLevel3Container() {
- if (level3Container != null) {
- level3Container.stopComponents();
- }
- level3Container = level2Container.createChild();
- new ServerComponentsStarter().start(level3Container);
- }
-
public ComponentContainer getContainer() {
- if (level3Container != null) {
- return level3Container;
- }
- if (level2Container != null) {
- return level2Container;
- }
- return level1Container;
+ return currentContainer;
}
public Object getComponent(Object key) {
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponentsStarter.java b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
index c360d947c6c..55754132be7 100644
--- a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponentsStarter.java
+++ b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
@@ -19,6 +19,8 @@
*/
package org.sonar.server.platform;
+import com.google.common.collect.Lists;
+import org.apache.commons.configuration.BaseConfiguration;
import org.sonar.api.config.EmailSettings;
import org.sonar.api.issue.action.Actions;
import org.sonar.api.platform.ComponentContainer;
@@ -29,8 +31,16 @@ import org.sonar.api.resources.Languages;
import org.sonar.api.resources.ResourceTypes;
import org.sonar.api.rules.AnnotationRuleParser;
import org.sonar.api.rules.XMLRuleParser;
+import org.sonar.api.utils.Durations;
+import org.sonar.api.utils.HttpDownloader;
+import org.sonar.api.utils.UriReader;
+import org.sonar.api.utils.internal.TempFolderCleaner;
import org.sonar.core.component.SnapshotPerspectives;
import org.sonar.core.component.db.ComponentDao;
+import org.sonar.core.config.Logback;
+import org.sonar.core.i18n.DefaultI18n;
+import org.sonar.core.i18n.GwtI18n;
+import org.sonar.core.i18n.RuleI18nManager;
import org.sonar.core.issue.IssueFilterSerializer;
import org.sonar.core.issue.IssueNotifications;
import org.sonar.core.issue.IssueUpdater;
@@ -42,7 +52,16 @@ import org.sonar.core.measure.MeasureFilterFactory;
import org.sonar.core.metric.DefaultMetricFinder;
import org.sonar.core.notification.DefaultNotificationManager;
import org.sonar.core.permission.PermissionFacade;
+import org.sonar.core.persistence.DaoUtils;
+import org.sonar.core.persistence.DatabaseVersion;
+import org.sonar.core.persistence.DefaultDatabase;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.persistence.PreviewDatabaseFactory;
+import org.sonar.core.persistence.SemaphoreUpdater;
+import org.sonar.core.persistence.SemaphoresImpl;
import org.sonar.core.preview.PreviewCache;
+import org.sonar.core.profiling.Profiling;
+import org.sonar.core.purge.PurgeProfiler;
import org.sonar.core.qualitygate.db.ProjectQgateAssociationDao;
import org.sonar.core.qualitygate.db.QualityGateConditionDao;
import org.sonar.core.qualitygate.db.QualityGateDao;
@@ -61,14 +80,21 @@ import org.sonar.jpa.dao.MeasuresDao;
import org.sonar.jpa.dao.ProfilesDao;
import org.sonar.jpa.dao.RulesDao;
import org.sonar.jpa.session.DatabaseSessionFactory;
+import org.sonar.jpa.session.DatabaseSessionProvider;
+import org.sonar.jpa.session.DefaultDatabaseConnector;
+import org.sonar.jpa.session.ThreadLocalDatabaseSessionFactory;
import org.sonar.server.charts.ChartFactory;
import org.sonar.server.component.DefaultComponentFinder;
import org.sonar.server.component.DefaultRubyComponentService;
+import org.sonar.server.db.EmbeddedDatabaseFactory;
+import org.sonar.server.db.migrations.DatabaseMigrations;
+import org.sonar.server.db.migrations.DatabaseMigrator;
import org.sonar.server.debt.DebtCharacteristicsXMLImporter;
import org.sonar.server.debt.DebtModelSynchronizer;
import org.sonar.server.debt.DebtRulesXMLImporter;
import org.sonar.server.debt.DebtService;
import org.sonar.server.es.ESIndex;
+import org.sonar.server.es.ESNode;
import org.sonar.server.issue.ActionPlanService;
import org.sonar.server.issue.ActionService;
import org.sonar.server.issue.AssignAction;
@@ -95,8 +121,14 @@ import org.sonar.server.notifications.NotificationService;
import org.sonar.server.permission.InternalPermissionService;
import org.sonar.server.permission.InternalPermissionTemplateService;
import org.sonar.server.permission.PermissionFinder;
+import org.sonar.server.platform.ws.PlatformWs;
+import org.sonar.server.platform.ws.RestartHandler;
+import org.sonar.server.plugins.InstalledPluginReferentialFactory;
import org.sonar.server.plugins.PluginDownloader;
import org.sonar.server.plugins.ServerExtensionInstaller;
+import org.sonar.server.plugins.ServerPluginJarInstaller;
+import org.sonar.server.plugins.ServerPluginJarsInstaller;
+import org.sonar.server.plugins.ServerPluginRepository;
import org.sonar.server.plugins.UpdateCenterClient;
import org.sonar.server.plugins.UpdateCenterMatrixFactory;
import org.sonar.server.qualitygate.QgateProjectFinder;
@@ -153,8 +185,11 @@ import org.sonar.server.startup.RegisterNewProfiles;
import org.sonar.server.startup.RegisterPermissionTemplates;
import org.sonar.server.startup.RegisterServletFilters;
import org.sonar.server.startup.RenameDeprecatedPropertyKeys;
+import org.sonar.server.startup.ServerMetadataPersister;
import org.sonar.server.text.MacroInterpreter;
import org.sonar.server.text.RubyTextService;
+import org.sonar.server.ui.JRubyI18n;
+import org.sonar.server.ui.JRubyProfiling;
import org.sonar.server.ui.PageDecorations;
import org.sonar.server.ui.Views;
import org.sonar.server.user.DefaultUserService;
@@ -172,15 +207,97 @@ import org.sonar.server.util.TypeValidations;
import org.sonar.server.ws.ListingWs;
import org.sonar.server.ws.WebServiceEngine;
-public class ServerComponentsStarter {
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
- public void start(ComponentContainer pico) {
- registerComponents(pico);
- pico.startComponents();
- executeStartupTaks(pico);
+class ServerComponents {
+
+ private final Object[] rootComponents;
+
+ ServerComponents(Object... rootComponents) {
+ this.rootComponents = rootComponents;
+ }
+
+ /**
+ * All the stuff required to connect to database
+ */
+ Collection level1Components() {
+ List components = Lists.newArrayList(rootComponents);
+ components.addAll(Arrays.asList(
+ new BaseConfiguration(),
+ ServerSettings.class,
+ ServerImpl.class,
+ Logback.class,
+ Profiling.class,
+ JRubyProfiling.class,
+ EmbeddedDatabaseFactory.class,
+ DefaultDatabase.class,
+ MyBatis.class,
+ DefaultServerUpgradeStatus.class,
+ DatabaseServerCompatibility.class,
+ DatabaseMigrator.class,
+ DatabaseVersion.class,
+ PurgeProfiler.class,
+ DefaultServerFileSystem.class,
+ PreviewDatabaseFactory.class,
+ SemaphoreUpdater.class,
+ SemaphoresImpl.class,
+ TempFolderCleaner.class,
+ new TempFolderProvider()
+ ));
+ components.addAll(DatabaseMigrations.CLASSES);
+ components.addAll(DaoUtils.getDaoClasses());
+ return components;
+ }
+
+ /**
+ * The stuff required to display the db upgrade form in webapp.
+ * Needs to be connected to db.
+ */
+ Collection level2Components() {
+ return Lists.newArrayList(
+ // plugins
+ ServerPluginJarsInstaller.class,
+ ServerPluginJarInstaller.class,
+ InstalledPluginReferentialFactory.class,
+ ServerPluginRepository.class,
+ ServerExtensionInstaller.class,
+
+ // depends on plugins
+ RailsAppsDeployer.class,
+ JRubyI18n.class,
+ DefaultI18n.class,
+ RuleI18nManager.class,
+ GwtI18n.class,
+ Durations.class,
+
+ // ws
+ RestartHandler.class,
+ PlatformWs.class
+ );
+ }
+
+ /**
+ * The core components that complete the initialization of database
+ * when its schema is up-to-date.
+ */
+ Collection level3Components() {
+ return Lists.newArrayList(
+ PersistentSettings.class,
+ DefaultDatabaseConnector.class,
+ ThreadLocalDatabaseSessionFactory.class,
+ new DatabaseSessionProvider(),
+ ServerMetadataPersister.class,
+ ESNode.class,
+ HttpDownloader.class,
+ UriReader.class,
+ ServerIdGenerator.class
+ );
}
- private void registerComponents(ComponentContainer pico) {
+
+ void startLevel4Components(ComponentContainer pico) {
pico.addSingleton(ESIndex.class);
pico.addSingleton(UpdateCenterClient.class);
pico.addSingleton(UpdateCenterMatrixFactory.class);
@@ -353,6 +470,9 @@ public class ServerComponentsStarter {
ServerExtensionInstaller extensionRegistrar = pico.getComponentByType(ServerExtensionInstaller.class);
extensionRegistrar.installExtensions(pico);
+
+ pico.startComponents();
+ executeStartupTaks(pico);
}
private void executeStartupTaks(ComponentContainer pico) {
@@ -383,7 +503,6 @@ public class ServerComponentsStarter {
// It would hide the possible exception raised during startup
// See SONAR-3107
startupContainer.stopComponents();
- pico.removeChild();
pico.getComponentByType(DatabaseSessionFactory.class).clear();
}
}
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/ws/RestartHandler.java b/sonar-server/src/main/java/org/sonar/server/platform/ws/RestartHandler.java
index 94312f13377..75b080a21f3 100644
--- a/sonar-server/src/main/java/org/sonar/server/platform/ws/RestartHandler.java
+++ b/sonar-server/src/main/java/org/sonar/server/platform/ws/RestartHandler.java
@@ -51,7 +51,7 @@ public class RestartHandler implements RequestHandler {
if (settings.getBoolean("sonar.dev")) {
Logger logger = LoggerFactory.getLogger(getClass());
logger.info("Restart server");
- platform.restartLevel3Container();
+ platform.restart();
logger.info("Server restarted");
response.noContent();
diff --git a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
index bd8bf72af01..98d8741014d 100644
--- a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
+++ b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
@@ -70,7 +70,6 @@ import static com.google.common.collect.Lists.newArrayList;
public final class JRubyFacade {
private static final JRubyFacade SINGLETON = new JRubyFacade();
- private JRubyI18n i18n;
public static JRubyFacade getInstance() {
return SINGLETON;
@@ -311,10 +310,7 @@ public final class JRubyFacade {
}
private JRubyI18n getJRubyI18n() {
- if (i18n == null) {
- i18n = get(JRubyI18n.class);
- }
- return i18n;
+ return get(JRubyI18n.class);
}
public String getMessage(String rubyLocale, String key, String defaultValue, Object... parameters) {