Line data Source code
1 : // Copyright (C) 2009 The Android Open Source Project
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : package com.google.gerrit.pgm;
16 :
17 : import static com.google.gerrit.common.Version.getVersion;
18 : import static java.nio.charset.StandardCharsets.UTF_8;
19 :
20 : import com.google.common.annotations.VisibleForTesting;
21 : import com.google.common.base.Joiner;
22 : import com.google.common.base.MoreObjects;
23 : import com.google.common.flogger.FluentLogger;
24 : import com.google.gerrit.auth.AuthModule;
25 : import com.google.gerrit.common.Nullable;
26 : import com.google.gerrit.extensions.client.AuthType;
27 : import com.google.gerrit.gpg.GpgModule;
28 : import com.google.gerrit.httpd.AllRequestFilter;
29 : import com.google.gerrit.httpd.GerritAuthModule;
30 : import com.google.gerrit.httpd.GetUserFilter.GetUserFilterModule;
31 : import com.google.gerrit.httpd.GitOverHttpModule;
32 : import com.google.gerrit.httpd.H2CacheBasedWebSession;
33 : import com.google.gerrit.httpd.HttpCanonicalWebUrlProvider;
34 : import com.google.gerrit.httpd.HttpdModule;
35 : import com.google.gerrit.httpd.RequestCleanupFilter;
36 : import com.google.gerrit.httpd.RequestContextFilter;
37 : import com.google.gerrit.httpd.RequestMetricsFilter;
38 : import com.google.gerrit.httpd.RequireSslFilter.RequireSslFilterModule;
39 : import com.google.gerrit.httpd.SetThreadNameFilter;
40 : import com.google.gerrit.httpd.WebModule;
41 : import com.google.gerrit.httpd.WebSshGlueModule;
42 : import com.google.gerrit.httpd.auth.oauth.OAuthModule;
43 : import com.google.gerrit.httpd.auth.openid.OpenIdModule;
44 : import com.google.gerrit.httpd.auth.restapi.OAuthRestModule;
45 : import com.google.gerrit.httpd.plugins.HttpPluginModule;
46 : import com.google.gerrit.httpd.raw.StaticModule;
47 : import com.google.gerrit.index.IndexType;
48 : import com.google.gerrit.lifecycle.LifecycleManager;
49 : import com.google.gerrit.lucene.LuceneIndexModule;
50 : import com.google.gerrit.metrics.dropwizard.DropWizardMetricMaker;
51 : import com.google.gerrit.pgm.http.jetty.JettyEnv;
52 : import com.google.gerrit.pgm.http.jetty.JettyModule;
53 : import com.google.gerrit.pgm.http.jetty.ProjectQoSFilter.ProjectQoSFilterModule;
54 : import com.google.gerrit.pgm.util.ErrorLogFile;
55 : import com.google.gerrit.pgm.util.LogFileCompressor.LogFileCompressorModule;
56 : import com.google.gerrit.pgm.util.RuntimeShutdown;
57 : import com.google.gerrit.pgm.util.SiteProgram;
58 : import com.google.gerrit.server.LibModuleLoader;
59 : import com.google.gerrit.server.LibModuleType;
60 : import com.google.gerrit.server.ModuleOverloader;
61 : import com.google.gerrit.server.StartupChecks.StartupChecksModule;
62 : import com.google.gerrit.server.account.AccountDeactivator.AccountDeactivatorModule;
63 : import com.google.gerrit.server.account.InternalAccountDirectory.InternalAccountDirectoryModule;
64 : import com.google.gerrit.server.account.externalids.ExternalIdCaseSensitivityMigrator;
65 : import com.google.gerrit.server.api.GerritApiModule;
66 : import com.google.gerrit.server.api.PluginApiModule;
67 : import com.google.gerrit.server.audit.AuditModule;
68 : import com.google.gerrit.server.cache.h2.H2CacheModule;
69 : import com.google.gerrit.server.cache.mem.DefaultMemoryCacheModule;
70 : import com.google.gerrit.server.change.ChangeCleanupRunner.ChangeCleanupRunnerModule;
71 : import com.google.gerrit.server.config.AuthConfig;
72 : import com.google.gerrit.server.config.AuthConfigModule;
73 : import com.google.gerrit.server.config.CanonicalWebUrlModule;
74 : import com.google.gerrit.server.config.CanonicalWebUrlProvider;
75 : import com.google.gerrit.server.config.DefaultUrlFormatter.DefaultUrlFormatterModule;
76 : import com.google.gerrit.server.config.DownloadConfig;
77 : import com.google.gerrit.server.config.GerritGlobalModule;
78 : import com.google.gerrit.server.config.GerritInstanceIdModule;
79 : import com.google.gerrit.server.config.GerritInstanceNameModule;
80 : import com.google.gerrit.server.config.GerritOptions;
81 : import com.google.gerrit.server.config.GerritRuntime;
82 : import com.google.gerrit.server.config.GerritServerConfig;
83 : import com.google.gerrit.server.config.SysExecutorModule;
84 : import com.google.gerrit.server.events.EventBroker.EventBrokerModule;
85 : import com.google.gerrit.server.events.StreamEventsApiListener.StreamEventsApiListenerModule;
86 : import com.google.gerrit.server.git.GarbageCollectionModule;
87 : import com.google.gerrit.server.git.SearchingChangeCacheImpl.SearchingChangeCacheImplModule;
88 : import com.google.gerrit.server.git.WorkQueue.WorkQueueModule;
89 : import com.google.gerrit.server.group.PeriodicGroupIndexer.PeriodicGroupIndexerModule;
90 : import com.google.gerrit.server.index.AbstractIndexModule;
91 : import com.google.gerrit.server.index.IndexModule;
92 : import com.google.gerrit.server.index.OnlineUpgrader.OnlineUpgraderModule;
93 : import com.google.gerrit.server.index.VersionManager;
94 : import com.google.gerrit.server.index.options.AutoFlush;
95 : import com.google.gerrit.server.mail.SignedTokenEmailTokenVerifier.SignedTokenEmailTokenVerifierModule;
96 : import com.google.gerrit.server.mail.receive.MailReceiver.MailReceiverModule;
97 : import com.google.gerrit.server.mail.send.SmtpEmailSender.SmtpEmailSenderModule;
98 : import com.google.gerrit.server.mime.MimeUtil2Module;
99 : import com.google.gerrit.server.patch.DiffExecutorModule;
100 : import com.google.gerrit.server.permissions.DefaultPermissionBackendModule;
101 : import com.google.gerrit.server.plugins.PluginGuiceEnvironment;
102 : import com.google.gerrit.server.plugins.PluginModule;
103 : import com.google.gerrit.server.project.DefaultProjectNameLockManager.DefaultProjectNameLockManagerModule;
104 : import com.google.gerrit.server.restapi.RestApiModule;
105 : import com.google.gerrit.server.schema.JdbcAccountPatchReviewStore.JdbcAccountPatchReviewStoreModule;
106 : import com.google.gerrit.server.schema.NoteDbSchemaVersionCheck;
107 : import com.google.gerrit.server.securestore.DefaultSecureStore;
108 : import com.google.gerrit.server.securestore.SecureStore;
109 : import com.google.gerrit.server.securestore.SecureStoreClassName;
110 : import com.google.gerrit.server.securestore.SecureStoreProvider;
111 : import com.google.gerrit.server.ssh.NoSshKeyCache;
112 : import com.google.gerrit.server.ssh.NoSshModule;
113 : import com.google.gerrit.server.ssh.SshAddressesModule;
114 : import com.google.gerrit.server.submit.LocalMergeSuperSetComputation.LocalMergeSuperSetComputationModule;
115 : import com.google.gerrit.server.submit.SubscriptionGraph.SubscriptionGraphModule;
116 : import com.google.gerrit.server.update.SuperprojectUpdateSubmissionListener.SuperprojectUpdateSubmissionListenerModule;
117 : import com.google.gerrit.sshd.SshHostKeyModule;
118 : import com.google.gerrit.sshd.SshKeyCacheImpl;
119 : import com.google.gerrit.sshd.SshModule;
120 : import com.google.gerrit.sshd.SshSessionFactoryInitializer;
121 : import com.google.gerrit.sshd.commands.DefaultCommandModule;
122 : import com.google.gerrit.sshd.commands.ExternalIdCommandsModule;
123 : import com.google.gerrit.sshd.commands.IndexCommandsModule;
124 : import com.google.gerrit.sshd.commands.SequenceCommandsModule;
125 : import com.google.gerrit.sshd.plugin.LfsPluginAuthCommand.LfsPluginAuthCommandModule;
126 : import com.google.inject.AbstractModule;
127 : import com.google.inject.Guice;
128 : import com.google.inject.Injector;
129 : import com.google.inject.Key;
130 : import com.google.inject.Module;
131 : import com.google.inject.Provider;
132 : import com.google.inject.Stage;
133 : import java.io.IOException;
134 : import java.lang.reflect.InvocationTargetException;
135 : import java.lang.reflect.Method;
136 : import java.nio.file.Files;
137 : import java.nio.file.Path;
138 : import java.util.ArrayList;
139 : import java.util.Arrays;
140 : import java.util.List;
141 : import javax.servlet.http.HttpServletRequest;
142 : import org.eclipse.jgit.lib.Config;
143 : import org.kohsuke.args4j.Option;
144 :
145 : /** Run SSH daemon portions of Gerrit. */
146 : public class Daemon extends SiteProgram {
147 138 : private static final FluentLogger logger = FluentLogger.forEnclosingClass();
148 :
149 : @Option(name = "--enable-httpd", usage = "Enable the internal HTTP daemon")
150 : private Boolean httpd;
151 :
152 : @Option(name = "--disable-httpd", usage = "Disable the internal HTTP daemon")
153 : void setDisableHttpd(@SuppressWarnings("unused") boolean arg) {
154 0 : httpd = false;
155 0 : }
156 :
157 138 : @Option(name = "--enable-sshd", usage = "Enable the internal SSH daemon")
158 : private boolean sshd = true;
159 :
160 : @Option(name = "--disable-sshd", usage = "Disable the internal SSH daemon")
161 : void setDisableSshd(@SuppressWarnings("unused") boolean arg) {
162 0 : sshd = false;
163 0 : }
164 :
165 : @Option(
166 : name = "--replica",
167 : aliases = {"--slave"},
168 : usage = "Support fetch only")
169 : private boolean replica;
170 :
171 : @Option(name = "--console-log", usage = "Log to console (not $site_path/logs)")
172 : private boolean consoleLog;
173 :
174 : @Option(name = "-s", usage = "Start interactive shell")
175 : private boolean inspector;
176 :
177 : @Option(name = "--run-id", usage = "Cookie to store in $site_path/logs/gerrit.run")
178 : private String runId;
179 :
180 : @Option(name = "--headless", usage = "Don't start the UI frontend")
181 : private boolean headless;
182 :
183 138 : private String devCdn = "";
184 :
185 : @Option(name = "--dev-cdn", usage = "Use specified cdn for serving static content.")
186 : void setDevCdn(String cdn) {
187 0 : if (cdn == null) {
188 0 : cdn = "";
189 : }
190 0 : if (cdn.endsWith("/")) {
191 0 : cdn = cdn.substring(0, cdn.length() - 1);
192 : }
193 0 : devCdn = cdn;
194 0 : }
195 :
196 : @Option(
197 : name = "--init",
198 : aliases = {"-i"},
199 : usage = "Init site before starting the daemon")
200 : private boolean doInit;
201 :
202 : @Option(name = "--stop-only", usage = "Stop the daemon", hidden = true)
203 : private boolean stopOnly;
204 :
205 138 : private final LifecycleManager manager = new LifecycleManager();
206 : private Injector dbInjector;
207 : private Injector cfgInjector;
208 : private Config config;
209 : private Injector sysInjector;
210 : private Injector sshInjector;
211 : private Injector webInjector;
212 : private Injector httpdInjector;
213 : private Path runFile;
214 : private boolean inMemoryTest;
215 : private AbstractModule indexModule;
216 : private Module emailModule;
217 138 : private List<Module> testSysModules = new ArrayList<>();
218 138 : private List<Module> testSshModules = new ArrayList<>();
219 : private Module auditEventModule;
220 :
221 : private Runnable serverStarted;
222 : private IndexType indexType;
223 :
224 0 : public Daemon() {}
225 :
226 : @VisibleForTesting
227 : public Daemon(Runnable serverStarted, Path sitePath) {
228 138 : super(sitePath);
229 138 : this.serverStarted = serverStarted;
230 138 : }
231 :
232 : @VisibleForTesting
233 : public void setEnableSshd(boolean enable) {
234 138 : sshd = enable;
235 138 : }
236 :
237 : @VisibleForTesting
238 : public boolean getEnableSshd() {
239 138 : return sshd;
240 : }
241 :
242 : public void setEnableHttpd(boolean enable) {
243 132 : httpd = enable;
244 132 : }
245 :
246 : public void setReplica(boolean replica) {
247 132 : this.replica = replica;
248 132 : }
249 :
250 : @VisibleForTesting
251 : public Injector getHttpdInjector() {
252 2 : return httpdInjector;
253 : }
254 :
255 : @Override
256 : public int run() throws Exception {
257 15 : if (stopOnly) {
258 0 : RuntimeShutdown.manualShutdown();
259 0 : return 0;
260 : }
261 15 : if (doInit) {
262 : try {
263 0 : new Init(getSitePath()).run();
264 0 : } catch (Exception e) {
265 0 : throw die("Init failed", e);
266 0 : }
267 : }
268 15 : mustHaveValidSite();
269 15 : Thread.setDefaultUncaughtExceptionHandler(
270 1 : (t, e) -> logger.atSevere().withCause(e).log("Thread %s threw exception", t.getName()));
271 :
272 15 : if (runId != null) {
273 0 : runFile = getSitePath().resolve("logs").resolve("gerrit.run");
274 : }
275 :
276 15 : if (httpd == null) {
277 15 : httpd = !replica;
278 : }
279 :
280 15 : if (!httpd && !sshd) {
281 0 : throw die("No services enabled, nothing to do");
282 : }
283 :
284 : try {
285 15 : start();
286 15 : RuntimeShutdown.add(
287 : () -> {
288 13 : logger.atInfo().log("caught shutdown, cleaning up");
289 13 : stop();
290 13 : });
291 :
292 15 : logger.atInfo().log("Gerrit Code Review %s ready", myVersion());
293 15 : if (runId != null) {
294 : try {
295 0 : Files.write(runFile, (runId + "\n").getBytes(UTF_8));
296 0 : runFile.toFile().setReadable(true, false);
297 0 : } catch (IOException err) {
298 0 : logger.atWarning().withCause(err).log("Cannot write --run-id to %s", runFile);
299 0 : }
300 : }
301 :
302 15 : if (serverStarted != null) {
303 15 : serverStarted.run();
304 : }
305 :
306 15 : if (inspector) {
307 0 : JythonShell shell = new JythonShell();
308 0 : shell.set("m", manager);
309 0 : shell.set("d", this);
310 0 : shell.run();
311 0 : } else {
312 15 : RuntimeShutdown.waitFor();
313 : }
314 15 : return 0;
315 1 : } catch (RuntimeException err) {
316 1 : logger.atSevere().withCause(err).log("Unable to start daemon");
317 1 : return 1;
318 : }
319 : }
320 :
321 : @VisibleForTesting
322 : public LifecycleManager getLifecycleManager() {
323 138 : return manager;
324 : }
325 :
326 : @VisibleForTesting
327 : public void setDatabaseForTesting(List<Module> modules) {
328 132 : dbInjector = Guice.createInjector(Stage.PRODUCTION, modules);
329 132 : inMemoryTest = true;
330 132 : headless = true;
331 132 : }
332 :
333 : @VisibleForTesting
334 : public void setEmailModuleForTesting(Module module) {
335 138 : emailModule = module;
336 138 : }
337 :
338 : @VisibleForTesting
339 : public void setAuditEventModuleForTesting(Module module) {
340 138 : auditEventModule = module;
341 138 : }
342 :
343 : @VisibleForTesting
344 : public void setIndexModule(AbstractIndexModule m) {
345 132 : indexModule = m;
346 132 : }
347 :
348 : @VisibleForTesting
349 : public void setInMemory(boolean inMemory) {
350 132 : this.inMemoryTest = inMemory;
351 132 : }
352 :
353 : @VisibleForTesting
354 : public void addAdditionalSysModuleForTesting(@Nullable Module... modules) {
355 138 : testSysModules.addAll(Arrays.asList(modules));
356 138 : }
357 :
358 : @VisibleForTesting
359 : public void addAdditionalSshModuleForTesting(@Nullable Module... modules) {
360 1 : testSshModules.addAll(Arrays.asList(modules));
361 1 : }
362 :
363 : @VisibleForTesting
364 : public void start() throws IOException {
365 138 : if (dbInjector == null) {
366 15 : dbInjector = createDbInjector(true /* enableMetrics */);
367 : }
368 138 : cfgInjector = createCfgInjector();
369 138 : config = cfgInjector.getInstance(Key.get(Config.class, GerritServerConfig.class));
370 138 : indexType = IndexModule.getIndexType(cfgInjector);
371 138 : sysInjector = createSysInjector();
372 138 : sysInjector.getInstance(PluginGuiceEnvironment.class).setDbCfgInjector(dbInjector, cfgInjector);
373 138 : manager.add(dbInjector, cfgInjector, sysInjector);
374 :
375 138 : manager.add(ErrorLogFile.start(getSitePath(), config, consoleLog));
376 :
377 138 : sshd &= !sshdOff();
378 138 : if (sshd) {
379 17 : initSshd();
380 : }
381 :
382 138 : if (MoreObjects.firstNonNull(httpd, true)) {
383 99 : initHttpd();
384 : }
385 :
386 138 : manager.start();
387 138 : }
388 :
389 : @VisibleForTesting
390 : public void stop() {
391 15 : if (runId != null) {
392 : try {
393 0 : Files.delete(runFile);
394 0 : } catch (IOException err) {
395 0 : logger.atWarning().withCause(err).log("failed to delete %s", runFile);
396 0 : }
397 : }
398 15 : manager.stop();
399 15 : }
400 :
401 : @Override
402 : protected GerritRuntime getGerritRuntime() {
403 15 : return GerritRuntime.DAEMON;
404 : }
405 :
406 : private boolean sshdOff() {
407 138 : return new SshAddressesModule().provideListenAddresses(config).isEmpty();
408 : }
409 :
410 : private String myVersion() {
411 15 : List<String> versionParts = new ArrayList<>();
412 15 : if (replica) {
413 0 : versionParts.add("[replica]");
414 : }
415 15 : if (headless) {
416 15 : versionParts.add("[headless]");
417 : }
418 15 : versionParts.add(getVersion());
419 15 : return Joiner.on(" ").join(versionParts);
420 : }
421 :
422 : private Injector createCfgInjector() {
423 138 : final List<Module> modules = new ArrayList<>();
424 138 : modules.add(new AuthConfigModule());
425 138 : return dbInjector.createChildInjector(modules);
426 : }
427 :
428 : private Injector createSysInjector() {
429 138 : final List<Module> modules = new ArrayList<>();
430 138 : modules.add(NoteDbSchemaVersionCheck.module());
431 138 : modules.add(new DropWizardMetricMaker.RestModule());
432 138 : modules.add(new LogFileCompressorModule());
433 :
434 : // Index module shutdown must happen before work queue shutdown, otherwise
435 : // work queue can get stuck waiting on index futures that will never return.
436 138 : modules.add(createIndexModule());
437 :
438 138 : modules.add(new SubscriptionGraphModule());
439 138 : modules.add(new SuperprojectUpdateSubmissionListenerModule());
440 138 : modules.add(new WorkQueueModule());
441 138 : modules.add(new StreamEventsApiListenerModule());
442 138 : modules.add(new EventBrokerModule());
443 138 : modules.add(new JdbcAccountPatchReviewStoreModule(config));
444 138 : modules.add(new SysExecutorModule());
445 138 : modules.add(new DiffExecutorModule());
446 138 : modules.add(new MimeUtil2Module());
447 138 : modules.add(cfgInjector.getInstance(GerritGlobalModule.class));
448 138 : modules.add(new GerritApiModule());
449 138 : modules.add(new PluginApiModule());
450 :
451 138 : modules.add(new SearchingChangeCacheImplModule(replica));
452 138 : modules.add(new InternalAccountDirectoryModule());
453 138 : modules.add(new DefaultPermissionBackendModule());
454 138 : modules.add(new DefaultMemoryCacheModule());
455 138 : modules.add(new H2CacheModule());
456 138 : modules.add(cfgInjector.getInstance(MailReceiverModule.class));
457 138 : if (emailModule != null) {
458 138 : modules.add(emailModule);
459 : } else {
460 0 : modules.add(new SmtpEmailSenderModule());
461 : }
462 138 : if (auditEventModule != null) {
463 138 : modules.add(auditEventModule);
464 : } else {
465 0 : modules.add(new AuditModule());
466 : }
467 138 : modules.add(new SignedTokenEmailTokenVerifierModule());
468 138 : modules.add(new PluginModule());
469 138 : if (VersionManager.getOnlineUpgrade(config)) {
470 15 : modules.add(new OnlineUpgraderModule());
471 : }
472 138 : modules.add(new OAuthRestModule());
473 138 : modules.add(new RestApiModule());
474 138 : modules.add(new GpgModule(config));
475 138 : modules.add(new StartupChecksModule());
476 138 : modules.add(new GerritInstanceNameModule());
477 138 : modules.add(new GerritInstanceIdModule());
478 138 : if (MoreObjects.firstNonNull(httpd, true)) {
479 99 : modules.add(
480 99 : new CanonicalWebUrlModule() {
481 : @Override
482 : protected Class<? extends Provider<String>> provider() {
483 99 : return HttpCanonicalWebUrlProvider.class;
484 : }
485 : });
486 : } else {
487 51 : modules.add(
488 51 : new CanonicalWebUrlModule() {
489 : @Override
490 : protected Class<? extends Provider<String>> provider() {
491 51 : return CanonicalWebUrlProvider.class;
492 : }
493 : });
494 : }
495 138 : modules.add(new DefaultUrlFormatterModule());
496 138 : SshSessionFactoryInitializer.init();
497 138 : if (sshd) {
498 17 : modules.add(SshKeyCacheImpl.module());
499 : } else {
500 127 : modules.add(NoSshKeyCache.module());
501 : }
502 138 : modules.add(
503 138 : new AbstractModule() {
504 : @Override
505 : protected void configure() {
506 138 : bind(GerritOptions.class).toInstance(new GerritOptions(headless, replica, devCdn));
507 138 : if (inMemoryTest) {
508 132 : bind(String.class)
509 132 : .annotatedWith(SecureStoreClassName.class)
510 132 : .toInstance(DefaultSecureStore.class.getName());
511 132 : bind(SecureStore.class).toProvider(SecureStoreProvider.class);
512 : }
513 138 : }
514 : });
515 138 : modules.add(new GarbageCollectionModule());
516 138 : if (replica) {
517 4 : modules.add(new PeriodicGroupIndexerModule());
518 : } else {
519 138 : modules.add(new AccountDeactivatorModule());
520 138 : modules.add(new ChangeCleanupRunnerModule());
521 : }
522 138 : modules.add(new LocalMergeSuperSetComputationModule());
523 138 : modules.add(new DefaultProjectNameLockManagerModule());
524 :
525 138 : List<Module> libModules =
526 138 : LibModuleLoader.loadModules(cfgInjector, LibModuleType.SYS_MODULE_TYPE);
527 138 : libModules.addAll(LibModuleLoader.loadModules(cfgInjector, LibModuleType.INDEX_MODULE_TYPE));
528 138 : libModules.addAll(testSysModules);
529 :
530 138 : AuthConfig authConfig = cfgInjector.getInstance(AuthConfig.class);
531 138 : modules.add(new AuthModule(authConfig));
532 :
533 138 : modules.add(new ExternalIdCaseSensitivityMigrator.ExternalIdCaseSensitivityMigratorModule());
534 :
535 138 : return cfgInjector.createChildInjector(ModuleOverloader.override(modules, libModules));
536 : }
537 :
538 : private Module createIndexModule() {
539 138 : if (indexModule != null) {
540 132 : return indexModule;
541 : }
542 15 : if (indexType.isLucene()) {
543 1 : return LuceneIndexModule.latestVersion(replica, AutoFlush.ENABLED);
544 : }
545 15 : if (indexType.isFake()) {
546 : // Use Reflection so that we can omit the fake index binary in production code. Test code does
547 : // compile the component in.
548 : try {
549 15 : Class<?> clazz = Class.forName("com.google.gerrit.index.testing.FakeIndexModule");
550 15 : Method m = clazz.getMethod("latestVersion", boolean.class);
551 15 : return (Module) m.invoke(null, replica);
552 0 : } catch (NoSuchMethodException
553 : | ClassNotFoundException
554 : | IllegalAccessException
555 : | InvocationTargetException e) {
556 0 : throw new IllegalStateException("can't create index", e);
557 : }
558 : }
559 0 : throw new IllegalStateException("unsupported index.type = " + indexType);
560 : }
561 :
562 : private void initSshd() {
563 17 : sshInjector = createSshInjector();
564 17 : sysInjector.getInstance(PluginGuiceEnvironment.class).setSshInjector(sshInjector);
565 17 : manager.add(sshInjector);
566 17 : }
567 :
568 : private Injector createSshInjector() {
569 17 : final List<Module> modules = new ArrayList<>();
570 17 : modules.add(sysInjector.getInstance(SshModule.class));
571 17 : if (!inMemoryTest) {
572 5 : modules.add(new SshHostKeyModule());
573 : }
574 17 : modules.add(
575 : new DefaultCommandModule(
576 : replica,
577 17 : sysInjector.getInstance(DownloadConfig.class),
578 17 : sysInjector.getInstance(LfsPluginAuthCommandModule.class)));
579 :
580 17 : modules.addAll(testSshModules);
581 17 : if (!replica) {
582 17 : modules.add(new IndexCommandsModule(sysInjector));
583 17 : modules.add(new SequenceCommandsModule());
584 17 : modules.add(new ExternalIdCommandsModule());
585 : }
586 17 : return sysInjector.createChildInjector(modules);
587 : }
588 :
589 : private void initHttpd() {
590 99 : webInjector = createWebInjector();
591 :
592 99 : sysInjector.getInstance(PluginGuiceEnvironment.class).setHttpInjector(webInjector);
593 :
594 99 : sysInjector
595 99 : .getInstance(HttpCanonicalWebUrlProvider.class)
596 99 : .setHttpServletRequest(webInjector.getProvider(HttpServletRequest.class));
597 :
598 99 : httpdInjector = createHttpdInjector();
599 99 : manager.add(webInjector, httpdInjector);
600 99 : }
601 :
602 : private Injector createWebInjector() {
603 99 : final List<Module> modules = new ArrayList<>();
604 99 : modules.add(RequestContextFilter.module());
605 99 : modules.add(RequestMetricsFilter.module());
606 99 : modules.add(H2CacheBasedWebSession.module());
607 99 : modules.add(sysInjector.getInstance(GerritAuthModule.class));
608 99 : modules.add(sysInjector.getInstance(GitOverHttpModule.class));
609 99 : modules.add(sysInjector.getInstance(HttpdModule.class));
610 99 : if (sshd) {
611 11 : modules.add(new ProjectQoSFilterModule());
612 : }
613 99 : modules.add(RequestCleanupFilter.module());
614 99 : modules.add(AllRequestFilter.module());
615 99 : modules.add(SetThreadNameFilter.module());
616 99 : modules.add(sysInjector.getInstance(WebModule.class));
617 99 : modules.add(sysInjector.getInstance(RequireSslFilterModule.class));
618 99 : modules.add(new HttpPluginModule());
619 99 : if (sshd) {
620 11 : modules.add(sshInjector.getInstance(WebSshGlueModule.class));
621 : } else {
622 92 : modules.add(new NoSshModule());
623 : }
624 :
625 99 : AuthConfig authConfig = cfgInjector.getInstance(AuthConfig.class);
626 99 : if (authConfig.getAuthType() == AuthType.OPENID
627 2 : || authConfig.getAuthType() == AuthType.OPENID_SSO) {
628 99 : modules.add(new OpenIdModule());
629 2 : } else if (authConfig.getAuthType() == AuthType.OAUTH) {
630 0 : modules.add(new OAuthModule());
631 : }
632 :
633 99 : modules.add(sysInjector.getInstance(GetUserFilterModule.class));
634 :
635 : // StaticModule contains a "/*" wildcard, place it last.
636 99 : GerritOptions opts = sysInjector.getInstance(GerritOptions.class);
637 99 : if (opts.enableMasterFeatures()) {
638 99 : modules.add(sysInjector.getInstance(StaticModule.class));
639 : }
640 :
641 99 : return sysInjector.createChildInjector(modules);
642 : }
643 :
644 : private Injector createHttpdInjector() {
645 99 : final List<Module> modules = new ArrayList<>();
646 99 : modules.add(new JettyModule(new JettyEnv(webInjector)));
647 99 : return webInjector.createChildInjector(modules);
648 : }
649 : }
|