Base group index on new class InternalGroup

To be able to add the members and sub-groups of a group to the group
index, we need a class which contains those additional details. For
this reason, we introduce a new class InternalGroup and base the
group index on it (instead of AccountGroup).

Change-Id: I88b1a0bf1bd06804069a2a3165e7664db7900903
This commit is contained in:
Alice Kober-Sotzek
2017-08-18 15:04:33 +02:00
parent e7f5e1975f
commit e23b34a206
25 changed files with 326 additions and 106 deletions

View File

@@ -48,6 +48,7 @@ public class GroupDescription {
AccountGroup.Id getId(); AccountGroup.Id getId();
@Nullable
String getDescription(); String getDescription();
AccountGroup.UUID getOwnerGroupUUID(); AccountGroup.UUID getOwnerGroupUUID();

View File

@@ -51,6 +51,7 @@ public class GroupDescriptions {
} }
@Override @Override
@Nullable
public String getDescription() { public String getDescription() {
return group.getDescription(); return group.getDescription();
} }

View File

@@ -27,6 +27,7 @@ import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.account.GroupCache; import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths; import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.index.IndexUtils; import com.google.gerrit.server.index.IndexUtils;
import com.google.gerrit.server.index.group.GroupField; import com.google.gerrit.server.index.group.GroupField;
import com.google.gerrit.server.index.group.GroupIndex; import com.google.gerrit.server.index.group.GroupIndex;
@@ -48,6 +49,7 @@ import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Config;
import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilder;
@@ -55,12 +57,12 @@ import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class ElasticGroupIndex extends AbstractElasticIndex<AccountGroup.UUID, AccountGroup> public class ElasticGroupIndex extends AbstractElasticIndex<AccountGroup.UUID, InternalGroup>
implements GroupIndex { implements GroupIndex {
static class GroupMapping { static class GroupMapping {
MappingProperties groups; MappingProperties groups;
GroupMapping(Schema<AccountGroup> schema) { GroupMapping(Schema<InternalGroup> schema) {
this.groups = ElasticMapping.createMapping(schema); this.groups = ElasticMapping.createMapping(schema);
} }
} }
@@ -79,14 +81,14 @@ public class ElasticGroupIndex extends AbstractElasticIndex<AccountGroup.UUID, A
SitePaths sitePaths, SitePaths sitePaths,
Provider<GroupCache> groupCache, Provider<GroupCache> groupCache,
JestClientBuilder clientBuilder, JestClientBuilder clientBuilder,
@Assisted Schema<AccountGroup> schema) { @Assisted Schema<InternalGroup> schema) {
super(cfg, sitePaths, schema, clientBuilder, GROUPS_PREFIX); super(cfg, sitePaths, schema, clientBuilder, GROUPS_PREFIX);
this.groupCache = groupCache; this.groupCache = groupCache;
this.mapping = new GroupMapping(schema); this.mapping = new GroupMapping(schema);
} }
@Override @Override
public void replace(AccountGroup group) throws IOException { public void replace(InternalGroup group) throws IOException {
Bulk bulk = Bulk bulk =
new Bulk.Builder() new Bulk.Builder()
.defaultIndex(indexName) .defaultIndex(indexName)
@@ -104,7 +106,7 @@ public class ElasticGroupIndex extends AbstractElasticIndex<AccountGroup.UUID, A
} }
@Override @Override
public DataSource<AccountGroup> getSource(Predicate<AccountGroup> p, QueryOptions opts) public DataSource<InternalGroup> getSource(Predicate<InternalGroup> p, QueryOptions opts)
throws QueryParseException { throws QueryParseException {
return new QuerySource(p, opts); return new QuerySource(p, opts);
} }
@@ -121,15 +123,15 @@ public class ElasticGroupIndex extends AbstractElasticIndex<AccountGroup.UUID, A
} }
@Override @Override
protected String getId(AccountGroup group) { protected String getId(InternalGroup group) {
return group.getGroupUUID().get(); return group.getGroupUUID().get();
} }
private class QuerySource implements DataSource<AccountGroup> { private class QuerySource implements DataSource<InternalGroup> {
private final Search search; private final Search search;
private final Set<String> fields; private final Set<String> fields;
QuerySource(Predicate<AccountGroup> p, QueryOptions opts) throws QueryParseException { QuerySource(Predicate<InternalGroup> p, QueryOptions opts) throws QueryParseException {
QueryBuilder qb = queryBuilder.toQueryBuilder(p); QueryBuilder qb = queryBuilder.toQueryBuilder(p);
fields = IndexUtils.groupFields(opts); fields = IndexUtils.groupFields(opts);
SearchSourceBuilder searchSource = SearchSourceBuilder searchSource =
@@ -156,9 +158,9 @@ public class ElasticGroupIndex extends AbstractElasticIndex<AccountGroup.UUID, A
} }
@Override @Override
public ResultSet<AccountGroup> read() throws OrmException { public ResultSet<InternalGroup> read() throws OrmException {
try { try {
List<AccountGroup> results = Collections.emptyList(); List<InternalGroup> results = Collections.emptyList();
JestResult result = client.execute(search); JestResult result = client.execute(search);
if (result.isSucceeded()) { if (result.isSucceeded()) {
JsonObject obj = result.getJsonObject().getAsJsonObject("hits"); JsonObject obj = result.getJsonObject().getAsJsonObject("hits");
@@ -166,21 +168,22 @@ public class ElasticGroupIndex extends AbstractElasticIndex<AccountGroup.UUID, A
JsonArray json = obj.getAsJsonArray("hits"); JsonArray json = obj.getAsJsonArray("hits");
results = Lists.newArrayListWithCapacity(json.size()); results = Lists.newArrayListWithCapacity(json.size());
for (int i = 0; i < json.size(); i++) { for (int i = 0; i < json.size(); i++) {
results.add(toAccountGroup(json.get(i))); Optional<InternalGroup> internalGroup = toInternalGroup(json.get(i));
internalGroup.ifPresent(results::add);
} }
} }
} else { } else {
log.error(result.getErrorMessage()); log.error(result.getErrorMessage());
} }
final List<AccountGroup> r = Collections.unmodifiableList(results); final List<InternalGroup> r = Collections.unmodifiableList(results);
return new ResultSet<AccountGroup>() { return new ResultSet<InternalGroup>() {
@Override @Override
public Iterator<AccountGroup> iterator() { public Iterator<InternalGroup> iterator() {
return r.iterator(); return r.iterator();
} }
@Override @Override
public List<AccountGroup> toList() { public List<InternalGroup> toList() {
return r; return r;
} }
@@ -199,7 +202,7 @@ public class ElasticGroupIndex extends AbstractElasticIndex<AccountGroup.UUID, A
return search.toString(); return search.toString();
} }
private AccountGroup toAccountGroup(JsonElement json) { private Optional<InternalGroup> toInternalGroup(JsonElement json) {
JsonElement source = json.getAsJsonObject().get("_source"); JsonElement source = json.getAsJsonObject().get("_source");
if (source == null) { if (source == null) {
source = json.getAsJsonObject().get("fields"); source = json.getAsJsonObject().get("fields");
@@ -210,7 +213,7 @@ public class ElasticGroupIndex extends AbstractElasticIndex<AccountGroup.UUID, A
source.getAsJsonObject().get(GroupField.UUID.getName()).getAsString()); source.getAsJsonObject().get(GroupField.UUID.getName()).getAsString());
// Use the GroupCache rather than depending on any stored fields in the // Use the GroupCache rather than depending on any stored fields in the
// document (of which there shouldn't be any). // document (of which there shouldn't be any).
return groupCache.get().get(uuid); return groupCache.get().getInternalGroup(uuid);
} }
} }
} }

View File

@@ -27,8 +27,8 @@ import com.google.gerrit.elasticsearch.ElasticAccountIndex.AccountMapping;
import com.google.gerrit.elasticsearch.ElasticChangeIndex.ChangeMapping; import com.google.gerrit.elasticsearch.ElasticChangeIndex.ChangeMapping;
import com.google.gerrit.elasticsearch.ElasticGroupIndex.GroupMapping; import com.google.gerrit.elasticsearch.ElasticGroupIndex.GroupMapping;
import com.google.gerrit.index.Schema; import com.google.gerrit.index.Schema;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.account.AccountState; import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.index.IndexModule.IndexType; import com.google.gerrit.server.index.IndexModule.IndexType;
import com.google.gerrit.server.index.account.AccountSchemaDefinitions; import com.google.gerrit.server.index.account.AccountSchemaDefinitions;
import com.google.gerrit.server.index.change.ChangeSchemaDefinitions; import com.google.gerrit.server.index.change.ChangeSchemaDefinitions;
@@ -146,7 +146,7 @@ final class ElasticTestUtils {
.execute() .execute()
.actionGet(); .actionGet();
Schema<AccountGroup> groupSchema = GroupSchemaDefinitions.INSTANCE.getLatest(); Schema<InternalGroup> groupSchema = GroupSchemaDefinitions.INSTANCE.getLatest();
GroupMapping groupMapping = new GroupMapping(groupSchema); GroupMapping groupMapping = new GroupMapping(groupSchema);
nodeInfo nodeInfo
.node .node

View File

@@ -25,6 +25,7 @@ import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.account.GroupCache; import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths; import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.index.IndexUtils; import com.google.gerrit.server.index.IndexUtils;
import com.google.gerrit.server.index.group.GroupIndex; import com.google.gerrit.server.index.group.GroupIndex;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
@@ -38,6 +39,7 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import org.apache.lucene.document.Document; import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
@@ -55,7 +57,7 @@ import org.eclipse.jgit.lib.Config;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class LuceneGroupIndex extends AbstractLuceneIndex<AccountGroup.UUID, AccountGroup> public class LuceneGroupIndex extends AbstractLuceneIndex<AccountGroup.UUID, InternalGroup>
implements GroupIndex { implements GroupIndex {
private static final Logger log = LoggerFactory.getLogger(LuceneGroupIndex.class); private static final Logger log = LoggerFactory.getLogger(LuceneGroupIndex.class);
@@ -63,7 +65,7 @@ public class LuceneGroupIndex extends AbstractLuceneIndex<AccountGroup.UUID, Acc
private static final String UUID_SORT_FIELD = sortFieldName(UUID); private static final String UUID_SORT_FIELD = sortFieldName(UUID);
private static Term idTerm(AccountGroup group) { private static Term idTerm(InternalGroup group) {
return idTerm(group.getGroupUUID()); return idTerm(group.getGroupUUID());
} }
@@ -72,10 +74,10 @@ public class LuceneGroupIndex extends AbstractLuceneIndex<AccountGroup.UUID, Acc
} }
private final GerritIndexWriterConfig indexWriterConfig; private final GerritIndexWriterConfig indexWriterConfig;
private final QueryBuilder<AccountGroup> queryBuilder; private final QueryBuilder<InternalGroup> queryBuilder;
private final Provider<GroupCache> groupCache; private final Provider<GroupCache> groupCache;
private static Directory dir(Schema<AccountGroup> schema, Config cfg, SitePaths sitePaths) private static Directory dir(Schema<?> schema, Config cfg, SitePaths sitePaths)
throws IOException { throws IOException {
if (LuceneIndexModule.isInMemoryTest(cfg)) { if (LuceneIndexModule.isInMemoryTest(cfg)) {
return new RAMDirectory(); return new RAMDirectory();
@@ -89,7 +91,7 @@ public class LuceneGroupIndex extends AbstractLuceneIndex<AccountGroup.UUID, Acc
@GerritServerConfig Config cfg, @GerritServerConfig Config cfg,
SitePaths sitePaths, SitePaths sitePaths,
Provider<GroupCache> groupCache, Provider<GroupCache> groupCache,
@Assisted Schema<AccountGroup> schema) @Assisted Schema<InternalGroup> schema)
throws IOException { throws IOException {
super( super(
schema, schema,
@@ -106,7 +108,7 @@ public class LuceneGroupIndex extends AbstractLuceneIndex<AccountGroup.UUID, Acc
} }
@Override @Override
public void replace(AccountGroup group) throws IOException { public void replace(InternalGroup group) throws IOException {
try { try {
replace(idTerm(group), toDocument(group)).get(); replace(idTerm(group), toDocument(group)).get();
} catch (ExecutionException | InterruptedException e) { } catch (ExecutionException | InterruptedException e) {
@@ -124,7 +126,7 @@ public class LuceneGroupIndex extends AbstractLuceneIndex<AccountGroup.UUID, Acc
} }
@Override @Override
public DataSource<AccountGroup> getSource(Predicate<AccountGroup> p, QueryOptions opts) public DataSource<InternalGroup> getSource(Predicate<InternalGroup> p, QueryOptions opts)
throws QueryParseException { throws QueryParseException {
return new QuerySource( return new QuerySource(
opts, opts,
@@ -132,7 +134,7 @@ public class LuceneGroupIndex extends AbstractLuceneIndex<AccountGroup.UUID, Acc
new Sort(new SortField(UUID_SORT_FIELD, SortField.Type.STRING, false))); new Sort(new SortField(UUID_SORT_FIELD, SortField.Type.STRING, false)));
} }
private class QuerySource implements DataSource<AccountGroup> { private class QuerySource implements DataSource<InternalGroup> {
private final QueryOptions opts; private final QueryOptions opts;
private final Query query; private final Query query;
private final Sort sort; private final Sort sort;
@@ -149,27 +151,28 @@ public class LuceneGroupIndex extends AbstractLuceneIndex<AccountGroup.UUID, Acc
} }
@Override @Override
public ResultSet<AccountGroup> read() throws OrmException { public ResultSet<InternalGroup> read() throws OrmException {
IndexSearcher searcher = null; IndexSearcher searcher = null;
try { try {
searcher = acquire(); searcher = acquire();
int realLimit = opts.start() + opts.limit(); int realLimit = opts.start() + opts.limit();
TopFieldDocs docs = searcher.search(query, realLimit, sort); TopFieldDocs docs = searcher.search(query, realLimit, sort);
List<AccountGroup> result = new ArrayList<>(docs.scoreDocs.length); List<InternalGroup> result = new ArrayList<>(docs.scoreDocs.length);
for (int i = opts.start(); i < docs.scoreDocs.length; i++) { for (int i = opts.start(); i < docs.scoreDocs.length; i++) {
ScoreDoc sd = docs.scoreDocs[i]; ScoreDoc sd = docs.scoreDocs[i];
Document doc = searcher.doc(sd.doc, IndexUtils.groupFields(opts)); Document doc = searcher.doc(sd.doc, IndexUtils.groupFields(opts));
result.add(toAccountGroup(doc)); Optional<InternalGroup> internalGroup = toInternalGroup(doc);
internalGroup.ifPresent(result::add);
} }
final List<AccountGroup> r = Collections.unmodifiableList(result); final List<InternalGroup> r = Collections.unmodifiableList(result);
return new ResultSet<AccountGroup>() { return new ResultSet<InternalGroup>() {
@Override @Override
public Iterator<AccountGroup> iterator() { public Iterator<InternalGroup> iterator() {
return r.iterator(); return r.iterator();
} }
@Override @Override
public List<AccountGroup> toList() { public List<InternalGroup> toList() {
return r; return r;
} }
@@ -192,10 +195,10 @@ public class LuceneGroupIndex extends AbstractLuceneIndex<AccountGroup.UUID, Acc
} }
} }
private AccountGroup toAccountGroup(Document doc) { private Optional<InternalGroup> toInternalGroup(Document doc) {
AccountGroup.UUID uuid = new AccountGroup.UUID(doc.getField(UUID.getName()).stringValue()); AccountGroup.UUID uuid = new AccountGroup.UUID(doc.getField(UUID.getName()).stringValue());
// Use the GroupCache rather than depending on any stored fields in the // Use the GroupCache rather than depending on any stored fields in the
// document (of which there shouldn't be any). // document (of which there shouldn't be any).
return groupCache.get().get(uuid); return groupCache.get().getInternalGroup(uuid);
} }
} }

View File

@@ -17,7 +17,9 @@ package com.google.gerrit.server.account;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.gerrit.common.Nullable; import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.group.InternalGroup;
import java.io.IOException; import java.io.IOException;
import java.util.Optional;
/** Tracks group objects in memory for efficient access. */ /** Tracks group objects in memory for efficient access. */
public interface GroupCache { public interface GroupCache {
@@ -32,6 +34,15 @@ public interface GroupCache {
@Nullable @Nullable
AccountGroup get(AccountGroup.UUID uuid); AccountGroup get(AccountGroup.UUID uuid);
/**
* Looks up an internal group by its UUID.
*
* @param groupUuid the UUID of the internal group
* @return an {@code Optional} of the internal group, or an empty {@code Optional} if no internal
* group with this UUID exists on this server or an error occurred during lookup
*/
Optional<InternalGroup> getInternalGroup(AccountGroup.UUID groupUuid);
/** @return sorted list of groups. */ /** @return sorted list of groups. */
ImmutableList<AccountGroup> all(); ImmutableList<AccountGroup> all();

View File

@@ -15,15 +15,20 @@
package com.google.gerrit.server.account; package com.google.gerrit.server.account;
import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.common.TimeUtil; import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.cache.CacheModule; import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.group.Groups; import com.google.gerrit.server.group.Groups;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.index.group.GroupIndexer; import com.google.gerrit.server.index.group.GroupIndexer;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory; import com.google.gwtorm.server.SchemaFactory;
@@ -148,11 +153,40 @@ public class GroupCacheImpl implements GroupCache {
try { try {
return byUUID.get(uuid.get()).orElse(null); return byUUID.get(uuid.get()).orElse(null);
} catch (ExecutionException e) { } catch (ExecutionException e) {
log.warn(String.format("Cannot lookup group %s by name", uuid.get()), e); log.warn(String.format("Cannot lookup group %s by uuid", uuid.get()), e);
return null; return null;
} }
} }
@Override
public Optional<InternalGroup> getInternalGroup(AccountGroup.UUID groupUuid) {
if (groupUuid == null) {
return Optional.empty();
}
Optional<AccountGroup> accountGroup = Optional.empty();
try {
accountGroup = byUUID.get(groupUuid.get());
} catch (ExecutionException e) {
log.warn(String.format("Cannot lookup group %s by uuid", groupUuid.get()), e);
}
if (!accountGroup.isPresent()) {
return Optional.empty();
}
try (ReviewDb db = schema.open()) {
ImmutableSet<Account.Id> members = groups.getMembers(db, groupUuid).collect(toImmutableSet());
ImmutableSet<AccountGroup.UUID> includes =
groups.getIncludes(db, groupUuid).collect(toImmutableSet());
return accountGroup.map(group -> InternalGroup.create(group, members, includes));
} catch (OrmException | NoSuchGroupException e) {
log.warn(
String.format("Cannot lookup members or sub-groups of group %s", groupUuid.get()), e);
}
return Optional.empty();
}
@Override @Override
public ImmutableList<AccountGroup> all() { public ImmutableList<AccountGroup> all() {
try (ReviewDb db = schema.open()) { try (ReviewDb db = schema.open()) {

View File

@@ -0,0 +1,65 @@
// Copyright (C) 2017 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.group;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
import java.sql.Timestamp;
@AutoValue
public abstract class InternalGroup {
public static InternalGroup create(
AccountGroup accountGroup,
ImmutableSet<Account.Id> members,
ImmutableSet<AccountGroup.UUID> includes) {
return new AutoValue_InternalGroup(
accountGroup.getId(),
accountGroup.getNameKey(),
accountGroup.getDescription(),
accountGroup.getOwnerGroupUUID(),
accountGroup.isVisibleToAll(),
accountGroup.getGroupUUID(),
accountGroup.getCreatedOn(),
members,
includes);
}
public abstract AccountGroup.Id getId();
public String getName() {
return getNameKey().get();
}
public abstract AccountGroup.NameKey getNameKey();
@Nullable
public abstract String getDescription();
public abstract AccountGroup.UUID getOwnerGroupUUID();
public abstract boolean isVisibleToAll();
public abstract AccountGroup.UUID getGroupUUID();
public abstract Timestamp getCreatedOn();
public abstract ImmutableSet<Account.Id> getMembers();
public abstract ImmutableSet<AccountGroup.UUID> getIncludes();
}

View File

@@ -0,0 +1,80 @@
// Copyright (C) 2017 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.group;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.GroupDescription;
import com.google.gerrit.reviewdb.client.AccountGroup;
import java.sql.Timestamp;
public class InternalGroupDescription implements GroupDescription.Internal {
private final InternalGroup internalGroup;
public InternalGroupDescription(InternalGroup internalGroup) {
this.internalGroup = checkNotNull(internalGroup);
}
@Override
public AccountGroup.UUID getGroupUUID() {
return internalGroup.getGroupUUID();
}
@Override
public String getName() {
return internalGroup.getName();
}
@Nullable
@Override
public String getEmailAddress() {
return null;
}
@Nullable
@Override
public String getUrl() {
return "#" + PageLinks.toGroup(getGroupUUID());
}
@Override
public AccountGroup.Id getId() {
return internalGroup.getId();
}
@Override
@Nullable
public String getDescription() {
return internalGroup.getDescription();
}
@Override
public AccountGroup.UUID getOwnerGroupUUID() {
return internalGroup.getOwnerGroupUUID();
}
@Override
public boolean isVisibleToAll() {
return internalGroup.isVisibleToAll();
}
@Override
public Timestamp getCreatedOn() {
return internalGroup.getCreatedOn();
}
}

View File

@@ -16,7 +16,6 @@ package com.google.gerrit.server.group;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.gerrit.common.data.GroupDescriptions;
import com.google.gerrit.extensions.client.ListGroupsOption; import com.google.gerrit.extensions.client.ListGroupsOption;
import com.google.gerrit.extensions.common.GroupInfo; import com.google.gerrit.extensions.common.GroupInfo;
import com.google.gerrit.extensions.restapi.BadRequestException; import com.google.gerrit.extensions.restapi.BadRequestException;
@@ -25,7 +24,6 @@ import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.extensions.restapi.TopLevelResource; import com.google.gerrit.extensions.restapi.TopLevelResource;
import com.google.gerrit.index.query.QueryParseException; import com.google.gerrit.index.query.QueryParseException;
import com.google.gerrit.index.query.QueryResult; import com.google.gerrit.index.query.QueryResult;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.index.group.GroupIndex; import com.google.gerrit.server.index.group.GroupIndex;
import com.google.gerrit.server.index.group.GroupIndexCollection; import com.google.gerrit.server.index.group.GroupIndexCollection;
import com.google.gerrit.server.query.group.GroupQueryBuilder; import com.google.gerrit.server.query.group.GroupQueryBuilder;
@@ -123,13 +121,13 @@ public class QueryGroups implements RestReadView<TopLevelResource> {
} }
try { try {
QueryResult<AccountGroup> result = queryProcessor.query(queryBuilder.parse(query)); QueryResult<InternalGroup> result = queryProcessor.query(queryBuilder.parse(query));
List<AccountGroup> groups = result.entities(); List<InternalGroup> groups = result.entities();
ArrayList<GroupInfo> groupInfos = Lists.newArrayListWithCapacity(groups.size()); ArrayList<GroupInfo> groupInfos = Lists.newArrayListWithCapacity(groups.size());
json.addOptions(options); json.addOptions(options);
for (AccountGroup group : groups) { for (InternalGroup group : groups) {
groupInfos.add(json.format(GroupDescriptions.forAccountGroup(group))); groupInfos.add(json.format(new InternalGroupDescription(group)));
} }
if (!groupInfos.isEmpty() && result.more()) { if (!groupInfos.isEmpty() && result.more()) {
groupInfos.get(groupInfos.size() - 1)._moreGroups = true; groupInfos.get(groupInfos.size() - 1)._moreGroups = true;

View File

@@ -17,8 +17,8 @@ package com.google.gerrit.server.index;
import com.google.gerrit.index.Index; import com.google.gerrit.index.Index;
import com.google.gerrit.index.IndexConfig; import com.google.gerrit.index.IndexConfig;
import com.google.gerrit.index.Schema; import com.google.gerrit.index.Schema;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.account.AccountState; import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.index.account.AccountIndex; import com.google.gerrit.server.index.account.AccountIndex;
import com.google.gerrit.server.index.change.ChangeIndex; import com.google.gerrit.server.index.change.ChangeIndex;
import com.google.gerrit.server.index.change.DummyChangeIndex; import com.google.gerrit.server.index.change.DummyChangeIndex;
@@ -43,7 +43,7 @@ public class DummyIndexModule extends AbstractModule {
private static class DummyGroupIndexFactory implements GroupIndex.Factory { private static class DummyGroupIndexFactory implements GroupIndex.Factory {
@Override @Override
public GroupIndex create(Schema<AccountGroup> schema) { public GroupIndex create(Schema<InternalGroup> schema) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
} }

View File

@@ -26,6 +26,7 @@ import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.account.GroupCache; import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.group.Groups; import com.google.gerrit.server.group.Groups;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.index.IndexExecutor; import com.google.gerrit.server.index.IndexExecutor;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory; import com.google.gwtorm.server.SchemaFactory;
@@ -34,6 +35,7 @@ import com.google.inject.Singleton;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@@ -43,7 +45,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@Singleton @Singleton
public class AllGroupsIndexer extends SiteIndexer<AccountGroup.UUID, AccountGroup, GroupIndex> { public class AllGroupsIndexer extends SiteIndexer<AccountGroup.UUID, InternalGroup, GroupIndex> {
private static final Logger log = LoggerFactory.getLogger(AllGroupsIndexer.class); private static final Logger log = LoggerFactory.getLogger(AllGroupsIndexer.class);
private final SchemaFactory<ReviewDb> schemaFactory; private final SchemaFactory<ReviewDb> schemaFactory;
@@ -96,7 +98,12 @@ public class AllGroupsIndexer extends SiteIndexer<AccountGroup.UUID, AccountGrou
if (oldGroup != null) { if (oldGroup != null) {
groupCache.evict(oldGroup); groupCache.evict(oldGroup);
} }
index.replace(groupCache.get(uuid)); Optional<InternalGroup> internalGroup = groupCache.getInternalGroup(uuid);
if (internalGroup.isPresent()) {
index.replace(internalGroup.get());
} else {
index.delete(uuid);
}
verboseWriter.println("Reindexed " + desc); verboseWriter.println("Reindexed " + desc);
done.incrementAndGet(); done.incrementAndGet();
} catch (Exception e) { } catch (Exception e) {

View File

@@ -22,40 +22,40 @@ import static com.google.gerrit.index.FieldDef.timestamp;
import com.google.gerrit.index.FieldDef; import com.google.gerrit.index.FieldDef;
import com.google.gerrit.index.SchemaUtil; import com.google.gerrit.index.SchemaUtil;
import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.server.group.InternalGroup;
import java.sql.Timestamp; import java.sql.Timestamp;
/** Secondary index schemas for groups. */ /** Secondary index schemas for groups. */
public class GroupField { public class GroupField {
/** Legacy group ID. */ /** Legacy group ID. */
public static final FieldDef<AccountGroup, Integer> ID = public static final FieldDef<InternalGroup, Integer> ID =
integer("id").build(g -> g.getId().get()); integer("id").build(g -> g.getId().get());
/** Group UUID. */ /** Group UUID. */
public static final FieldDef<AccountGroup, String> UUID = public static final FieldDef<InternalGroup, String> UUID =
exact("uuid").stored().build(g -> g.getGroupUUID().get()); exact("uuid").stored().build(g -> g.getGroupUUID().get());
/** Group owner UUID. */ /** Group owner UUID. */
public static final FieldDef<AccountGroup, String> OWNER_UUID = public static final FieldDef<InternalGroup, String> OWNER_UUID =
exact("owner_uuid").build(g -> g.getOwnerGroupUUID().get()); exact("owner_uuid").build(g -> g.getOwnerGroupUUID().get());
/** Timestamp indicating when this group was created. */ /** Timestamp indicating when this group was created. */
public static final FieldDef<AccountGroup, Timestamp> CREATED_ON = public static final FieldDef<InternalGroup, Timestamp> CREATED_ON =
timestamp("created_on").build(AccountGroup::getCreatedOn); timestamp("created_on").build(InternalGroup::getCreatedOn);
/** Group name. */ /** Group name. */
public static final FieldDef<AccountGroup, String> NAME = public static final FieldDef<InternalGroup, String> NAME =
exact("name").build(AccountGroup::getName); exact("name").build(InternalGroup::getName);
/** Prefix match on group name parts. */ /** Prefix match on group name parts. */
public static final FieldDef<AccountGroup, Iterable<String>> NAME_PART = public static final FieldDef<InternalGroup, Iterable<String>> NAME_PART =
prefix("name_part").buildRepeatable(g -> SchemaUtil.getNameParts(g.getName())); prefix("name_part").buildRepeatable(g -> SchemaUtil.getNameParts(g.getName()));
/** Group description. */ /** Group description. */
public static final FieldDef<AccountGroup, String> DESCRIPTION = public static final FieldDef<InternalGroup, String> DESCRIPTION =
fullText("description").build(AccountGroup::getDescription); fullText("description").build(InternalGroup::getDescription);
/** Whether the group is visible to all users. */ /** Whether the group is visible to all users. */
public static final FieldDef<AccountGroup, String> IS_VISIBLE_TO_ALL = public static final FieldDef<InternalGroup, String> IS_VISIBLE_TO_ALL =
exact("is_visible_to_all").build(g -> g.isVisibleToAll() ? "1" : "0"); exact("is_visible_to_all").build(g -> g.isVisibleToAll() ? "1" : "0");
} }

View File

@@ -18,14 +18,15 @@ import com.google.gerrit.index.Index;
import com.google.gerrit.index.IndexDefinition; import com.google.gerrit.index.IndexDefinition;
import com.google.gerrit.index.query.Predicate; import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.query.group.GroupPredicates; import com.google.gerrit.server.query.group.GroupPredicates;
public interface GroupIndex extends Index<AccountGroup.UUID, AccountGroup> { public interface GroupIndex extends Index<AccountGroup.UUID, InternalGroup> {
public interface Factory public interface Factory
extends IndexDefinition.IndexFactory<AccountGroup.UUID, AccountGroup, GroupIndex> {} extends IndexDefinition.IndexFactory<AccountGroup.UUID, InternalGroup, GroupIndex> {}
@Override @Override
default Predicate<AccountGroup> keyPredicate(AccountGroup.UUID uuid) { default Predicate<InternalGroup> keyPredicate(AccountGroup.UUID uuid) {
return GroupPredicates.uuid(uuid); return GroupPredicates.uuid(uuid);
} }
} }

View File

@@ -17,11 +17,12 @@ package com.google.gerrit.server.index.group;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.gerrit.index.IndexCollection; import com.google.gerrit.index.IndexCollection;
import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.group.InternalGroup;
import com.google.inject.Singleton; import com.google.inject.Singleton;
@Singleton @Singleton
public class GroupIndexCollection public class GroupIndexCollection
extends IndexCollection<AccountGroup.UUID, AccountGroup, GroupIndex> { extends IndexCollection<AccountGroup.UUID, InternalGroup, GroupIndex> {
@VisibleForTesting @VisibleForTesting
public GroupIndexCollection() {} public GroupIndexCollection() {}
} }

View File

@@ -17,10 +17,11 @@ package com.google.gerrit.server.index.group;
import com.google.gerrit.common.Nullable; import com.google.gerrit.common.Nullable;
import com.google.gerrit.index.IndexDefinition; import com.google.gerrit.index.IndexDefinition;
import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.group.InternalGroup;
import com.google.inject.Inject; import com.google.inject.Inject;
public class GroupIndexDefinition public class GroupIndexDefinition
extends IndexDefinition<AccountGroup.UUID, AccountGroup, GroupIndex> { extends IndexDefinition<AccountGroup.UUID, InternalGroup, GroupIndex> {
@Inject @Inject
GroupIndexDefinition( GroupIndexDefinition(

View File

@@ -20,12 +20,12 @@ import com.google.gerrit.index.IndexRewriter;
import com.google.gerrit.index.QueryOptions; import com.google.gerrit.index.QueryOptions;
import com.google.gerrit.index.query.Predicate; import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.index.query.QueryParseException; import com.google.gerrit.index.query.QueryParseException;
import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.server.group.InternalGroup;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
@Singleton @Singleton
public class GroupIndexRewriter implements IndexRewriter<AccountGroup> { public class GroupIndexRewriter implements IndexRewriter<InternalGroup> {
private final GroupIndexCollection indexes; private final GroupIndexCollection indexes;
@Inject @Inject
@@ -34,7 +34,7 @@ public class GroupIndexRewriter implements IndexRewriter<AccountGroup> {
} }
@Override @Override
public Predicate<AccountGroup> rewrite(Predicate<AccountGroup> in, QueryOptions opts) public Predicate<InternalGroup> rewrite(Predicate<InternalGroup> in, QueryOptions opts)
throws QueryParseException { throws QueryParseException {
GroupIndex index = indexes.getSearchIndex(); GroupIndex index = indexes.getSearchIndex();
checkNotNull(index, "no active search index configured for groups"); checkNotNull(index, "no active search index configured for groups");

View File

@@ -21,11 +21,13 @@ import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.index.Index; import com.google.gerrit.index.Index;
import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.account.GroupCache; import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.group.InternalGroup;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject; import com.google.inject.assistedinject.AssistedInject;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Optional;
public class GroupIndexerImpl implements GroupIndexer { public class GroupIndexerImpl implements GroupIndexer {
public interface Factory { public interface Factory {
@@ -63,8 +65,13 @@ public class GroupIndexerImpl implements GroupIndexer {
@Override @Override
public void index(AccountGroup.UUID uuid) throws IOException { public void index(AccountGroup.UUID uuid) throws IOException {
for (Index<?, AccountGroup> i : getWriteIndexes()) { for (Index<AccountGroup.UUID, InternalGroup> i : getWriteIndexes()) {
i.replace(groupCache.get(uuid)); Optional<InternalGroup> internalGroup = groupCache.getInternalGroup(uuid);
if (internalGroup.isPresent()) {
i.replace(internalGroup.get());
} else {
i.delete(uuid);
}
} }
fireGroupIndexedEvent(uuid.get()); fireGroupIndexedEvent(uuid.get());
} }

View File

@@ -18,11 +18,11 @@ import static com.google.gerrit.index.SchemaUtil.schema;
import com.google.gerrit.index.Schema; import com.google.gerrit.index.Schema;
import com.google.gerrit.index.SchemaDefinitions; import com.google.gerrit.index.SchemaDefinitions;
import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.server.group.InternalGroup;
public class GroupSchemaDefinitions extends SchemaDefinitions<AccountGroup> { public class GroupSchemaDefinitions extends SchemaDefinitions<InternalGroup> {
@Deprecated @Deprecated
static final Schema<AccountGroup> V2 = static final Schema<InternalGroup> V2 =
schema( schema(
GroupField.DESCRIPTION, GroupField.DESCRIPTION,
GroupField.ID, GroupField.ID,
@@ -32,11 +32,11 @@ public class GroupSchemaDefinitions extends SchemaDefinitions<AccountGroup> {
GroupField.OWNER_UUID, GroupField.OWNER_UUID,
GroupField.UUID); GroupField.UUID);
static final Schema<AccountGroup> V3 = schema(V2, GroupField.CREATED_ON); static final Schema<InternalGroup> V3 = schema(V2, GroupField.CREATED_ON);
public static final GroupSchemaDefinitions INSTANCE = new GroupSchemaDefinitions(); public static final GroupSchemaDefinitions INSTANCE = new GroupSchemaDefinitions();
private GroupSchemaDefinitions() { private GroupSchemaDefinitions() {
super("groups", AccountGroup.class); super("groups", InternalGroup.class);
} }
} }

View File

@@ -21,12 +21,15 @@ import com.google.gerrit.index.query.DataSource;
import com.google.gerrit.index.query.Predicate; import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.index.query.QueryParseException; import com.google.gerrit.index.query.QueryParseException;
import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.group.InternalGroup;
public class IndexedGroupQuery extends IndexedQuery<AccountGroup.UUID, AccountGroup> public class IndexedGroupQuery extends IndexedQuery<AccountGroup.UUID, InternalGroup>
implements DataSource<AccountGroup> { implements DataSource<InternalGroup> {
public IndexedGroupQuery( public IndexedGroupQuery(
Index<AccountGroup.UUID, AccountGroup> index, Predicate<AccountGroup> pred, QueryOptions opts) Index<AccountGroup.UUID, InternalGroup> index,
Predicate<InternalGroup> pred,
QueryOptions opts)
throws QueryParseException { throws QueryParseException {
super(index, pred, opts.convertForBackend()); super(index, pred, opts.convertForBackend());
} }

View File

@@ -16,14 +16,14 @@ package com.google.gerrit.server.query.group;
import com.google.gerrit.common.errors.NoSuchGroupException; import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.index.query.IsVisibleToPredicate; import com.google.gerrit.index.query.IsVisibleToPredicate;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.GroupControl; import com.google.gerrit.server.account.GroupControl;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.index.IndexUtils; import com.google.gerrit.server.index.IndexUtils;
import com.google.gerrit.server.query.account.AccountQueryBuilder; import com.google.gerrit.server.query.account.AccountQueryBuilder;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
public class GroupIsVisibleToPredicate extends IsVisibleToPredicate<AccountGroup> { public class GroupIsVisibleToPredicate extends IsVisibleToPredicate<InternalGroup> {
protected final GroupControl.GenericFactory groupControlFactory; protected final GroupControl.GenericFactory groupControlFactory;
protected final CurrentUser user; protected final CurrentUser user;
@@ -35,7 +35,7 @@ public class GroupIsVisibleToPredicate extends IsVisibleToPredicate<AccountGroup
} }
@Override @Override
public boolean match(AccountGroup group) throws OrmException { public boolean match(InternalGroup group) throws OrmException {
try { try {
return groupControlFactory.controlFor(user, group.getGroupUUID()).isVisible(); return groupControlFactory.controlFor(user, group.getGroupUUID()).isVisible();
} catch (NoSuchGroupException e) { } catch (NoSuchGroupException e) {

View File

@@ -18,43 +18,44 @@ import com.google.gerrit.index.FieldDef;
import com.google.gerrit.index.query.IndexPredicate; import com.google.gerrit.index.query.IndexPredicate;
import com.google.gerrit.index.query.Predicate; import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.index.group.GroupField; import com.google.gerrit.server.index.group.GroupField;
import java.util.Locale; import java.util.Locale;
public class GroupPredicates { public class GroupPredicates {
public static Predicate<AccountGroup> uuid(AccountGroup.UUID uuid) { public static Predicate<InternalGroup> uuid(AccountGroup.UUID uuid) {
return new GroupPredicate(GroupField.UUID, GroupQueryBuilder.FIELD_UUID, uuid.get()); return new GroupPredicate(GroupField.UUID, GroupQueryBuilder.FIELD_UUID, uuid.get());
} }
public static Predicate<AccountGroup> description(String description) { public static Predicate<InternalGroup> description(String description) {
return new GroupPredicate( return new GroupPredicate(
GroupField.DESCRIPTION, GroupQueryBuilder.FIELD_DESCRIPTION, description); GroupField.DESCRIPTION, GroupQueryBuilder.FIELD_DESCRIPTION, description);
} }
public static Predicate<AccountGroup> inname(String name) { public static Predicate<InternalGroup> inname(String name) {
return new GroupPredicate( return new GroupPredicate(
GroupField.NAME_PART, GroupQueryBuilder.FIELD_INNAME, name.toLowerCase(Locale.US)); GroupField.NAME_PART, GroupQueryBuilder.FIELD_INNAME, name.toLowerCase(Locale.US));
} }
public static Predicate<AccountGroup> name(String name) { public static Predicate<InternalGroup> name(String name) {
return new GroupPredicate(GroupField.NAME, GroupQueryBuilder.FIELD_NAME, name); return new GroupPredicate(GroupField.NAME, GroupQueryBuilder.FIELD_NAME, name);
} }
public static Predicate<AccountGroup> owner(AccountGroup.UUID ownerUuid) { public static Predicate<InternalGroup> owner(AccountGroup.UUID ownerUuid) {
return new GroupPredicate( return new GroupPredicate(
GroupField.OWNER_UUID, GroupQueryBuilder.FIELD_OWNER, ownerUuid.get()); GroupField.OWNER_UUID, GroupQueryBuilder.FIELD_OWNER, ownerUuid.get());
} }
public static Predicate<AccountGroup> isVisibleToAll() { public static Predicate<InternalGroup> isVisibleToAll() {
return new GroupPredicate(GroupField.IS_VISIBLE_TO_ALL, "1"); return new GroupPredicate(GroupField.IS_VISIBLE_TO_ALL, "1");
} }
static class GroupPredicate extends IndexPredicate<AccountGroup> { static class GroupPredicate extends IndexPredicate<InternalGroup> {
GroupPredicate(FieldDef<AccountGroup, ?> def, String value) { GroupPredicate(FieldDef<InternalGroup, ?> def, String value) {
super(def, value); super(def, value);
} }
GroupPredicate(FieldDef<AccountGroup, ?> def, String name, String value) { GroupPredicate(FieldDef<InternalGroup, ?> def, String name, String value) {
super(def, name, value); super(def, name, value);
} }
} }

View File

@@ -26,11 +26,12 @@ import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.account.GroupBackend; import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.account.GroupBackends; import com.google.gerrit.server.account.GroupBackends;
import com.google.gerrit.server.account.GroupCache; import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.group.InternalGroup;
import com.google.inject.Inject; import com.google.inject.Inject;
import java.util.List; import java.util.List;
/** Parses a query string meant to be applied to group objects. */ /** Parses a query string meant to be applied to group objects. */
public class GroupQueryBuilder extends QueryBuilder<AccountGroup> { public class GroupQueryBuilder extends QueryBuilder<InternalGroup> {
public static final String FIELD_UUID = "uuid"; public static final String FIELD_UUID = "uuid";
public static final String FIELD_DESCRIPTION = "description"; public static final String FIELD_DESCRIPTION = "description";
public static final String FIELD_INNAME = "inname"; public static final String FIELD_INNAME = "inname";
@@ -38,7 +39,7 @@ public class GroupQueryBuilder extends QueryBuilder<AccountGroup> {
public static final String FIELD_OWNER = "owner"; public static final String FIELD_OWNER = "owner";
public static final String FIELD_LIMIT = "limit"; public static final String FIELD_LIMIT = "limit";
private static final QueryBuilder.Definition<AccountGroup, GroupQueryBuilder> mydef = private static final QueryBuilder.Definition<InternalGroup, GroupQueryBuilder> mydef =
new QueryBuilder.Definition<>(GroupQueryBuilder.class); new QueryBuilder.Definition<>(GroupQueryBuilder.class);
public static class Arguments { public static class Arguments {
@@ -61,12 +62,12 @@ public class GroupQueryBuilder extends QueryBuilder<AccountGroup> {
} }
@Operator @Operator
public Predicate<AccountGroup> uuid(String uuid) { public Predicate<InternalGroup> uuid(String uuid) {
return GroupPredicates.uuid(new AccountGroup.UUID(uuid)); return GroupPredicates.uuid(new AccountGroup.UUID(uuid));
} }
@Operator @Operator
public Predicate<AccountGroup> description(String description) throws QueryParseException { public Predicate<InternalGroup> description(String description) throws QueryParseException {
if (Strings.isNullOrEmpty(description)) { if (Strings.isNullOrEmpty(description)) {
throw error("description operator requires a value"); throw error("description operator requires a value");
} }
@@ -75,7 +76,7 @@ public class GroupQueryBuilder extends QueryBuilder<AccountGroup> {
} }
@Operator @Operator
public Predicate<AccountGroup> inname(String namePart) { public Predicate<InternalGroup> inname(String namePart) {
if (namePart.isEmpty()) { if (namePart.isEmpty()) {
return name(namePart); return name(namePart);
} }
@@ -83,12 +84,12 @@ public class GroupQueryBuilder extends QueryBuilder<AccountGroup> {
} }
@Operator @Operator
public Predicate<AccountGroup> name(String name) { public Predicate<InternalGroup> name(String name) {
return GroupPredicates.name(name); return GroupPredicates.name(name);
} }
@Operator @Operator
public Predicate<AccountGroup> owner(String owner) throws QueryParseException { public Predicate<InternalGroup> owner(String owner) throws QueryParseException {
AccountGroup group = args.groupCache.get(new AccountGroup.UUID(owner)); AccountGroup group = args.groupCache.get(new AccountGroup.UUID(owner));
if (group != null) { if (group != null) {
return GroupPredicates.owner(group.getGroupUUID()); return GroupPredicates.owner(group.getGroupUUID());
@@ -101,7 +102,7 @@ public class GroupQueryBuilder extends QueryBuilder<AccountGroup> {
} }
@Operator @Operator
public Predicate<AccountGroup> is(String value) throws QueryParseException { public Predicate<InternalGroup> is(String value) throws QueryParseException {
if ("visibletoall".equalsIgnoreCase(value)) { if ("visibletoall".equalsIgnoreCase(value)) {
return GroupPredicates.isVisibleToAll(); return GroupPredicates.isVisibleToAll();
} }
@@ -109,9 +110,9 @@ public class GroupQueryBuilder extends QueryBuilder<AccountGroup> {
} }
@Override @Override
protected Predicate<AccountGroup> defaultField(String query) throws QueryParseException { protected Predicate<InternalGroup> defaultField(String query) throws QueryParseException {
// Adapt the capacity of this list when adding more default predicates. // Adapt the capacity of this list when adding more default predicates.
List<Predicate<AccountGroup>> preds = Lists.newArrayListWithCapacity(5); List<Predicate<InternalGroup>> preds = Lists.newArrayListWithCapacity(5);
preds.add(uuid(query)); preds.add(uuid(query));
preds.add(name(query)); preds.add(name(query));
preds.add(inname(query)); preds.add(inname(query));
@@ -127,7 +128,7 @@ public class GroupQueryBuilder extends QueryBuilder<AccountGroup> {
} }
@Operator @Operator
public Predicate<AccountGroup> limit(String query) throws QueryParseException { public Predicate<InternalGroup> limit(String query) throws QueryParseException {
Integer limit = Ints.tryParse(query); Integer limit = Ints.tryParse(query);
if (limit == null) { if (limit == null) {
throw error("Invalid limit: " + query); throw error("Invalid limit: " + query);

View File

@@ -23,10 +23,10 @@ import com.google.gerrit.index.query.IndexPredicate;
import com.google.gerrit.index.query.Predicate; import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.index.query.QueryProcessor; import com.google.gerrit.index.query.QueryProcessor;
import com.google.gerrit.metrics.MetricMaker; import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.AccountLimits; import com.google.gerrit.server.account.AccountLimits;
import com.google.gerrit.server.account.GroupControl; import com.google.gerrit.server.account.GroupControl;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.index.group.GroupIndexCollection; import com.google.gerrit.server.index.group.GroupIndexCollection;
import com.google.gerrit.server.index.group.GroupIndexRewriter; import com.google.gerrit.server.index.group.GroupIndexRewriter;
import com.google.gerrit.server.index.group.GroupSchemaDefinitions; import com.google.gerrit.server.index.group.GroupSchemaDefinitions;
@@ -39,7 +39,7 @@ import com.google.inject.Provider;
* <p>Instances are one-time-use. Other singleton classes should inject a Provider rather than * <p>Instances are one-time-use. Other singleton classes should inject a Provider rather than
* holding on to a single instance. * holding on to a single instance.
*/ */
public class GroupQueryProcessor extends QueryProcessor<AccountGroup> { public class GroupQueryProcessor extends QueryProcessor<InternalGroup> {
private final Provider<CurrentUser> userProvider; private final Provider<CurrentUser> userProvider;
private final GroupControl.GenericFactory groupControlFactory; private final GroupControl.GenericFactory groupControlFactory;
@@ -72,7 +72,7 @@ public class GroupQueryProcessor extends QueryProcessor<AccountGroup> {
} }
@Override @Override
protected Predicate<AccountGroup> enforceVisibility(Predicate<AccountGroup> pred) { protected Predicate<InternalGroup> enforceVisibility(Predicate<InternalGroup> pred) {
return new AndSource<>( return new AndSource<>(
pred, new GroupIsVisibleToPredicate(groupControlFactory, userProvider.get()), start); pred, new GroupIsVisibleToPredicate(groupControlFactory, userProvider.get()), start);
} }

View File

@@ -14,6 +14,7 @@
package com.google.gerrit.server.schema; package com.google.gerrit.server.schema;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.common.TimeUtil; import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.common.data.GroupReference; import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.reviewdb.client.AccountGroup;
@@ -25,6 +26,7 @@ import com.google.gerrit.server.account.GroupUUID;
import com.google.gerrit.server.config.SitePath; import com.google.gerrit.server.config.SitePath;
import com.google.gerrit.server.config.SitePaths; import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.group.GroupsUpdate; import com.google.gerrit.server.group.GroupsUpdate;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.index.group.GroupIndex; import com.google.gerrit.server.index.group.GroupIndex;
import com.google.gerrit.server.index.group.GroupIndexCollection; import com.google.gerrit.server.index.group.GroupIndexCollection;
import com.google.gwtorm.jdbc.JdbcExecutor; import com.google.gwtorm.jdbc.JdbcExecutor;
@@ -100,16 +102,16 @@ public class SchemaCreator {
admin = newGroup(db, "Administrators"); admin = newGroup(db, "Administrators");
admin.setDescription("Gerrit Site Administrators"); admin.setDescription("Gerrit Site Administrators");
GroupsUpdate.addNewGroup(db, admin); GroupsUpdate.addNewGroup(db, admin);
index(admin); index(InternalGroup.create(admin, ImmutableSet.of(), ImmutableSet.of()));
batch = newGroup(db, "Non-Interactive Users"); batch = newGroup(db, "Non-Interactive Users");
batch.setDescription("Users who perform batch actions on Gerrit"); batch.setDescription("Users who perform batch actions on Gerrit");
batch.setOwnerGroupUUID(admin.getGroupUUID()); batch.setOwnerGroupUUID(admin.getGroupUUID());
GroupsUpdate.addNewGroup(db, batch); GroupsUpdate.addNewGroup(db, batch);
index(batch); index(InternalGroup.create(batch, ImmutableSet.of(), ImmutableSet.of()));
} }
private void index(AccountGroup group) throws IOException { private void index(InternalGroup group) throws IOException {
for (GroupIndex groupIndex : indexCollection.getWriteIndexes()) { for (GroupIndex groupIndex : indexCollection.getWriteIndexes()) {
groupIndex.replace(group); groupIndex.replace(group);
} }