diff --git a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java index 8b0ea41e7a..5982b803ed 100644 --- a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java +++ b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java @@ -43,6 +43,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.ResultSet; +import com.google.inject.Provider; import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.AssistedInject; @@ -65,8 +66,8 @@ import io.searchbox.core.Search; import io.searchbox.core.search.sort.Sort; import io.searchbox.core.search.sort.Sort.Sorting; -class ElasticAccountIndex extends AbstractElasticIndex - implements AccountIndex { +public class ElasticAccountIndex extends + AbstractElasticIndex implements AccountIndex { static class AccountMapping { MappingProperties accounts; @@ -83,7 +84,7 @@ class ElasticAccountIndex extends AbstractElasticIndex private final Gson gson; private final AccountMapping mapping; - private final AccountCache accountCache; + private final Provider accountCache; private final ElasticQueryBuilder queryBuilder; @AssistedInject @@ -91,7 +92,7 @@ class ElasticAccountIndex extends AbstractElasticIndex @GerritServerConfig Config cfg, FillArgs fillArgs, SitePaths sitePaths, - AccountCache accountCache, + Provider accountCache, @Assisted Schema schema) { super(cfg, fillArgs, sitePaths, schema, ACCOUNTS_PREFIX); this.accountCache = accountCache; @@ -228,7 +229,7 @@ class ElasticAccountIndex extends AbstractElasticIndex // document (of which there shouldn't be any. The most expensive part to // compute anyway is the effective group IDs, and we don't have a good way // to reindex when those change. - return accountCache.get(id); + return accountCache.get().get(id); } } } diff --git a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneAccountIndex.java b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneAccountIndex.java index 87f16082c6..e259155d00 100644 --- a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneAccountIndex.java +++ b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneAccountIndex.java @@ -31,6 +31,7 @@ import com.google.gerrit.server.query.QueryParseException; import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.ResultSet; import com.google.inject.Inject; +import com.google.inject.Provider; import com.google.inject.assistedinject.Assisted; import org.apache.lucene.document.Document; @@ -77,7 +78,7 @@ public class LuceneAccountIndex private final GerritIndexWriterConfig indexWriterConfig; private final QueryBuilder queryBuilder; - private final AccountCache accountCache; + private final Provider accountCache; private static Directory dir(Schema schema, Config cfg, SitePaths sitePaths) throws IOException { @@ -93,7 +94,7 @@ public class LuceneAccountIndex LuceneAccountIndex( @GerritServerConfig Config cfg, SitePaths sitePaths, - AccountCache accountCache, + Provider accountCache, @Assisted Schema schema) throws IOException { super(schema, sitePaths, dir(schema, cfg, sitePaths), ACCOUNTS, null, new GerritIndexWriterConfig(cfg, ACCOUNTS), new SearcherFactory()); @@ -203,6 +204,6 @@ public class LuceneAccountIndex // document (of which there shouldn't be any. The most expensive part to // compute anyway is the effective group IDs, and we don't have a good way // to reindex when those change. - return accountCache.get(id); + return accountCache.get().get(id); } } diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/BaseInit.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/BaseInit.java index 2acc849a59..d9a054c548 100644 --- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/BaseInit.java +++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/BaseInit.java @@ -131,10 +131,18 @@ public class BaseInit extends SiteProgram { init.initializer.run(); init.flags.deleteOnFailure = false; - run = createSiteRun(init); - run.upgradeSchema(); + Injector sysInjector = createSysInjector(init); + IndexManagerOnInit indexManager = + sysInjector.getInstance(IndexManagerOnInit.class); + try { + indexManager.start(); + run = createSiteRun(init); + run.upgradeSchema(); - init.initializer.postRun(createSysInjector(init)); + init.initializer.postRun(sysInjector); + } finally { + indexManager.stop(); + } } catch (Exception | Error failure) { if (init.flags.deleteOnFailure) { recursiveDelete(getSitePath()); @@ -347,7 +355,6 @@ public class BaseInit extends SiteProgram { final SchemaUpdater schemaUpdater; final SchemaFactory schema; final GitRepositoryManager repositoryManager; - final IndexManagerOnInit indexManager; @Inject SiteRun(ConsoleUI ui, @@ -355,50 +362,43 @@ public class BaseInit extends SiteProgram { InitFlags flags, SchemaUpdater schemaUpdater, SchemaFactory schema, - GitRepositoryManager repositoryManager, - IndexManagerOnInit indexManager) { + GitRepositoryManager repositoryManager) { this.ui = ui; this.site = site; this.flags = flags; this.schemaUpdater = schemaUpdater; this.schema = schema; this.repositoryManager = repositoryManager; - this.indexManager = indexManager; } void upgradeSchema() throws OrmException { final List pruneList = new ArrayList<>(); - try { - indexManager.start(); - schemaUpdater.update(new UpdateUI() { - @Override - public void message(String msg) { - System.err.println(msg); - System.err.flush(); - } + schemaUpdater.update(new UpdateUI() { + @Override + public void message(String msg) { + System.err.println(msg); + System.err.flush(); + } - @Override - public boolean yesno(boolean def, String msg) { - return ui.yesno(def, msg); - } + @Override + public boolean yesno(boolean def, String msg) { + return ui.yesno(def, msg); + } - @Override - public boolean isBatch() { - return ui.isBatch(); - } + @Override + public boolean isBatch() { + return ui.isBatch(); + } - @Override - public void pruneSchema(StatementExecutor e, List prune) { - for (String p : prune) { - if (!pruneList.contains(p)) { - pruneList.add(p); - } + @Override + public void pruneSchema(StatementExecutor e, List prune) { + for (String p : prune) { + if (!pruneList.contains(p)) { + pruneList.add(p); } } - }); - } finally { - indexManager.stop(); - } + } + }); if (!pruneList.isEmpty()) { StringBuilder msg = new StringBuilder(); diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitAdminUser.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitAdminUser.java index 136ec5a120..bf46e33a3e 100644 --- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitAdminUser.java +++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitAdminUser.java @@ -29,6 +29,8 @@ import com.google.gerrit.reviewdb.client.AccountGroupMember; import com.google.gerrit.reviewdb.client.AccountGroupName; import com.google.gerrit.reviewdb.client.AccountSshKey; import com.google.gerrit.reviewdb.server.ReviewDb; +import com.google.gerrit.server.account.AccountState; +import com.google.gerrit.server.index.account.AccountIndexCollection; import com.google.gwtorm.server.SchemaFactory; import com.google.inject.Inject; @@ -38,13 +40,17 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; +import java.util.List; public class InitAdminUser implements InitStep { private final ConsoleUI ui; private final InitFlags flags; private final VersionedAuthorizedKeysOnInit.Factory authorizedKeysFactory; private SchemaFactory dbFactory; + private AccountIndexCollection indexCollection; @Inject InitAdminUser( @@ -65,6 +71,11 @@ public class InitAdminUser implements InitStep { this.dbFactory = dbFactory; } + @Inject(optional = true) + void set(AccountIndexCollection indexCollection) { + this.indexCollection = indexCollection; + } + @Override public void postRun() throws Exception { AuthType authType = @@ -84,12 +95,14 @@ public class InitAdminUser implements InitStep { AccountSshKey sshKey = readSshKey(id); String email = readEmail(sshKey); + List extIds = new ArrayList<>(2); AccountExternalId extUser = new AccountExternalId(id, new AccountExternalId.Key( AccountExternalId.SCHEME_USERNAME, username)); if (!Strings.isNullOrEmpty(httpPassword)) { extUser.setPassword(httpPassword); } + extIds.add(extUser); db.accountExternalIds().insert(Collections.singleton(extUser)); if (email != null) { @@ -97,6 +110,7 @@ public class InitAdminUser implements InitStep { new AccountExternalId(id, new AccountExternalId.Key( AccountExternalId.SCHEME_MAILTO, email)); extMailto.setEmailAddress(email); + extIds.add(extMailto); db.accountExternalIds().insert(Collections.singleton(extMailto)); } @@ -105,11 +119,11 @@ public class InitAdminUser implements InitStep { a.setPreferredEmail(email); db.accounts().insert(Collections.singleton(a)); - AccountGroupName adminGroup = db.accountGroupNames().get( + AccountGroupName adminGroupName = db.accountGroupNames().get( new AccountGroup.NameKey("Administrators")); AccountGroupMember m = new AccountGroupMember(new AccountGroupMember.Key(id, - adminGroup.getId())); + adminGroupName.getId())); db.accountGroupMembers().insert(Collections.singleton(m)); if (sshKey != null) { @@ -118,6 +132,13 @@ public class InitAdminUser implements InitStep { authorizedKeys.addKey(sshKey.getSshPublicKey()); authorizedKeys.save("Added SSH key for initial admin user\n"); } + + AccountGroup adminGroup = + db.accountGroups().get(adminGroupName.getId()); + AccountState as = new AccountState(a, + Collections.singleton(adminGroup.getGroupUUID()), extIds, + new HashMap<>()); + indexCollection.getSearchIndex().replace(as); } } } diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/index/IndexModuleOnInit.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/index/IndexModuleOnInit.java index 78691cdf23..7b1d2ebda1 100644 --- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/index/IndexModuleOnInit.java +++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/index/IndexModuleOnInit.java @@ -15,14 +15,20 @@ package com.google.gerrit.pgm.init.index; import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.gerrit.extensions.events.LifecycleListener; +import com.google.gerrit.server.account.AccountCache; import com.google.gerrit.server.account.GroupCache; import com.google.gerrit.server.index.IndexDefinition; import com.google.gerrit.server.index.SchemaDefinitions; import com.google.gerrit.server.index.SingleVersionModule; import com.google.gerrit.server.index.SingleVersionModule.SingleVersionListener; +import com.google.gerrit.server.index.account.AccountIndexCollection; +import com.google.gerrit.server.index.account.AccountIndexDefinition; +import com.google.gerrit.server.index.account.AccountSchemaDefinitions; +import com.google.gerrit.server.index.account.AllAccountsIndexer; import com.google.gerrit.server.index.group.AllGroupsIndexer; import com.google.gerrit.server.index.group.GroupIndexCollection; import com.google.gerrit.server.index.group.GroupIndexDefinition; @@ -41,8 +47,26 @@ import java.util.Set; public class IndexModuleOnInit extends AbstractModule { static final String INDEX_MANAGER = "IndexModuleOnInit/IndexManager"; + private static final ImmutableCollection> ALL_SCHEMA_DEFS = + ImmutableList.> of( + AccountSchemaDefinitions.INSTANCE, + GroupSchemaDefinitions.INSTANCE); + @Override protected void configure() { + // The AccountIndex implementations (LuceneAccountIndex and + // ElasticAccountIndex) need AccountCache only for reading from the index. + // On init we only want to write to the index, hence we don't need the + // account cache. + bind(AccountCache.class).toProvider(Providers.of(null)); + + // AccountIndexDefinition wants to have AllAccountsIndexer but it is only + // used by the Reindex program and the OnlineReindexer which are both not + // used during init, hence we don't need AllAccountsIndexer. + bind(AllAccountsIndexer.class).toProvider(Providers.of(null)); + + bind(AccountIndexCollection.class); + // The GroupIndex implementations (LuceneGroupIndex and ElasticGroupIndex) // need GroupCache only for reading from the index. On init we only want to // write to the index, hence we don't need the group cache. @@ -64,12 +88,14 @@ public class IndexModuleOnInit extends AbstractModule { @Provides Collection> getIndexDefinitions( + AccountIndexDefinition accounts, GroupIndexDefinition groups) { Collection> result = ImmutableList.> of( + accounts, groups); Set expected = - FluentIterable.of(GroupSchemaDefinitions.INSTANCE) + FluentIterable.from(ALL_SCHEMA_DEFS) .transform(SchemaDefinitions::getName) .toSet(); Set actual = FluentIterable.from(result) diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/index/elasticsearch/ElasticIndexModuleOnInit.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/index/elasticsearch/ElasticIndexModuleOnInit.java index c6d7db07a9..7f74c2b88e 100644 --- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/index/elasticsearch/ElasticIndexModuleOnInit.java +++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/index/elasticsearch/ElasticIndexModuleOnInit.java @@ -14,8 +14,10 @@ package com.google.gerrit.pgm.init.index.elasticsearch; +import com.google.gerrit.elasticsearch.ElasticAccountIndex; import com.google.gerrit.elasticsearch.ElasticGroupIndex; import com.google.gerrit.pgm.init.index.IndexModuleOnInit; +import com.google.gerrit.server.index.account.AccountIndex; import com.google.gerrit.server.index.group.GroupIndex; import com.google.inject.AbstractModule; import com.google.inject.assistedinject.FactoryModuleBuilder; @@ -24,6 +26,11 @@ public class ElasticIndexModuleOnInit extends AbstractModule { @Override protected void configure() { + install( + new FactoryModuleBuilder() + .implement(AccountIndex.class, ElasticAccountIndex.class) + .build(AccountIndex.Factory.class)); + install( new FactoryModuleBuilder() .implement(GroupIndex.class, ElasticGroupIndex.class) diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/index/lucene/LuceneIndexModuleOnInit.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/index/lucene/LuceneIndexModuleOnInit.java index c5d81506a4..12a44dc535 100644 --- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/index/lucene/LuceneIndexModuleOnInit.java +++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/index/lucene/LuceneIndexModuleOnInit.java @@ -14,8 +14,10 @@ package com.google.gerrit.pgm.init.index.lucene; +import com.google.gerrit.lucene.LuceneAccountIndex; import com.google.gerrit.lucene.LuceneGroupIndex; import com.google.gerrit.pgm.init.index.IndexModuleOnInit; +import com.google.gerrit.server.index.account.AccountIndex; import com.google.gerrit.server.index.group.GroupIndex; import com.google.inject.AbstractModule; import com.google.inject.assistedinject.FactoryModuleBuilder; @@ -23,6 +25,11 @@ import com.google.inject.assistedinject.FactoryModuleBuilder; public class LuceneIndexModuleOnInit extends AbstractModule { @Override protected void configure() { + install( + new FactoryModuleBuilder() + .implement(AccountIndex.class, LuceneAccountIndex.class) + .build(AccountIndex.Factory.class)); + install( new FactoryModuleBuilder() .implement(GroupIndex.class, LuceneGroupIndex.class) diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/account/AccountIndexDefinition.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/account/AccountIndexDefinition.java index 2771bd4883..31a9250728 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/index/account/AccountIndexDefinition.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/account/AccountIndexDefinition.java @@ -14,6 +14,7 @@ package com.google.gerrit.server.index.account; +import com.google.gerrit.common.Nullable; import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.server.account.AccountState; import com.google.gerrit.server.index.IndexDefinition; @@ -27,7 +28,7 @@ public class AccountIndexDefinition AccountIndexDefinition( AccountIndexCollection indexCollection, AccountIndex.Factory indexFactory, - AllAccountsIndexer allAccountsIndexer) { + @Nullable AllAccountsIndexer allAccountsIndexer) { super(AccountSchemaDefinitions.INSTANCE, indexCollection, indexFactory, Providers.of(allAccountsIndexer)); }