diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/systemstatus/ServerInformation.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/systemstatus/ServerInformation.java new file mode 100644 index 0000000000..3d2df21226 --- /dev/null +++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/systemstatus/ServerInformation.java @@ -0,0 +1,42 @@ +// Copyright (C) 2012 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.extensions.systemstatus; + +/** Exports current server information to an extension. */ +public interface ServerInformation { + /** Current state of the server. */ + public enum State { + /** + * The server is starting up, and network connections are not yet being + * accepted. Plugins or extensions starting during this time are starting + * for the first time in this process. + */ + STARTUP, + + /** + * The server is running and handling requests. Plugins starting during this + * state may be reloading, or being installed into a running system. + */ + RUNNING, + + /** + * The server is attempting a graceful halt of operations and will exit (or + * be killed by the operating system) soon. + */ + SHUTDOWN; + } + + State getState(); +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/Plugin.java b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/Plugin.java index c47f370494..42587dae4a 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/Plugin.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/Plugin.java @@ -19,6 +19,7 @@ import com.google.common.collect.Lists; import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.registration.RegistrationHandle; import com.google.gerrit.extensions.registration.ReloadableRegistrationHandle; +import com.google.gerrit.extensions.systemstatus.ServerInformation; import com.google.gerrit.lifecycle.LifecycleListener; import com.google.gerrit.lifecycle.LifecycleManager; import com.google.inject.AbstractModule; @@ -165,16 +166,24 @@ public class Plugin { } private Injector newRootInjector(PluginGuiceEnvironment env) { - return Guice.createInjector( - env.getSysModule(), - new AbstractModule() { - @Override - protected void configure() { - bind(String.class) - .annotatedWith(PluginName.class) - .toInstance(name); - } - }); + List modules = Lists.newArrayListWithCapacity(4); + modules.add(env.getSysModule()); + final ServerInformation srvInfo = env.getServerInformation(); + modules.add(new AbstractModule() { + @Override + protected void configure() { + bind(ServerInformation.class).toInstance(srvInfo); + } + }); + modules.add(new AbstractModule() { + @Override + protected void configure() { + bind(String.class) + .annotatedWith(PluginName.class) + .toInstance(name); + } + }); + return Guice.createInjector(modules); } public void stop() { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginGuiceEnvironment.java b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginGuiceEnvironment.java index 1b94c0cabe..782f1edb16 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginGuiceEnvironment.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginGuiceEnvironment.java @@ -24,6 +24,7 @@ import com.google.gerrit.extensions.registration.DynamicSet; import com.google.gerrit.extensions.registration.PrivateInternals_DynamicMapImpl; import com.google.gerrit.extensions.registration.RegistrationHandle; import com.google.gerrit.extensions.registration.ReloadableRegistrationHandle; +import com.google.gerrit.extensions.systemstatus.ServerInformation; import com.google.gerrit.lifecycle.LifecycleListener; import com.google.inject.AbstractModule; import com.google.inject.Binding; @@ -56,6 +57,7 @@ import javax.inject.Inject; @Singleton public class PluginGuiceEnvironment { private final Injector sysInjector; + private final ServerInformation srvInfo; private final CopyConfigModule copyConfigModule; private final List onStart; private final List onReload; @@ -76,8 +78,12 @@ public class PluginGuiceEnvironment { private Map, DynamicMap> httpMaps; @Inject - PluginGuiceEnvironment(Injector sysInjector, CopyConfigModule ccm) { + PluginGuiceEnvironment( + Injector sysInjector, + ServerInformation srvInfo, + CopyConfigModule ccm) { this.sysInjector = sysInjector; + this.srvInfo = srvInfo; this.copyConfigModule = ccm; onStart = new CopyOnWriteArrayList(); @@ -90,6 +96,10 @@ public class PluginGuiceEnvironment { sysMaps = dynamicMapsOf(sysInjector); } + ServerInformation getServerInformation() { + return srvInfo; + } + boolean hasDynamicSet(TypeLiteral type) { return sysSets.containsKey(type) || (sshSets != null && sshSets.containsKey(type)) diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginLoader.java b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginLoader.java index 577a7bb984..ac29c62929 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginLoader.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginLoader.java @@ -17,6 +17,7 @@ package com.google.gerrit.server.plugins; import com.google.common.base.Strings; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import com.google.gerrit.extensions.systemstatus.ServerInformation; import com.google.gerrit.lifecycle.LifecycleListener; import com.google.gerrit.server.config.ConfigUtil; import com.google.gerrit.server.config.GerritServerConfig; @@ -59,6 +60,7 @@ public class PluginLoader implements LifecycleListener { private final File pluginsDir; private final File tmpDir; private final PluginGuiceEnvironment env; + private final ServerInformationImpl srvInfoImpl; private final ConcurrentMap running; private final Map broken; private final ReferenceQueue cleanupQueue; @@ -68,10 +70,12 @@ public class PluginLoader implements LifecycleListener { @Inject public PluginLoader(SitePaths sitePaths, PluginGuiceEnvironment pe, + ServerInformationImpl sii, @GerritServerConfig Config cfg) { pluginsDir = sitePaths.plugins_dir; tmpDir = sitePaths.tmp_dir; env = pe; + srvInfoImpl = sii; running = Maps.newConcurrentMap(); broken = Maps.newHashMap(); cleanupQueue = new ReferenceQueue(); @@ -184,7 +188,9 @@ public class PluginLoader implements LifecycleListener { @Override public synchronized void start() { log.info("Loading plugins from " + pluginsDir.getAbsolutePath()); + srvInfoImpl.state = ServerInformation.State.STARTUP; rescan(false); + srvInfoImpl.state = ServerInformation.State.RUNNING; if (scanner != null) { scanner.start(); } @@ -195,6 +201,7 @@ public class PluginLoader implements LifecycleListener { if (scanner != null) { scanner.end(); } + srvInfoImpl.state = ServerInformation.State.SHUTDOWN; synchronized (this) { boolean clean = !running.isEmpty(); for (Plugin p : running.values()) { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginModule.java b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginModule.java index 0431ee16a9..5f5b8e3633 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginModule.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginModule.java @@ -14,11 +14,15 @@ package com.google.gerrit.server.plugins; +import com.google.gerrit.extensions.systemstatus.ServerInformation; import com.google.gerrit.lifecycle.LifecycleModule; public class PluginModule extends LifecycleModule { @Override protected void configure() { + bind(ServerInformationImpl.class); + bind(ServerInformation.class).to(ServerInformationImpl.class); + bind(PluginGuiceEnvironment.class); bind(PluginLoader.class); bind(CopyConfigModule.class); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/ServerInformationImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/ServerInformationImpl.java new file mode 100644 index 0000000000..c4a89009f1 --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/ServerInformationImpl.java @@ -0,0 +1,28 @@ +// Copyright (C) 2012 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server.plugins; + +import com.google.gerrit.extensions.systemstatus.ServerInformation; +import com.google.inject.Singleton; + +@Singleton +class ServerInformationImpl implements ServerInformation { + volatile State state = State.STARTUP; + + @Override + public State getState() { + return state; + } +}