Merge "Fix pushing a series of changes to a non-existing branch with createNewChangeForAllNotInTarget"
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 6362597..fc9d405 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -2979,7 +2979,7 @@
for production use. For compatibility information, please refer to the
link:https://www.gerritcodereview.com/elasticsearch.html[project homepage].
-When using Elasticsearch versions 2.4 and 5.6, the open and closed changes are
+When using Elasticsearch version 5.6, the open and closed changes are
indexed in a single index, separated into types `open_changes` and `closed_changes`
respectively. When using version 6.2 or later, the open and closed changes are
merged into the default `_doc` type. The latter is also used for the accounts and
@@ -3016,6 +3016,22 @@
+
Defaults to `30000 ms`.
+[[elasticsearch.numberOfShards]]elasticsearch.numberOfShards::
++
+Sets the number of shards to use per index. Refer to the
+link:https://www.elastic.co/guide/en/elasticsearch/reference/current/_basic_concepts.html#getting-started-shards-and-replicas[
+Elasticsearch documentation] for details.
++
+Defaults to 5.
+
+[[elasticsearch.numberOfReplicas]]elasticsearch.numberOfReplicas::
++
+Sets the number of replicas to use per index. Refer to the
+link:https://www.elastic.co/guide/en/elasticsearch/reference/current/_basic_concepts.html#getting-started-shards-and-replicas[
+Elasticsearch documentation] for details.
++
+Defaults to 1.
+
==== Elasticsearch Security
When security is enabled in Elasticsearch, the username and password must be provided.
@@ -3023,11 +3039,11 @@
For further information about Elasticsearch security, please refer to the documentation:
-* link:https://www.elastic.co/guide/en/elasticsearch/plugins/2.4/security.html[Elasticsearch 2.4]
* link:https://www.elastic.co/guide/en/x-pack/5.6/security-getting-started.html[Elasticsearch 5.6]
* link:https://www.elastic.co/guide/en/x-pack/6.2/security-getting-started.html[Elasticsearch 6.2]
* link:https://www.elastic.co/guide/en/elastic-stack-overview/6.3/security-getting-started.html[Elasticsearch 6.3]
* link:https://www.elastic.co/guide/en/elastic-stack-overview/6.4/security-getting-started.html[Elasticsearch 6.4]
+* link:https://www.elastic.co/guide/en/elastic-stack-overview/6.5/security-getting-started.html[Elasticsearch 6.5]
[[elasticsearch.username]]elasticsearch.username::
+
diff --git a/java/com/google/gerrit/acceptance/BUILD b/java/com/google/gerrit/acceptance/BUILD
index b0a39cf..7becf99 100644
--- a/java/com/google/gerrit/acceptance/BUILD
+++ b/java/com/google/gerrit/acceptance/BUILD
@@ -26,6 +26,7 @@
"//java/com/google/gerrit/pgm/util",
"//java/com/google/gerrit/reviewdb:server",
"//java/com/google/gerrit/server",
+ "//java/com/google/gerrit/server/audit",
"//java/com/google/gerrit/server/git/receive",
"//java/com/google/gerrit/server/project/testing:project-test-util",
"//java/com/google/gerrit/server/restapi",
diff --git a/java/com/google/gerrit/acceptance/GerritServer.java b/java/com/google/gerrit/acceptance/GerritServer.java
index 981ee6b..96a9053 100644
--- a/java/com/google/gerrit/acceptance/GerritServer.java
+++ b/java/com/google/gerrit/acceptance/GerritServer.java
@@ -228,6 +228,9 @@
// Silence non-critical messages from apache.http.
.put("org.apache.http", Level.WARN)
+
+ // Silence non-critical messages from Jetty.
+ .put("org.eclipse.jetty", Level.WARN)
.build();
private static boolean forceLocalDisk() {
diff --git a/java/com/google/gerrit/common/data/LabelType.java b/java/com/google/gerrit/common/data/LabelType.java
index ff7d25b..be4c33c 100644
--- a/java/com/google/gerrit/common/data/LabelType.java
+++ b/java/com/google/gerrit/common/data/LabelType.java
@@ -94,8 +94,7 @@
protected String name;
- // String rather than LabelFunction for backwards compatibility with GWT JSON interface.
- protected String functionName;
+ protected LabelFunction function;
protected boolean copyMinScore;
protected boolean copyMaxScore;
@@ -123,7 +122,7 @@
values = sortValues(valueList);
defaultValue = 0;
- functionName = LabelFunction.MAX_WITH_BLOCK.getFunctionName();
+ function = LabelFunction.MAX_WITH_BLOCK;
maxNegative = Short.MIN_VALUE;
maxPositive = Short.MAX_VALUE;
@@ -160,15 +159,11 @@
}
public LabelFunction getFunction() {
- if (functionName == null) {
- return null;
- }
- return LabelFunction.parse(functionName)
- .orElseThrow(() -> new IllegalStateException("Unsupported functionName: " + functionName));
+ return function;
}
public void setFunction(@Nullable LabelFunction function) {
- this.functionName = function != null ? function.getFunctionName() : null;
+ this.function = function;
}
public boolean canOverride() {
diff --git a/java/com/google/gerrit/common/data/ProjectAccess.java b/java/com/google/gerrit/common/data/ProjectAccess.java
index ea17525..a40af22 100644
--- a/java/com/google/gerrit/common/data/ProjectAccess.java
+++ b/java/com/google/gerrit/common/data/ProjectAccess.java
@@ -14,6 +14,7 @@
package com.google.gerrit.common.data;
+import com.google.gerrit.extensions.common.WebLinkInfo;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import java.util.List;
@@ -31,7 +32,7 @@
protected LabelTypes labelTypes;
protected Map<String, String> capabilities;
protected Map<AccountGroup.UUID, GroupInfo> groupInfo;
- protected List<WebLinkInfoCommon> fileHistoryLinks;
+ protected List<WebLinkInfo> fileHistoryLinks;
public ProjectAccess() {}
@@ -132,11 +133,11 @@
groupInfo = m;
}
- public void setFileHistoryLinks(List<WebLinkInfoCommon> links) {
+ public void setFileHistoryLinks(List<WebLinkInfo> links) {
fileHistoryLinks = links;
}
- public List<WebLinkInfoCommon> getFileHistoryLinks() {
+ public List<WebLinkInfo> getFileHistoryLinks() {
return fileHistoryLinks;
}
}
diff --git a/java/com/google/gerrit/common/data/WebLinkInfoCommon.java b/java/com/google/gerrit/common/data/WebLinkInfoCommon.java
deleted file mode 100644
index dd0a70a..0000000
--- a/java/com/google/gerrit/common/data/WebLinkInfoCommon.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (C) 2015 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.common.data;
-
-public class WebLinkInfoCommon {
- public WebLinkInfoCommon() {}
-
- public String name;
- public String imageUrl;
- public String url;
- public String target;
-}
diff --git a/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java b/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
index 6da19cd..3b589b2 100644
--- a/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
+++ b/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
@@ -107,6 +107,7 @@
return content;
}
+ private final ElasticConfiguration config;
private final Schema<V> schema;
private final SitePaths sitePaths;
private final String indexNameRaw;
@@ -118,17 +119,18 @@
protected final ElasticQueryBuilder queryBuilder;
AbstractElasticIndex(
- ElasticConfiguration cfg,
+ ElasticConfiguration config,
SitePaths sitePaths,
Schema<V> schema,
ElasticRestClientProvider client,
String indexName,
String indexType) {
+ this.config = config;
this.sitePaths = sitePaths;
this.schema = schema;
this.gson = new GsonBuilder().setFieldNamingPolicy(LOWER_CASE_WITH_UNDERSCORES).create();
this.queryBuilder = new ElasticQueryBuilder();
- this.indexName = cfg.getIndexName(indexName, schema.getVersion());
+ this.indexName = config.getIndexName(indexName, schema.getVersion());
this.indexNameRaw = indexName;
this.client = client;
this.type = client.adapter().getType(indexType);
@@ -199,7 +201,7 @@
protected abstract String getMappings();
private String getSettings() {
- return gson.toJson(ImmutableMap.of(SETTINGS, ElasticSetting.createSetting()));
+ return gson.toJson(ImmutableMap.of(SETTINGS, ElasticSetting.createSetting(config)));
}
protected abstract String getId(V v);
@@ -293,8 +295,11 @@
}
protected String getURI(String type, String request) throws UnsupportedEncodingException {
- String encodedType = URLEncoder.encode(type, UTF_8.toString());
String encodedIndexName = URLEncoder.encode(indexName, UTF_8.toString());
+ if (SEARCH.equals(request) && client.adapter().omitTypeFromSearch()) {
+ return encodedIndexName + "/" + request;
+ }
+ String encodedType = URLEncoder.encode(type, UTF_8.toString());
return encodedIndexName + "/" + encodedType + "/" + request;
}
diff --git a/java/com/google/gerrit/elasticsearch/ElasticConfiguration.java b/java/com/google/gerrit/elasticsearch/ElasticConfiguration.java
index 8d29d21..6863238 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticConfiguration.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticConfiguration.java
@@ -40,9 +40,13 @@
static final String KEY_MAX_RETRY_TIMEOUT = "maxRetryTimeout";
static final String KEY_PREFIX = "prefix";
static final String KEY_SERVER = "server";
+ static final String KEY_NUMBER_OF_SHARDS = "numberOfShards";
+ static final String KEY_NUMBER_OF_REPLICAS = "numberOfReplicas";
static final String DEFAULT_PORT = "9200";
static final String DEFAULT_USERNAME = "elastic";
static final int DEFAULT_MAX_RETRY_TIMEOUT_MS = 30000;
+ static final int DEFAULT_NUMBER_OF_SHARDS = 5;
+ static final int DEFAULT_NUMBER_OF_REPLICAS = 1;
static final TimeUnit MAX_RETRY_TIMEOUT_UNIT = TimeUnit.MILLISECONDS;
private final Config cfg;
@@ -51,6 +55,8 @@
final String username;
final String password;
final int maxRetryTimeout;
+ final int numberOfShards;
+ final int numberOfReplicas;
final String prefix;
@Inject
@@ -71,6 +77,10 @@
DEFAULT_MAX_RETRY_TIMEOUT_MS,
MAX_RETRY_TIMEOUT_UNIT);
this.prefix = Strings.nullToEmpty(cfg.getString(SECTION_ELASTICSEARCH, null, KEY_PREFIX));
+ this.numberOfShards =
+ cfg.getInt(SECTION_ELASTICSEARCH, null, KEY_NUMBER_OF_SHARDS, DEFAULT_NUMBER_OF_SHARDS);
+ this.numberOfReplicas =
+ cfg.getInt(SECTION_ELASTICSEARCH, null, KEY_NUMBER_OF_REPLICAS, DEFAULT_NUMBER_OF_REPLICAS);
this.hosts = new ArrayList<>();
for (String server : cfg.getStringList(SECTION_ELASTICSEARCH, null, KEY_SERVER)) {
try {
diff --git a/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java b/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java
index 65d2916..40c1bbb 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java
@@ -21,6 +21,7 @@
private final boolean ignoreUnmapped;
private final boolean usePostV5Type;
+ private final boolean omitTypeFromSearch;
private final String searchFilteringName;
private final String indicesExistParam;
@@ -31,33 +32,16 @@
private final String versionDiscoveryUrl;
ElasticQueryAdapter(ElasticVersion version) {
- this.ignoreUnmapped = version == ElasticVersion.V2_4;
- this.usePostV5Type = version.isV6();
- this.versionDiscoveryUrl = version.isV6() ? "/%s*" : "/%s*/_aliases";
-
- switch (version) {
- case V5_6:
- case V6_2:
- case V6_3:
- case V6_4:
- case V6_5:
- this.searchFilteringName = "_source";
- this.indicesExistParam = "?allow_no_indices=false";
- this.exactFieldType = "keyword";
- this.stringFieldType = "text";
- this.indexProperty = "true";
- this.rawFieldsKey = "_source";
- break;
- case V2_4:
- default:
- this.searchFilteringName = "fields";
- this.indicesExistParam = "";
- this.exactFieldType = "string";
- this.stringFieldType = "string";
- this.indexProperty = "not_analyzed";
- this.rawFieldsKey = "fields";
- break;
- }
+ this.ignoreUnmapped = false;
+ this.usePostV5Type = version.isV6OrLater();
+ this.omitTypeFromSearch = version.isV7OrLater();
+ this.versionDiscoveryUrl = version.isV6OrLater() ? "/%s*" : "/%s*/_aliases";
+ this.searchFilteringName = "_source";
+ this.indicesExistParam = "?allow_no_indices=false";
+ this.exactFieldType = "keyword";
+ this.stringFieldType = "text";
+ this.indexProperty = "true";
+ this.rawFieldsKey = "_source";
}
void setIgnoreUnmapped(JsonObject properties) {
@@ -100,8 +84,12 @@
return usePostV5Type;
}
- String getType(String preV6Type) {
- return usePostV5Type() ? POST_V5_TYPE : preV6Type;
+ boolean omitTypeFromSearch() {
+ return omitTypeFromSearch;
+ }
+
+ String getType(String type) {
+ return usePostV5Type() ? POST_V5_TYPE : type;
}
String getVersionDiscoveryUrl(String name) {
diff --git a/java/com/google/gerrit/elasticsearch/ElasticSetting.java b/java/com/google/gerrit/elasticsearch/ElasticSetting.java
index 6fd234d..98c313c 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticSetting.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticSetting.java
@@ -22,33 +22,33 @@
private static final ImmutableMap<String, String> CUSTOM_CHAR_MAPPING =
ImmutableMap.of("\\u002E", "\\u0020", "\\u005F", "\\u0020");
- static SettingProperties createSetting() {
- ElasticSetting.Builder settings = new ElasticSetting.Builder();
- settings.addCharFilter();
- settings.addAnalyzer();
- return settings.build();
+ static SettingProperties createSetting(ElasticConfiguration config) {
+ return new ElasticSetting.Builder().addCharFilter().addAnalyzer().build(config);
}
static class Builder {
private final ImmutableMap.Builder<String, FieldProperties> fields =
new ImmutableMap.Builder<>();
- SettingProperties build() {
+ SettingProperties build(ElasticConfiguration config) {
SettingProperties properties = new SettingProperties();
properties.analysis = fields.build();
+ properties.numberOfShards = config.numberOfShards;
+ properties.numberOfReplicas = config.numberOfReplicas;
return properties;
}
- void addCharFilter() {
+ Builder addCharFilter() {
FieldProperties charMapping = new FieldProperties("mapping");
charMapping.mappings = getCustomCharMappings(CUSTOM_CHAR_MAPPING);
FieldProperties charFilter = new FieldProperties();
charFilter.customMapping = charMapping;
fields.put("char_filter", charFilter);
+ return this;
}
- void addAnalyzer() {
+ Builder addAnalyzer() {
FieldProperties customAnalyzer = new FieldProperties("custom");
customAnalyzer.tokenizer = "standard";
customAnalyzer.charFilter = new String[] {"custom_mapping"};
@@ -57,6 +57,7 @@
FieldProperties analyzer = new FieldProperties();
analyzer.customWithCharFilter = customAnalyzer;
fields.put("analyzer", analyzer);
+ return this;
}
private static String[] getCustomCharMappings(ImmutableMap<String, String> map) {
@@ -72,6 +73,8 @@
static class SettingProperties {
Map<String, FieldProperties> analysis;
+ Integer numberOfShards;
+ Integer numberOfReplicas;
}
static class FieldProperties {
diff --git a/java/com/google/gerrit/elasticsearch/ElasticVersion.java b/java/com/google/gerrit/elasticsearch/ElasticVersion.java
index 4c98df1..b69f8f9 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticVersion.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticVersion.java
@@ -18,12 +18,12 @@
import java.util.regex.Pattern;
public enum ElasticVersion {
- V2_4("2.4.*"),
V5_6("5.6.*"),
V6_2("6.2.*"),
V6_3("6.3.*"),
V6_4("6.4.*"),
- V6_5("6.5.*");
+ V6_5("6.5.*"),
+ V7_0("7.0.*");
private final String version;
private final Pattern pattern;
@@ -56,8 +56,16 @@
return Joiner.on(", ").join(ElasticVersion.values());
}
- public boolean isV6() {
- return version.startsWith("6.");
+ public boolean isV6OrLater() {
+ return isAtLeastVersion(6);
+ }
+
+ public boolean isV7OrLater() {
+ return isAtLeastVersion(7);
+ }
+
+ private boolean isAtLeastVersion(int v) {
+ return Integer.valueOf(version.split("\\.")[0]) >= v;
}
@Override
diff --git a/java/com/google/gerrit/extensions/client/MenuItem.java b/java/com/google/gerrit/extensions/client/MenuItem.java
index 8375bba..0c7dd88 100644
--- a/java/com/google/gerrit/extensions/client/MenuItem.java
+++ b/java/com/google/gerrit/extensions/client/MenuItem.java
@@ -22,11 +22,6 @@
public final String target;
public final String id;
- // Needed for GWT
- public MenuItem() {
- this(null, null, null, null);
- }
-
public MenuItem(String name, String url) {
this(name, url, "_blank");
}
diff --git a/java/com/google/gerrit/httpd/GitOverHttpServlet.java b/java/com/google/gerrit/httpd/GitOverHttpServlet.java
index e74c4b2..2e1b562 100644
--- a/java/com/google/gerrit/httpd/GitOverHttpServlet.java
+++ b/java/com/google/gerrit/httpd/GitOverHttpServlet.java
@@ -15,7 +15,7 @@
package com.google.gerrit.httpd;
import com.google.common.cache.Cache;
-import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.gerrit.common.data.Capable;
@@ -52,6 +52,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
@@ -61,6 +62,7 @@
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.http.server.GitServlet;
import org.eclipse.jgit.http.server.GitSmartHttpTools;
@@ -130,6 +132,55 @@
}
}
+ static class HttpServletResponseWithStatusWrapper extends HttpServletResponseWrapper {
+ private int responseStatus;
+
+ HttpServletResponseWithStatusWrapper(HttpServletResponse response) {
+ super(response);
+ /* Even if we could read the status from response, we assume that it is all
+ * fine because we entered the filter without any prior issues.
+ * When Google will have upgraded to Servlet 3.0, we could actually
+ * call response.getStatus() and the code will be clearer.
+ */
+ responseStatus = HttpServletResponse.SC_OK;
+ }
+
+ @Override
+ public void setStatus(int sc) {
+ responseStatus = sc;
+ super.setStatus(sc);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void setStatus(int sc, String sm) {
+ responseStatus = sc;
+ super.setStatus(sc, sm);
+ }
+
+ @Override
+ public void sendError(int sc) throws IOException {
+ this.responseStatus = sc;
+ super.sendError(sc);
+ }
+
+ @Override
+ public void sendError(int sc, String msg) throws IOException {
+ this.responseStatus = sc;
+ super.sendError(sc, msg);
+ }
+
+ @Override
+ public void sendRedirect(String location) throws IOException {
+ this.responseStatus = HttpServletResponse.SC_MOVED_TEMPORARILY;
+ super.sendRedirect(location);
+ }
+
+ public int getResponseStatus() {
+ return responseStatus;
+ }
+ }
+
@Inject
GitOverHttpServlet(
Resolver resolver,
@@ -156,19 +207,15 @@
}
private static ListMultimap<String, String> extractParameters(HttpServletRequest request) {
-
- ListMultimap<String, String> multiMap = ArrayListMultimap.create();
- if (request.getQueryString() != null) {
- request
- .getParameterMap()
- .forEach(
- (k, v) -> {
- for (int i = 0; i < v.length; i++) {
- multiMap.put(k, v[i]);
- }
- });
+ if (request.getQueryString() == null) {
+ return ImmutableListMultimap.of();
}
- return multiMap;
+ // Explicit cast is required to compile under Servlet API 2.5, where the return type is raw Map.
+ @SuppressWarnings("cast")
+ Map<String, String[]> parameterMap = (Map<String, String[]>) request.getParameterMap();
+ ImmutableListMultimap.Builder<String, String> b = ImmutableListMultimap.builder();
+ parameterMap.forEach(b::putAll);
+ return b.build();
}
static class Resolver implements RepositoryResolver<HttpServletRequest> {
@@ -301,41 +348,48 @@
UploadPack up = (UploadPack) request.getAttribute(ServletUtils.ATTRIBUTE_HANDLER);
PermissionBackend.ForProject perm =
permissionBackend.currentUser().project(state.getNameKey());
+ HttpServletResponseWithStatusWrapper responseWrapper =
+ new HttpServletResponseWithStatusWrapper((HttpServletResponse) response);
+ HttpServletRequest httpRequest = (HttpServletRequest) request;
+ String sessionId = httpRequest.getSession().getId();
+
try {
- perm.check(ProjectPermission.RUN_UPLOAD_PACK);
- } catch (AuthException e) {
- GitSmartHttpTools.sendError(
- (HttpServletRequest) request,
- (HttpServletResponse) response,
- HttpServletResponse.SC_FORBIDDEN,
- "upload-pack not permitted on this server");
- return;
- } catch (PermissionBackendException e) {
- throw new ServletException(e);
+ try {
+ perm.check(ProjectPermission.RUN_UPLOAD_PACK);
+ } catch (AuthException e) {
+ GitSmartHttpTools.sendError(
+ (HttpServletRequest) request,
+ responseWrapper,
+ HttpServletResponse.SC_FORBIDDEN,
+ "upload-pack not permitted on this server");
+ return;
+ } catch (PermissionBackendException e) {
+ responseWrapper.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ throw new ServletException(e);
+ }
+
+ // We use getRemoteHost() here instead of getRemoteAddr() because REMOTE_ADDR
+ // may have been overridden by a proxy server -- we'll try to avoid this.
+ UploadValidators uploadValidators =
+ uploadValidatorsFactory.create(state.getProject(), repo, request.getRemoteHost());
+ up.setPreUploadHook(
+ PreUploadHookChain.newChain(
+ Lists.newArrayList(up.getPreUploadHook(), uploadValidators)));
+ up.setAdvertiseRefsHook(new DefaultAdvertiseRefsHook(perm, RefFilterOptions.defaults()));
+ next.doFilter(httpRequest, responseWrapper);
} finally {
- HttpServletRequest httpRequest = (HttpServletRequest) request;
- HttpServletResponse httpResponse = (HttpServletResponse) response;
groupAuditService.dispatch(
new HttpAuditEvent(
- httpRequest.getSession().getId(),
+ sessionId,
userProvider.get(),
extractWhat(httpRequest),
TimeUtil.nowMs(),
extractParameters(httpRequest),
httpRequest.getMethod(),
httpRequest,
- httpResponse.getStatus(),
- httpResponse));
+ responseWrapper.getResponseStatus(),
+ responseWrapper));
}
-
- // We use getRemoteHost() here instead of getRemoteAddr() because REMOTE_ADDR
- // may have been overridden by a proxy server -- we'll try to avoid this.
- UploadValidators uploadValidators =
- uploadValidatorsFactory.create(state.getProject(), repo, request.getRemoteHost());
- up.setPreUploadHook(
- PreUploadHookChain.newChain(Lists.newArrayList(up.getPreUploadHook(), uploadValidators)));
- up.setAdvertiseRefsHook(new DefaultAdvertiseRefsHook(perm, RefFilterOptions.defaults()));
- next.doFilter(request, response);
}
@Override
@@ -411,25 +465,28 @@
rp.getAdvertiseRefsHook().advertiseRefs(rp);
ProjectState state = (ProjectState) request.getAttribute(ATT_STATE);
+ HttpServletResponseWithStatusWrapper responseWrapper =
+ new HttpServletResponseWithStatusWrapper((HttpServletResponse) response);
+ HttpServletRequest httpRequest = (HttpServletRequest) request;
Capable canUpload;
try {
- permissionBackend
- .currentUser()
- .project(state.getNameKey())
- .check(ProjectPermission.RUN_RECEIVE_PACK);
- canUpload = arc.canUpload();
- } catch (AuthException e) {
- GitSmartHttpTools.sendError(
- (HttpServletRequest) request,
- (HttpServletResponse) response,
- HttpServletResponse.SC_FORBIDDEN,
- "receive-pack not permitted on this server");
- return;
- } catch (PermissionBackendException e) {
- throw new RuntimeException(e);
+ try {
+ permissionBackend
+ .currentUser()
+ .project(state.getNameKey())
+ .check(ProjectPermission.RUN_RECEIVE_PACK);
+ canUpload = arc.canUpload();
+ } catch (AuthException e) {
+ GitSmartHttpTools.sendError(
+ httpRequest,
+ responseWrapper,
+ HttpServletResponse.SC_FORBIDDEN,
+ "receive-pack not permitted on this server");
+ return;
+ } catch (PermissionBackendException e) {
+ throw new RuntimeException(e);
+ }
} finally {
- HttpServletRequest httpRequest = (HttpServletRequest) request;
- HttpServletResponse httpResponse = (HttpServletResponse) response;
groupAuditService.dispatch(
new HttpAuditEvent(
httpRequest.getSession().getId(),
@@ -439,26 +496,26 @@
extractParameters(httpRequest),
httpRequest.getMethod(),
httpRequest,
- httpResponse.getStatus(),
- httpResponse));
+ responseWrapper.getResponseStatus(),
+ responseWrapper));
}
if (canUpload != Capable.OK) {
GitSmartHttpTools.sendError(
- (HttpServletRequest) request,
- (HttpServletResponse) response,
+ httpRequest,
+ responseWrapper,
HttpServletResponse.SC_FORBIDDEN,
"\n" + canUpload.getMessage());
return;
}
if (!rp.isCheckReferencedObjectsAreReachable()) {
- chain.doFilter(request, response);
+ chain.doFilter(request, responseWrapper);
return;
}
if (!(userProvider.get().isIdentifiedUser())) {
- chain.doFilter(request, response);
+ chain.doFilter(request, responseWrapper);
return;
}
@@ -475,7 +532,7 @@
}
}
- chain.doFilter(request, response);
+ chain.doFilter(request, responseWrapper);
if (isGet) {
cache.put(cacheKey, Collections.unmodifiableSet(new HashSet<>(rp.getAdvertisedObjects())));
diff --git a/java/com/google/gerrit/pgm/init/GroupsOnInit.java b/java/com/google/gerrit/pgm/init/GroupsOnInit.java
index 8e06aa1..584d8af 100644
--- a/java/com/google/gerrit/pgm/init/GroupsOnInit.java
+++ b/java/com/google/gerrit/pgm/init/GroupsOnInit.java
@@ -25,7 +25,6 @@
import com.google.gerrit.pgm.init.api.InitFlags;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.GerritPersonIdentProvider;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.GerritServerIdProvider;
@@ -37,7 +36,6 @@
import com.google.gerrit.server.group.db.GroupConfig;
import com.google.gerrit.server.group.db.GroupNameNotes;
import com.google.gerrit.server.group.db.InternalGroupUpdate;
-import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import java.io.File;
import java.io.IOException;
@@ -54,9 +52,8 @@
/**
* A database accessor for calls related to groups.
*
- * <p>All calls which read or write group related details to the database <strong>during
- * init</strong> (either ReviewDb or NoteDb) are gathered here. For non-init cases, use {@code
- * Groups} or {@code GroupsUpdate} instead.
+ * <p>All calls which read or write group related details to the NoteDb <strong>during init</strong>
+ * are gathered here. For non-init cases, use {@code Groups} or {@code GroupsUpdate} instead.
*
* <p>All methods of this class refer to <em>internal</em> groups.
*/
@@ -76,16 +73,14 @@
/**
* Returns the {@code AccountGroup} for the specified {@code GroupReference}.
*
- * @param db the {@code ReviewDb} instance to use for lookups
* @param groupReference the {@code GroupReference} of the group
* @return the {@code InternalGroup} represented by the {@code GroupReference}
- * @throws OrmException if the group couldn't be retrieved from ReviewDb
* @throws IOException if an error occurs while reading from NoteDb
* @throws ConfigInvalidException if the data in NoteDb is in an incorrect format
* @throws NoSuchGroupException if a group with such a name doesn't exist
*/
- public InternalGroup getExistingGroup(ReviewDb db, GroupReference groupReference)
- throws OrmException, NoSuchGroupException, IOException, ConfigInvalidException {
+ public InternalGroup getExistingGroup(GroupReference groupReference)
+ throws NoSuchGroupException, IOException, ConfigInvalidException {
File allUsersRepoPath = getPathToAllUsersRepository();
if (allUsersRepoPath != null) {
try (Repository allUsersRepo = new FileRepository(allUsersRepoPath)) {
@@ -102,14 +97,11 @@
/**
* Returns {@code GroupReference}s for all internal groups.
*
- * @param db the {@code ReviewDb} instance to use for lookups
* @return a stream of the {@code GroupReference}s of all internal groups
- * @throws OrmException if an error occurs while reading from ReviewDb
* @throws IOException if an error occurs while reading from NoteDb
* @throws ConfigInvalidException if the data in NoteDb is in an incorrect format
*/
- public Stream<GroupReference> getAllGroupReferences(ReviewDb db)
- throws OrmException, IOException, ConfigInvalidException {
+ public Stream<GroupReference> getAllGroupReferences() throws IOException, ConfigInvalidException {
File allUsersRepoPath = getPathToAllUsersRepository();
if (allUsersRepoPath != null) {
try (Repository allUsersRepo = new FileRepository(allUsersRepoPath)) {
@@ -126,14 +118,12 @@
* <p><strong>Note</strong>: This method doesn't check whether the account exists! It also doesn't
* update the account index!
*
- * @param db the {@code ReviewDb} instance to update
* @param groupUuid the UUID of the group
* @param account the account to add
- * @throws OrmException if an error occurs while reading/writing from/to ReviewDb
* @throws NoSuchGroupException if the specified group doesn't exist
*/
- public void addGroupMember(ReviewDb db, AccountGroup.UUID groupUuid, Account account)
- throws OrmException, NoSuchGroupException, IOException, ConfigInvalidException {
+ public void addGroupMember(AccountGroup.UUID groupUuid, Account account)
+ throws NoSuchGroupException, IOException, ConfigInvalidException {
File allUsersRepoPath = getPathToAllUsersRepository();
if (allUsersRepoPath != null) {
try (Repository repository = new FileRepository(allUsersRepoPath)) {
diff --git a/java/com/google/gerrit/pgm/init/InitAdminUser.java b/java/com/google/gerrit/pgm/init/InitAdminUser.java
index f12fa50..f19cf39 100644
--- a/java/com/google/gerrit/pgm/init/InitAdminUser.java
+++ b/java/com/google/gerrit/pgm/init/InitAdminUser.java
@@ -26,7 +26,6 @@
import com.google.gerrit.pgm.init.api.InitStep;
import com.google.gerrit.pgm.init.api.SequencesOnInit;
import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.account.AccountSshKey;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.account.externalids.ExternalId;
@@ -37,7 +36,6 @@
import com.google.gerrit.server.index.group.GroupIndex;
import com.google.gerrit.server.index.group.GroupIndexCollection;
import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
import java.io.IOException;
import java.nio.file.Files;
@@ -57,7 +55,6 @@
private final ExternalIdsOnInit externalIds;
private final SequencesOnInit sequencesOnInit;
private final GroupsOnInit groupsOnInit;
- private SchemaFactory<ReviewDb> dbFactory;
private AccountIndexCollection accountIndexCollection;
private GroupIndexCollection groupIndexCollection;
@@ -84,11 +81,6 @@
@Override
public void run() {}
- @Inject(optional = true)
- void set(SchemaFactory<ReviewDb> dbFactory) {
- this.dbFactory = dbFactory;
- }
-
@Inject
void set(AccountIndexCollection accountIndexCollection) {
this.accountIndexCollection = accountIndexCollection;
@@ -106,58 +98,56 @@
return;
}
- try (ReviewDb db = dbFactory.open()) {
- if (!accounts.hasAnyAccount()) {
- ui.header("Gerrit Administrator");
- if (ui.yesno(true, "Create administrator user")) {
- Account.Id id = new Account.Id(sequencesOnInit.nextAccountId(db));
- String username = ui.readString("admin", "username");
- String name = ui.readString("Administrator", "name");
- String httpPassword = ui.readString("secret", "HTTP password");
- AccountSshKey sshKey = readSshKey(id);
- String email = readEmail(sshKey);
+ if (!accounts.hasAnyAccount()) {
+ ui.header("Gerrit Administrator");
+ if (ui.yesno(true, "Create administrator user")) {
+ Account.Id id = new Account.Id(sequencesOnInit.nextAccountId());
+ String username = ui.readString("admin", "username");
+ String name = ui.readString("Administrator", "name");
+ String httpPassword = ui.readString("secret", "HTTP password");
+ AccountSshKey sshKey = readSshKey(id);
+ String email = readEmail(sshKey);
- List<ExternalId> extIds = new ArrayList<>(2);
- extIds.add(ExternalId.createUsername(username, id, httpPassword));
+ List<ExternalId> extIds = new ArrayList<>(2);
+ extIds.add(ExternalId.createUsername(username, id, httpPassword));
- if (email != null) {
- extIds.add(ExternalId.createEmail(id, email));
- }
- externalIds.insert("Add external IDs for initial admin user", extIds);
+ if (email != null) {
+ extIds.add(ExternalId.createEmail(id, email));
+ }
+ externalIds.insert("Add external IDs for initial admin user", extIds);
- Account a = new Account(id, TimeUtil.nowTs());
- a.setFullName(name);
- a.setPreferredEmail(email);
- accounts.insert(a);
+ Account a = new Account(id, TimeUtil.nowTs());
+ a.setFullName(name);
+ a.setPreferredEmail(email);
+ accounts.insert(a);
- // Only two groups should exist at this point in time and hence iterating over all of them
- // is cheap.
- Optional<GroupReference> adminGroupReference =
- groupsOnInit
- .getAllGroupReferences(db)
- .filter(group -> group.getName().equals("Administrators"))
- .findAny();
- if (!adminGroupReference.isPresent()) {
- throw new NoSuchGroupException("Administrators");
- }
- GroupReference adminGroup = adminGroupReference.get();
- groupsOnInit.addGroupMember(db, adminGroup.getUUID(), a);
+ // Only two groups should exist at this point in time and hence iterating over all of them
+ // is cheap.
+ Optional<GroupReference> adminGroupReference =
+ groupsOnInit
+ .getAllGroupReferences()
+ .filter(group -> group.getName().equals("Administrators"))
+ .findAny();
+ if (!adminGroupReference.isPresent()) {
+ throw new NoSuchGroupException("Administrators");
+ }
+ GroupReference adminGroup = adminGroupReference.get();
+ groupsOnInit.addGroupMember(adminGroup.getUUID(), a);
- if (sshKey != null) {
- VersionedAuthorizedKeysOnInit authorizedKeys = authorizedKeysFactory.create(id).load();
- authorizedKeys.addKey(sshKey.sshPublicKey());
- authorizedKeys.save("Add SSH key for initial admin user\n");
- }
+ if (sshKey != null) {
+ VersionedAuthorizedKeysOnInit authorizedKeys = authorizedKeysFactory.create(id).load();
+ authorizedKeys.addKey(sshKey.sshPublicKey());
+ authorizedKeys.save("Add SSH key for initial admin user\n");
+ }
- AccountState as = AccountState.forAccount(new AllUsersName(allUsers.get()), a, extIds);
- for (AccountIndex accountIndex : accountIndexCollection.getWriteIndexes()) {
- accountIndex.replace(as);
- }
+ AccountState as = AccountState.forAccount(new AllUsersName(allUsers.get()), a, extIds);
+ for (AccountIndex accountIndex : accountIndexCollection.getWriteIndexes()) {
+ accountIndex.replace(as);
+ }
- InternalGroup adminInternalGroup = groupsOnInit.getExistingGroup(db, adminGroup);
- for (GroupIndex groupIndex : groupIndexCollection.getWriteIndexes()) {
- groupIndex.replace(adminInternalGroup);
- }
+ InternalGroup adminInternalGroup = groupsOnInit.getExistingGroup(adminGroup);
+ for (GroupIndex groupIndex : groupIndexCollection.getWriteIndexes()) {
+ groupIndex.replace(adminInternalGroup);
}
}
}
diff --git a/java/com/google/gerrit/pgm/init/api/SequencesOnInit.java b/java/com/google/gerrit/pgm/init/api/SequencesOnInit.java
index c9c3a64..1716a3c 100644
--- a/java/com/google/gerrit/pgm/init/api/SequencesOnInit.java
+++ b/java/com/google/gerrit/pgm/init/api/SequencesOnInit.java
@@ -35,16 +35,14 @@
this.allUsersName = allUsersName;
}
- public int nextAccountId(ReviewDb db) throws OrmException {
- @SuppressWarnings("deprecation")
- RepoSequence.Seed accountSeed = db::nextAccountId;
+ public int nextAccountId() throws OrmException {
RepoSequence accountSeq =
new RepoSequence(
repoManager,
GitReferenceUpdated.DISABLED,
new Project.NameKey(allUsersName.get()),
Sequences.NAME_ACCOUNTS,
- accountSeed,
+ () -> ReviewDb.FIRST_ACCOUNT_ID,
1);
return accountSeq.next();
}
diff --git a/java/com/google/gerrit/reviewdb/client/AccountGroup.java b/java/com/google/gerrit/reviewdb/client/AccountGroup.java
index c7dc420..5ec98fc 100644
--- a/java/com/google/gerrit/reviewdb/client/AccountGroup.java
+++ b/java/com/google/gerrit/reviewdb/client/AccountGroup.java
@@ -18,6 +18,7 @@
import com.google.gwtorm.client.IntKey;
import com.google.gwtorm.client.StringKey;
import java.sql.Timestamp;
+import java.time.Instant;
import java.util.Objects;
/** Named group of one or more accounts, typically used for access controls. */
@@ -26,12 +27,10 @@
* Time when the audit subsystem was implemented, used as the default value for {@link #createdOn}
* when one couldn't be determined from the audit log.
*/
- // Can't use Instant here because GWT. This is verified against a readable time in the tests,
- // which don't need to compile under GWT.
- private static final long AUDIT_CREATION_INSTANT_MS = 1244489460000L;
+ private static final Instant AUDIT_CREATION_INSTANT_MS = Instant.ofEpochMilli(1244489460000L);
public static Timestamp auditCreationInstantTs() {
- return new Timestamp(AUDIT_CREATION_INSTANT_MS);
+ return Timestamp.from(AUDIT_CREATION_INSTANT_MS);
}
/** Group name key */
diff --git a/java/com/google/gerrit/reviewdb/server/ReviewDb.java b/java/com/google/gerrit/reviewdb/server/ReviewDb.java
index 8e4292c..90cd066 100644
--- a/java/com/google/gerrit/reviewdb/server/ReviewDb.java
+++ b/java/com/google/gerrit/reviewdb/server/ReviewDb.java
@@ -14,8 +14,6 @@
package com.google.gerrit.reviewdb.server;
-import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.Relation;
@@ -28,7 +26,6 @@
* <p>Root entities that are at the top level of some important data graph:
*
* <ul>
- * <li>{@link Account}: Per-user account registration, preferences, identity.
* <li>{@link Change}: All review information about a single proposed change.
* </ul>
*/
@@ -91,22 +88,8 @@
int FIRST_ACCOUNT_ID = 1000000;
- /**
- * Next unique id for a {@link Account}.
- *
- * @deprecated use {@link com.google.gerrit.server.Sequences#nextAccountId()}.
- */
- @Sequence(startWith = FIRST_ACCOUNT_ID)
- @Deprecated
- int nextAccountId() throws OrmException;
-
int FIRST_GROUP_ID = 1;
- /** Next unique id for a {@link AccountGroup}. */
- @Sequence(startWith = FIRST_GROUP_ID)
- @Deprecated
- int nextAccountGroupId() throws OrmException;
-
int FIRST_CHANGE_ID = 1;
/**
diff --git a/java/com/google/gerrit/reviewdb/server/ReviewDbWrapper.java b/java/com/google/gerrit/reviewdb/server/ReviewDbWrapper.java
index 202729e..c420254 100644
--- a/java/com/google/gerrit/reviewdb/server/ReviewDbWrapper.java
+++ b/java/com/google/gerrit/reviewdb/server/ReviewDbWrapper.java
@@ -136,18 +136,6 @@
@Override
@SuppressWarnings("deprecation")
- public int nextAccountId() throws OrmException {
- return delegate.nextAccountId();
- }
-
- @Override
- @SuppressWarnings("deprecation")
- public int nextAccountGroupId() throws OrmException {
- return delegate.nextAccountGroupId();
- }
-
- @Override
- @SuppressWarnings("deprecation")
public int nextChangeId() throws OrmException {
return delegate.nextChangeId();
}
diff --git a/java/com/google/gerrit/server/Sequences.java b/java/com/google/gerrit/server/Sequences.java
index fcf0759..70a02a8 100644
--- a/java/com/google/gerrit/server/Sequences.java
+++ b/java/com/google/gerrit/server/Sequences.java
@@ -93,11 +93,15 @@
new RepoSequence(
repoManager, gitRefUpdated, allProjects, NAME_CHANGES, changeSeed, changeBatchSize);
- RepoSequence.Seed groupSeed = () -> nextGroupId(db.get());
int groupBatchSize = 1;
groupSeq =
new RepoSequence(
- repoManager, gitRefUpdated, allUsers, NAME_GROUPS, groupSeed, groupBatchSize);
+ repoManager,
+ gitRefUpdated,
+ allUsers,
+ NAME_GROUPS,
+ () -> ReviewDb.FIRST_GROUP_ID,
+ groupBatchSize);
nextIdLatency =
metrics.newTimer(
@@ -158,9 +162,4 @@
private static int nextChangeId(ReviewDb db) throws OrmException {
return db.nextChangeId();
}
-
- @SuppressWarnings("deprecation")
- static int nextGroupId(ReviewDb db) throws OrmException {
- return db.nextAccountGroupId();
- }
}
diff --git a/java/com/google/gerrit/server/WebLinks.java b/java/com/google/gerrit/server/WebLinks.java
index 39a2328..589344c 100644
--- a/java/com/google/gerrit/server/WebLinks.java
+++ b/java/com/google/gerrit/server/WebLinks.java
@@ -19,7 +19,6 @@
import com.google.common.base.Strings;
import com.google.common.collect.FluentIterable;
import com.google.common.flogger.FluentLogger;
-import com.google.gerrit.common.data.WebLinkInfoCommon;
import com.google.gerrit.extensions.common.DiffWebLinkInfo;
import com.google.gerrit.extensions.common.WebLinkInfo;
import com.google.gerrit.extensions.registration.DynamicSet;
@@ -54,17 +53,6 @@
return true;
};
- private static final Predicate<WebLinkInfoCommon> INVALID_WEBLINK_COMMON =
- link -> {
- if (link == null) {
- return false;
- } else if (Strings.isNullOrEmpty(link.name) || Strings.isNullOrEmpty(link.url)) {
- logger.atWarning().log("%s is missing name and/or url", link.getClass().getName());
- return false;
- }
- return true;
- };
-
private final DynamicSet<PatchSetWebLink> patchSetLinks;
private final DynamicSet<ParentWebLink> parentLinks;
private final DynamicSet<FileWebLink> fileLinks;
@@ -130,25 +118,13 @@
* @param file File name.
* @return Links for file history
*/
- public List<WebLinkInfoCommon> getFileHistoryLinks(String project, String revision, String file) {
+ public List<WebLinkInfo> getFileHistoryLinks(String project, String revision, String file) {
if (Patch.isMagic(file)) {
return Collections.emptyList();
}
return FluentIterable.from(fileHistoryLinks)
- .transform(
- webLink -> {
- WebLinkInfo info = webLink.getFileHistoryWebLink(project, revision, file);
- if (info == null) {
- return null;
- }
- WebLinkInfoCommon commonInfo = new WebLinkInfoCommon();
- commonInfo.name = info.name;
- commonInfo.imageUrl = info.imageUrl;
- commonInfo.url = info.url;
- commonInfo.target = info.target;
- return commonInfo;
- })
- .filter(INVALID_WEBLINK_COMMON)
+ .transform(webLink -> webLink.getFileHistoryWebLink(project, revision, file))
+ .filter(INVALID_WEBLINK)
.toList();
}
diff --git a/java/com/google/gerrit/server/git/meta/MetaDataUpdate.java b/java/com/google/gerrit/server/git/meta/MetaDataUpdate.java
index bbe0c62..97beefd 100644
--- a/java/com/google/gerrit/server/git/meta/MetaDataUpdate.java
+++ b/java/com/google/gerrit/server/git/meta/MetaDataUpdate.java
@@ -22,6 +22,7 @@
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Inject;
import com.google.inject.Provider;
+import com.google.inject.Singleton;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
@@ -33,21 +34,22 @@
/** Helps with the updating of a {@link VersionedMetaData}. */
public class MetaDataUpdate implements AutoCloseable {
+ @Singleton
public static class User {
private final InternalFactory factory;
private final GitRepositoryManager mgr;
- private final PersonIdent serverIdent;
+ private final Provider<PersonIdent> serverIdentProvider;
private final Provider<IdentifiedUser> identifiedUser;
@Inject
User(
InternalFactory factory,
GitRepositoryManager mgr,
- @GerritPersonIdent PersonIdent serverIdent,
+ @GerritPersonIdent Provider<PersonIdent> serverIdentProvider,
Provider<IdentifiedUser> identifiedUser) {
this.factory = factory;
this.mgr = mgr;
- this.serverIdent = serverIdent;
+ this.serverIdentProvider = serverIdentProvider;
this.identifiedUser = identifiedUser;
}
@@ -126,29 +128,31 @@
public MetaDataUpdate create(
Project.NameKey name, Repository repository, IdentifiedUser user, BatchRefUpdate batch) {
MetaDataUpdate md = factory.create(name, repository, batch);
- md.getCommitBuilder().setCommitter(serverIdent);
+ md.getCommitBuilder().setCommitter(serverIdentProvider.get());
md.setAuthor(user);
return md;
}
private PersonIdent createPersonIdent(IdentifiedUser user) {
+ PersonIdent serverIdent = serverIdentProvider.get();
return user.newCommitterIdent(serverIdent.getWhen(), serverIdent.getTimeZone());
}
}
+ @Singleton
public static class Server {
private final InternalFactory factory;
private final GitRepositoryManager mgr;
- private final PersonIdent serverIdent;
+ private final Provider<PersonIdent> serverIdentProvider;
@Inject
Server(
InternalFactory factory,
GitRepositoryManager mgr,
- @GerritPersonIdent PersonIdent serverIdent) {
+ @GerritPersonIdent Provider<PersonIdent> serverIdentProvider) {
this.factory = factory;
this.mgr = mgr;
- this.serverIdent = serverIdent;
+ this.serverIdentProvider = serverIdentProvider;
}
public MetaDataUpdate create(Project.NameKey name)
@@ -162,6 +166,7 @@
Repository repo = mgr.openRepository(name);
MetaDataUpdate md = factory.create(name, repo, batch);
md.setCloseRepository(true);
+ PersonIdent serverIdent = serverIdentProvider.get();
md.getCommitBuilder().setAuthor(serverIdent);
md.getCommitBuilder().setCommitter(serverIdent);
return md;
diff --git a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
index 48df354..cdfd00d 100644
--- a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
+++ b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
@@ -1873,7 +1873,9 @@
private static String readHEAD(Repository repo) {
try {
- return repo.getFullBranch();
+ String head = repo.getFullBranch();
+ logger.atFine().log("HEAD = %s", head);
+ return head;
} catch (IOException e) {
logger.atSevere().withCause(e).log("Cannot read HEAD symref");
return null;
@@ -2734,10 +2736,13 @@
/** prints a warning if the new PS has the same tree as the previous commit. */
private void sameTreeWarning() throws IOException {
- RevCommit newCommit = receivePack.getRevWalk().parseCommit(newCommitId);
+ RevWalk rw = receivePack.getRevWalk();
+ RevCommit newCommit = rw.parseCommit(newCommitId);
RevCommit priorCommit = revisions.inverse().get(priorPatchSet);
if (newCommit.getTree().equals(priorCommit.getTree())) {
+ rw.parseBody(newCommit);
+ rw.parseBody(priorCommit);
boolean messageEq =
Objects.equals(newCommit.getFullMessage(), priorCommit.getFullMessage());
boolean parentsEq = parentsEqual(newCommit, priorCommit);
diff --git a/java/com/google/gerrit/server/restapi/project/GetAccess.java b/java/com/google/gerrit/server/restapi/project/GetAccess.java
index 8875d40..0f46535 100644
--- a/java/com/google/gerrit/server/restapi/project/GetAccess.java
+++ b/java/com/google/gerrit/server/restapi/project/GetAccess.java
@@ -30,13 +30,11 @@
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.common.data.RefConfigSection;
-import com.google.gerrit.common.data.WebLinkInfoCommon;
import com.google.gerrit.extensions.api.access.AccessSectionInfo;
import com.google.gerrit.extensions.api.access.PermissionInfo;
import com.google.gerrit.extensions.api.access.PermissionRuleInfo;
import com.google.gerrit.extensions.api.access.ProjectAccessInfo;
import com.google.gerrit.extensions.common.GroupInfo;
-import com.google.gerrit.extensions.common.WebLinkInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
@@ -149,13 +147,9 @@
// config may have a null revision if the repo doesn't have its own refs/meta/config.
if (config.getRevision() != null) {
- // WebLinks operates in terms of the data types used in the GWT UI. Once the GWT UI is
- // gone, WebLinks should be fixed to use the extension data types.
- for (WebLinkInfoCommon wl :
+ info.configWebLinks.addAll(
webLinks.getFileHistoryLinks(
- projectName.get(), config.getRevision().getName(), ProjectConfig.PROJECT_CONFIG)) {
- info.configWebLinks.add(new WebLinkInfo(wl.name, wl.imageUrl, wl.url, wl.target));
- }
+ projectName.get(), config.getRevision().getName(), ProjectConfig.PROJECT_CONFIG));
}
if (config.updateGroupNames(groupBackend)) {
diff --git a/java/com/google/gerrit/server/schema/Schema_155.java b/java/com/google/gerrit/server/schema/Schema_155.java
index 812d7a6..e9372a5 100644
--- a/java/com/google/gerrit/server/schema/Schema_155.java
+++ b/java/com/google/gerrit/server/schema/Schema_155.java
@@ -40,15 +40,13 @@
@Override
protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException, SQLException {
- @SuppressWarnings("deprecation")
- RepoSequence.Seed accountSeed = db::nextAccountId;
RepoSequence accountSeq =
new RepoSequence(
repoManager,
GitReferenceUpdated.DISABLED,
allUsersName,
Sequences.NAME_ACCOUNTS,
- accountSeed,
+ () -> ReviewDb.FIRST_ACCOUNT_ID,
1);
// consume one account ID to ensure that the account sequence is initialized in NoteDb
diff --git a/java/com/google/gerrit/server/schema/Schema_163.java b/java/com/google/gerrit/server/schema/Schema_163.java
index 9eb5d5e..4b3659de 100644
--- a/java/com/google/gerrit/server/schema/Schema_163.java
+++ b/java/com/google/gerrit/server/schema/Schema_163.java
@@ -40,15 +40,13 @@
@Override
protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException, SQLException {
- @SuppressWarnings("deprecation")
- RepoSequence.Seed groupSeed = db::nextAccountGroupId;
RepoSequence groupSeq =
new RepoSequence(
repoManager,
GitReferenceUpdated.DISABLED,
allUsersName,
Sequences.NAME_GROUPS,
- groupSeed,
+ () -> ReviewDb.FIRST_GROUP_ID,
1);
// consume one account ID to ensure that the group sequence is initialized in NoteDb
diff --git a/java/com/google/gerrit/testing/DisabledReviewDb.java b/java/com/google/gerrit/testing/DisabledReviewDb.java
index 2bf95b0..d06beb9 100644
--- a/java/com/google/gerrit/testing/DisabledReviewDb.java
+++ b/java/com/google/gerrit/testing/DisabledReviewDb.java
@@ -95,16 +95,6 @@
}
@Override
- public int nextAccountId() {
- throw new Disabled();
- }
-
- @Override
- public int nextAccountGroupId() {
- throw new Disabled();
- }
-
- @Override
public int nextChangeId() {
throw new Disabled();
}
diff --git a/java/com/google/gerrit/testing/FakeGroupAuditService.java b/java/com/google/gerrit/testing/FakeGroupAuditService.java
index f2e85cd..ddf03f5 100644
--- a/java/com/google/gerrit/testing/FakeGroupAuditService.java
+++ b/java/com/google/gerrit/testing/FakeGroupAuditService.java
@@ -63,7 +63,10 @@
@Override
public void dispatch(AuditEvent action) {
- auditEvents.add(action);
+ synchronized (auditEvents) {
+ auditEvents.add(action);
+ auditEvents.notifyAll();
+ }
}
@Override
diff --git a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
index f2ee8e1..bb4b728 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
@@ -2010,36 +2010,6 @@
}
@Test
- public void implicitlyCcOnNonVotingReviewGwtStyle() throws Exception {
- testImplicitlyCcOnNonVotingReviewGwtStyle(user);
- }
-
- @Test
- public void implicitlyCcOnNonVotingReviewForUserWithoutUserNameGwtStyle() throws Exception {
- com.google.gerrit.acceptance.TestAccount accountWithoutUsername = accountCreator.create();
- assertThat(accountWithoutUsername.username).isNull();
- testImplicitlyCcOnNonVotingReviewGwtStyle(accountWithoutUsername);
- }
-
- private void testImplicitlyCcOnNonVotingReviewGwtStyle(
- com.google.gerrit.acceptance.TestAccount testAccount) throws Exception {
- PushOneCommit.Result r = createChange();
- setApiUser(testAccount);
- assertThat(getReviewerState(r.getChangeId(), testAccount.id)).isEmpty();
-
- // Exact request format made by GWT UI at ddc6b7160fe416fed9e7e3180489d44c82fd64f8.
- ReviewInput in = new ReviewInput();
- in.labels = ImmutableMap.of("Code-Review", (short) 0);
- in.drafts = DraftHandling.PUBLISH_ALL_REVISIONS;
- in.message = "comment";
- gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).review(in);
-
- // If we're not reading from NoteDb, then the CCed user will be returned in the REVIEWER state.
- assertThat(getReviewerState(r.getChangeId(), testAccount.id))
- .hasValue(notesMigration.readChanges() ? CC : REVIEWER);
- }
-
- @Test
public void implicitlyAddReviewerOnVotingReview() throws Exception {
PushOneCommit.Result r = createChange();
setApiUser(user);
diff --git a/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java b/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java
index 6f25d28..18eb37a 100644
--- a/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java
@@ -89,14 +89,13 @@
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.sql.Timestamp;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.CommitBuilder;
@@ -334,9 +333,6 @@
String p = createUniqueGroup();
String g1 = createUniqueGroup();
String g2 = createUniqueGroup();
- List<String> groups = new ArrayList<>();
- groups.add(g1);
- groups.add(g2);
gApi.groups().id(p).addGroups(g1, g2);
assertIncludes(p, g1, g2);
}
@@ -952,8 +948,8 @@
}
/**
- * @Sandboxed is used by this test because it deletes a group reference which introduces an
- * inconsistency for the group storage. Once group deletion is supported, this test should be
+ * {@code @Sandboxed} is used by this test because it deletes a group reference which introduces
+ * an inconsistency for the group storage. Once group deletion is supported, this test should be
* updated to use the API instead.
*/
@Test
@@ -1001,8 +997,7 @@
TestAccount groupOwner = accountCreator.user2();
GroupInput in = new GroupInput();
in.name = name("group");
- in.members =
- Collections.singleton(groupOwner).stream().map(u -> u.id.toString()).collect(toList());
+ in.members = Stream.of(groupOwner).map(u -> u.id.toString()).collect(toList());
in.visibleToAll = true;
GroupInfo group = gApi.groups().create(in).get();
@@ -1045,7 +1040,7 @@
@Test
public void pushToGroupsBranchForNonAllUsersRepo() throws Exception {
- assertCreateGroupBranch(project, null);
+ assertCreateGroupBranch(project);
String groupRef =
RefNames.refsGroups(new AccountGroup.UUID(gApi.groups().create(name("foo")).get().id));
createBranch(project, groupRef);
@@ -1054,7 +1049,7 @@
@Test
public void pushToDeletedGroupsBranchForNonAllUsersRepo() throws Exception {
- assertCreateGroupBranch(project, null);
+ assertCreateGroupBranch(project);
String groupRef =
RefNames.refsDeletedGroups(
new AccountGroup.UUID(gApi.groups().create(name("foo")).get().id));
@@ -1092,8 +1087,7 @@
}
}
- private void assertCreateGroupBranch(Project.NameKey project, String expectedErrorOnCreate)
- throws Exception {
+ private void assertCreateGroupBranch(Project.NameKey project) throws Exception {
grant(project, RefNames.REFS_GROUPS + "*", Permission.CREATE, false, REGISTERED_USERS);
grant(project, RefNames.REFS_GROUPS + "*", Permission.PUSH, false, REGISTERED_USERS);
TestRepository<InMemoryRepository> repo = cloneProject(project);
@@ -1102,11 +1096,7 @@
.create(db, admin.getIdent(), repo, "Update group", "arbitraryFile.txt", "some content")
.setParents(ImmutableList.of())
.to(RefNames.REFS_GROUPS + name("bar"));
- if (expectedErrorOnCreate != null) {
- r.assertErrorStatus(expectedErrorOnCreate);
- } else {
- r.assertOkStatus();
- }
+ r.assertOkStatus();
}
@Test
@@ -1495,7 +1485,7 @@
private void assertMembers(String group, TestAccount... expectedMembers) throws Exception {
assertMembers(
gApi.groups().id(group).members(),
- TestAccount.names(expectedMembers).stream().toArray(String[]::new));
+ TestAccount.names(expectedMembers).toArray(new String[0]));
assertAccountInfos(Arrays.asList(expectedMembers), gApi.groups().id(group).members());
}
diff --git a/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java b/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
index 254b6ac..7529ee3 100644
--- a/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
+++ b/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
@@ -1476,14 +1476,7 @@
@Test
public void pushSameCommitTwice() throws Exception {
- try (ProjectConfigUpdate u = updateProject(project)) {
- u.getConfig()
- .getProject()
- .setBooleanConfig(
- BooleanProjectConfig.CREATE_NEW_CHANGE_FOR_ALL_NOT_IN_TARGET,
- InheritableBoolean.TRUE);
- u.save();
- }
+ enableCreateNewChangeForAllNotInTarget();
PushOneCommit push =
pushFactory.create(
@@ -1505,14 +1498,7 @@
@Test
public void pushSameCommitTwiceWhenIndexFailed() throws Exception {
- try (ProjectConfigUpdate u = updateProject(project)) {
- u.getConfig()
- .getProject()
- .setBooleanConfig(
- BooleanProjectConfig.CREATE_NEW_CHANGE_FOR_ALL_NOT_IN_TARGET,
- InheritableBoolean.TRUE);
- u.save();
- }
+ enableCreateNewChangeForAllNotInTarget();
PushOneCommit push =
pushFactory.create(
@@ -2368,6 +2354,113 @@
assertPushOk(pr, "refs/heads/permitted");
}
+ @Test
+ public void pushCommitsWithSameTreeNoChanges() throws Exception {
+ RevCommit c =
+ testRepo
+ .commit()
+ .message("Foo")
+ .parent(getHead(testRepo.getRepository()))
+ .insertChangeId()
+ .create();
+ testRepo.reset(c);
+
+ String r = "refs/for/master";
+ PushResult pr = pushHead(testRepo, r, false);
+ assertPushOk(pr, r);
+
+ RevCommit amended = testRepo.amend(c).create();
+ testRepo.reset(amended);
+
+ pr = pushHead(testRepo, r, false);
+ assertPushOk(pr, r);
+ assertThat(pr.getMessages())
+ .contains(
+ "warning: no changes between prior commit "
+ + c.abbreviate(7).name()
+ + " and new commit "
+ + amended.abbreviate(7).name());
+ }
+
+ @Test
+ public void pushCommitsWithSameTreeNoFilesChangedMessageUpdated() throws Exception {
+ RevCommit c =
+ testRepo
+ .commit()
+ .message("Foo")
+ .parent(getHead(testRepo.getRepository()))
+ .insertChangeId()
+ .create();
+ String id = GitUtil.getChangeId(testRepo, c).get();
+ testRepo.reset(c);
+
+ String r = "refs/for/master";
+ PushResult pr = pushHead(testRepo, r, false);
+ assertPushOk(pr, r);
+
+ RevCommit amended =
+ testRepo.amend(c).message("Foo Bar").insertChangeId(id.substring(1)).create();
+ testRepo.reset(amended);
+
+ pr = pushHead(testRepo, r, false);
+ assertPushOk(pr, r);
+ assertThat(pr.getMessages())
+ .contains(
+ "warning: " + amended.abbreviate(7).name() + ": no files changed, message updated");
+ }
+
+ @Test
+ public void pushCommitsWithSameTreeNoFilesChangedAuthorChanged() throws Exception {
+ RevCommit c =
+ testRepo
+ .commit()
+ .message("Foo")
+ .parent(getHead(testRepo.getRepository()))
+ .insertChangeId()
+ .create();
+ testRepo.reset(c);
+
+ String r = "refs/for/master";
+ PushResult pr = pushHead(testRepo, r, false);
+ assertPushOk(pr, r);
+
+ RevCommit amended = testRepo.amend(c).author(user.getIdent()).create();
+ testRepo.reset(amended);
+
+ pr = pushHead(testRepo, r, false);
+ assertPushOk(pr, r);
+ assertThat(pr.getMessages())
+ .contains(
+ "warning: " + amended.abbreviate(7).name() + ": no files changed, author changed");
+ }
+
+ @Test
+ public void pushCommitsWithSameTreeNoFilesChangedWasRebased() throws Exception {
+ RevCommit head = getHead(testRepo.getRepository());
+ RevCommit c = testRepo.commit().message("Foo").parent(head).insertChangeId().create();
+ testRepo.reset(c);
+
+ String r = "refs/for/master";
+ PushResult pr = pushHead(testRepo, r, false);
+ assertPushOk(pr, r);
+
+ testRepo.reset(head);
+ RevCommit newBase = testRepo.commit().message("Base").parent(head).insertChangeId().create();
+ testRepo.reset(newBase);
+
+ pr = pushHead(testRepo, r, false);
+ assertPushOk(pr, r);
+
+ testRepo.reset(c);
+ RevCommit amended = testRepo.amend(c).parent(newBase).create();
+ testRepo.reset(amended);
+
+ pr = pushHead(testRepo, r, false);
+ assertPushOk(pr, r);
+ assertThat(pr.getMessages())
+ .contains("warning: " + amended.abbreviate(7).name() + ": no files changed, was rebased");
+ }
+
private DraftInput newDraft(String path, int line, String message) {
DraftInput d = new DraftInput();
d.path = path;
diff --git a/javatests/com/google/gerrit/acceptance/git/GitOverHttpServletIT.java b/javatests/com/google/gerrit/acceptance/git/GitOverHttpServletIT.java
index 42e046a..90f4134 100644
--- a/javatests/com/google/gerrit/acceptance/git/GitOverHttpServletIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/GitOverHttpServletIT.java
@@ -17,7 +17,9 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.server.AuditEvent;
+import com.google.gerrit.server.audit.HttpAuditEvent;
import java.util.Collections;
+import javax.servlet.http.HttpServletResponse;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
@@ -25,6 +27,7 @@
import org.junit.Test;
public class GitOverHttpServletIT extends AbstractPushForReview {
+ private static final long AUDIT_EVENT_TIMEOUT = 500L;
@Before
public void beforeEach() throws Exception {
@@ -42,6 +45,7 @@
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/for/master"))
.call();
+ waitForAudit();
// Git smart protocol makes two requests:
// https://github.com/git/git/blob/master/Documentation/technical/http-protocol.txt
@@ -51,11 +55,13 @@
assertThat(e.who.getAccountId()).isEqualTo(admin.id);
assertThat(e.what).endsWith("/git-receive-pack");
assertThat(e.params).isEmpty();
+ assertThat(((HttpAuditEvent) e).httpStatus).isEqualTo(HttpServletResponse.SC_OK);
}
@Test
public void uploadPackAuditEventLog() throws Exception {
testRepo.git().fetch().call();
+ waitForAudit();
assertThat(auditService.auditEvents.size()).isEqualTo(1);
@@ -64,5 +70,12 @@
assertThat(e.params.get("service"))
.containsExactlyElementsIn(Collections.singletonList("git-upload-pack"));
assertThat(e.what).endsWith("service=git-upload-pack");
+ assertThat(((HttpAuditEvent) e).httpStatus).isEqualTo(HttpServletResponse.SC_OK);
+ }
+
+ private void waitForAudit() throws InterruptedException {
+ synchronized (auditService.auditEvents) {
+ auditService.auditEvents.wait(AUDIT_EVENT_TIMEOUT);
+ }
}
}
diff --git a/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java b/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java
index 29a5bd0..bb7cff7 100644
--- a/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java
+++ b/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java
@@ -26,11 +26,6 @@
public class ElasticReindexIT extends AbstractReindexTests {
@ConfigSuite.Default
- public static Config elasticsearchV2() {
- return getConfig(ElasticVersion.V2_4);
- }
-
- @ConfigSuite.Config
public static Config elasticsearchV5() {
return getConfig(ElasticVersion.V5_6);
}
@@ -40,6 +35,11 @@
return getConfig(ElasticVersion.V6_5);
}
+ @ConfigSuite.Config
+ public static Config elasticsearchV7() {
+ return getConfig(ElasticVersion.V7_0);
+ }
+
@Override
public void configureIndex(Injector injector) throws Exception {
createAllIndexes(injector);
diff --git a/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java b/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java
index 1e60071..4e88955 100644
--- a/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java
+++ b/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java
@@ -25,11 +25,6 @@
public class ElasticIndexIT extends AbstractIndexTests {
@ConfigSuite.Default
- public static Config elasticsearchV2() {
- return getConfig(ElasticVersion.V2_4);
- }
-
- @ConfigSuite.Config
public static Config elasticsearchV5() {
return getConfig(ElasticVersion.V5_6);
}
@@ -39,6 +34,11 @@
return getConfig(ElasticVersion.V6_5);
}
+ @ConfigSuite.Config
+ public static Config elasticsearchV7() {
+ return getConfig(ElasticVersion.V7_0);
+ }
+
@Override
public void configureIndex(Injector injector) throws Exception {
createAllIndexes(injector);
diff --git a/javatests/com/google/gerrit/elasticsearch/BUILD b/javatests/com/google/gerrit/elasticsearch/BUILD
index 51d45f2..20ef2fa 100644
--- a/javatests/com/google/gerrit/elasticsearch/BUILD
+++ b/javatests/com/google/gerrit/elasticsearch/BUILD
@@ -40,12 +40,12 @@
SUFFIX = "sTest.java"
-ELASTICSEARCH_TESTS = {i: "ElasticQuery" + i.capitalize() + SUFFIX for i in TYPES}
-
ELASTICSEARCH_TESTS_V5 = {i: "ElasticV5Query" + i.capitalize() + SUFFIX for i in TYPES}
ELASTICSEARCH_TESTS_V6 = {i: "ElasticV6Query" + i.capitalize() + SUFFIX for i in TYPES}
+ELASTICSEARCH_TESTS_V7 = {i: "ElasticV7Query" + i.capitalize() + SUFFIX for i in TYPES}
+
ELASTICSEARCH_TAGS = [
"docker",
"elastic",
@@ -53,14 +53,6 @@
]
[junit_tests(
- name = "elasticsearch_query_%ss_test" % name,
- size = "large",
- srcs = [src],
- tags = ELASTICSEARCH_TAGS,
- deps = ELASTICSEARCH_DEPS + [QUERY_TESTS_DEP % name],
-) for name, src in ELASTICSEARCH_TESTS.items()]
-
-[junit_tests(
name = "elasticsearch_query_%ss_test_V5" % name,
size = "large",
srcs = [src],
@@ -76,6 +68,14 @@
deps = ELASTICSEARCH_DEPS + [QUERY_TESTS_DEP % name],
) for name, src in ELASTICSEARCH_TESTS_V6.items()]
+[junit_tests(
+ name = "elasticsearch_query_%ss_test_V7" % name,
+ size = "large",
+ srcs = [src],
+ tags = ELASTICSEARCH_TAGS + ["flaky"],
+ deps = ELASTICSEARCH_DEPS + [QUERY_TESTS_DEP % name],
+) for name, src in ELASTICSEARCH_TESTS_V7.items()]
+
junit_tests(
name = "elasticsearch_tests",
size = "small",
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java b/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
index 0b5ef6e..79e2853 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
@@ -36,14 +36,8 @@
}
}
- public static ElasticContainer<?> createAndStart() {
- return createAndStart(ElasticVersion.V2_4);
- }
-
private static String getImageName(ElasticVersion version) {
switch (version) {
- case V2_4:
- return "elasticsearch:2.4.6-alpine";
case V5_6:
return "docker.elastic.co/elasticsearch/elasticsearch:5.6.13";
case V6_2:
@@ -54,6 +48,8 @@
return "docker.elastic.co/elasticsearch/elasticsearch-oss:6.4.3";
case V6_5:
return "docker.elastic.co/elasticsearch/elasticsearch-oss:6.5.1";
+ case V7_0:
+ return "docker.elastic.co/elasticsearch/elasticsearch-oss:7.0.0-alpha1";
}
throw new IllegalStateException("No tests for version: " + version.name());
}
@@ -65,9 +61,6 @@
@Override
protected void configure() {
addExposedPort(ELASTICSEARCH_DEFAULT_PORT);
-
- // https://github.com/docker-library/elasticsearch/issues/58
- addEnv("-Ees.network.host", "0.0.0.0");
}
@Override
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryAccountsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryAccountsTest.java
index 5d2f944..074debc 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryAccountsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryAccountsTest.java
@@ -52,10 +52,6 @@
}
}
- private String testName() {
- return testName.getMethodName().toLowerCase() + "_";
- }
-
@Override
protected void initAfterLifecycleStart() throws Exception {
super.initAfterLifecycleStart();
@@ -66,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = testName();
+ String indicesPrefix = getSanitizedMethodName();
ElasticTestUtils.configure(
elasticsearchConfig, nodeInfo.port, indicesPrefix, ElasticVersion.V5_6);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryChangesTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryChangesTest.java
index 5d76162..89d0168 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryChangesTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryChangesTest.java
@@ -52,10 +52,6 @@
}
}
- private String testName() {
- return testName.getMethodName().toLowerCase() + "_";
- }
-
@Override
protected void initAfterLifecycleStart() throws Exception {
super.initAfterLifecycleStart();
@@ -66,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = testName();
+ String indicesPrefix = getSanitizedMethodName();
ElasticTestUtils.configure(
elasticsearchConfig, nodeInfo.port, indicesPrefix, ElasticVersion.V5_6);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryGroupsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryGroupsTest.java
index 9ce2e93..79d3ca5 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryGroupsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryGroupsTest.java
@@ -52,10 +52,6 @@
}
}
- private String testName() {
- return testName.getMethodName().toLowerCase() + "_";
- }
-
@Override
protected void initAfterLifecycleStart() throws Exception {
super.initAfterLifecycleStart();
@@ -66,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = testName();
+ String indicesPrefix = getSanitizedMethodName();
ElasticTestUtils.configure(
elasticsearchConfig, nodeInfo.port, indicesPrefix, ElasticVersion.V5_6);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java
index 4184935..247cb29 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java
@@ -52,10 +52,6 @@
}
}
- private String testName() {
- return testName.getMethodName().toLowerCase() + "_";
- }
-
@Override
protected void initAfterLifecycleStart() throws Exception {
super.initAfterLifecycleStart();
@@ -66,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = testName();
+ String indicesPrefix = getSanitizedMethodName();
ElasticTestUtils.configure(
elasticsearchConfig, nodeInfo.port, indicesPrefix, ElasticVersion.V5_6);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryAccountsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryAccountsTest.java
index eeb4c09..519a9c3 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryAccountsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryAccountsTest.java
@@ -52,10 +52,6 @@
}
}
- private String testName() {
- return testName.getMethodName().toLowerCase() + "_";
- }
-
@Override
protected void initAfterLifecycleStart() throws Exception {
super.initAfterLifecycleStart();
@@ -66,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = testName();
+ String indicesPrefix = getSanitizedMethodName();
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java
index 7525b65..690734c 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java
@@ -52,10 +52,6 @@
}
}
- private String testName() {
- return testName.getMethodName().toLowerCase() + "_";
- }
-
@Override
protected void initAfterLifecycleStart() throws Exception {
super.initAfterLifecycleStart();
@@ -66,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = testName();
+ String indicesPrefix = getSanitizedMethodName();
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryGroupsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryGroupsTest.java
index e8d5683..bf0095a 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryGroupsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryGroupsTest.java
@@ -52,10 +52,6 @@
}
}
- private String testName() {
- return testName.getMethodName().toLowerCase() + "_";
- }
-
@Override
protected void initAfterLifecycleStart() throws Exception {
super.initAfterLifecycleStart();
@@ -66,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = testName();
+ String indicesPrefix = getSanitizedMethodName();
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryProjectsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryProjectsTest.java
index eaaf0c8..f2227a9 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryProjectsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryProjectsTest.java
@@ -52,10 +52,6 @@
}
}
- private String testName() {
- return testName.getMethodName().toLowerCase() + "_";
- }
-
@Override
protected void initAfterLifecycleStart() throws Exception {
super.initAfterLifecycleStart();
@@ -66,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = testName();
+ String indicesPrefix = getSanitizedMethodName();
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticQueryAccountsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
similarity index 87%
rename from javatests/com/google/gerrit/elasticsearch/ElasticQueryAccountsTest.java
rename to javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
index 4f0f8b0..7ac9f21 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticQueryAccountsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2016 The Android Open Source Project
+// Copyright (C) 2018 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.
@@ -25,7 +25,7 @@
import org.junit.AfterClass;
import org.junit.BeforeClass;
-public class ElasticQueryAccountsTest extends AbstractQueryAccountsTest {
+public class ElasticV7QueryAccountsTest extends AbstractQueryAccountsTest {
@ConfigSuite.Default
public static Config defaultConfig() {
return IndexConfig.createForElasticsearch();
@@ -41,7 +41,7 @@
return;
}
- container = ElasticContainer.createAndStart();
+ container = ElasticContainer.createAndStart(ElasticVersion.V7_0);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
}
@@ -52,10 +52,6 @@
}
}
- private String testName() {
- return testName.getMethodName().toLowerCase() + "_";
- }
-
@Override
protected void initAfterLifecycleStart() throws Exception {
super.initAfterLifecycleStart();
@@ -66,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = testName();
+ String indicesPrefix = getSanitizedMethodName();
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticQueryChangesTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
similarity index 87%
rename from javatests/com/google/gerrit/elasticsearch/ElasticQueryChangesTest.java
rename to javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
index a02d691..ed6f95b 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticQueryChangesTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2014 The Android Open Source Project
+// Copyright (C) 2018 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.
@@ -25,7 +25,7 @@
import org.junit.AfterClass;
import org.junit.BeforeClass;
-public class ElasticQueryChangesTest extends AbstractQueryChangesTest {
+public class ElasticV7QueryChangesTest extends AbstractQueryChangesTest {
@ConfigSuite.Default
public static Config defaultConfig() {
return IndexConfig.createForElasticsearch();
@@ -41,7 +41,7 @@
return;
}
- container = ElasticContainer.createAndStart();
+ container = ElasticContainer.createAndStart(ElasticVersion.V7_0);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
}
@@ -52,10 +52,6 @@
}
}
- private String testName() {
- return testName.getMethodName().toLowerCase() + "_";
- }
-
@Override
protected void initAfterLifecycleStart() throws Exception {
super.initAfterLifecycleStart();
@@ -66,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = testName();
+ String indicesPrefix = getSanitizedMethodName();
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticQueryGroupsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
similarity index 87%
rename from javatests/com/google/gerrit/elasticsearch/ElasticQueryGroupsTest.java
rename to javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
index f13c491..5efaa4a 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticQueryGroupsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 The Android Open Source Project
+// Copyright (C) 2018 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.
@@ -25,7 +25,7 @@
import org.junit.AfterClass;
import org.junit.BeforeClass;
-public class ElasticQueryGroupsTest extends AbstractQueryGroupsTest {
+public class ElasticV7QueryGroupsTest extends AbstractQueryGroupsTest {
@ConfigSuite.Default
public static Config defaultConfig() {
return IndexConfig.createForElasticsearch();
@@ -41,7 +41,7 @@
return;
}
- container = ElasticContainer.createAndStart();
+ container = ElasticContainer.createAndStart(ElasticVersion.V7_0);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
}
@@ -52,10 +52,6 @@
}
}
- private String testName() {
- return testName.getMethodName().toLowerCase() + "_";
- }
-
@Override
protected void initAfterLifecycleStart() throws Exception {
super.initAfterLifecycleStart();
@@ -66,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = testName();
+ String indicesPrefix = getSanitizedMethodName();
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticQueryProjectsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
similarity index 87%
rename from javatests/com/google/gerrit/elasticsearch/ElasticQueryProjectsTest.java
rename to javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
index dd04010..02b3641 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticQueryProjectsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 The Android Open Source Project
+// Copyright (C) 2018 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.
@@ -25,7 +25,7 @@
import org.junit.AfterClass;
import org.junit.BeforeClass;
-public class ElasticQueryProjectsTest extends AbstractQueryProjectsTest {
+public class ElasticV7QueryProjectsTest extends AbstractQueryProjectsTest {
@ConfigSuite.Default
public static Config defaultConfig() {
return IndexConfig.createForElasticsearch();
@@ -41,7 +41,7 @@
return;
}
- container = ElasticContainer.createAndStart();
+ container = ElasticContainer.createAndStart(ElasticVersion.V7_0);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
}
@@ -52,10 +52,6 @@
}
}
- private String testName() {
- return testName.getMethodName().toLowerCase() + "_";
- }
-
@Override
protected void initAfterLifecycleStart() throws Exception {
super.initAfterLifecycleStart();
@@ -66,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = testName();
+ String indicesPrefix = getSanitizedMethodName();
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java
index 3ab9d5a..baf6c2b 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java
@@ -22,9 +22,6 @@
public class ElasticVersionTest extends GerritBaseTests {
@Test
public void supportedVersion() throws Exception {
- assertThat(ElasticVersion.forVersion("2.4.0")).isEqualTo(ElasticVersion.V2_4);
- assertThat(ElasticVersion.forVersion("2.4.6")).isEqualTo(ElasticVersion.V2_4);
-
assertThat(ElasticVersion.forVersion("5.6.0")).isEqualTo(ElasticVersion.V5_6);
assertThat(ElasticVersion.forVersion("5.6.11")).isEqualTo(ElasticVersion.V5_6);
@@ -36,6 +33,12 @@
assertThat(ElasticVersion.forVersion("6.4.0")).isEqualTo(ElasticVersion.V6_4);
assertThat(ElasticVersion.forVersion("6.4.1")).isEqualTo(ElasticVersion.V6_4);
+
+ assertThat(ElasticVersion.forVersion("6.5.0")).isEqualTo(ElasticVersion.V6_5);
+ assertThat(ElasticVersion.forVersion("6.5.1")).isEqualTo(ElasticVersion.V6_5);
+
+ assertThat(ElasticVersion.forVersion("7.0.0")).isEqualTo(ElasticVersion.V7_0);
+ assertThat(ElasticVersion.forVersion("7.0.1")).isEqualTo(ElasticVersion.V7_0);
}
@Test
@@ -48,9 +51,19 @@
@Test
public void version6() throws Exception {
- assertThat(ElasticVersion.V6_2.isV6()).isTrue();
- assertThat(ElasticVersion.V6_3.isV6()).isTrue();
- assertThat(ElasticVersion.V6_4.isV6()).isTrue();
- assertThat(ElasticVersion.V5_6.isV6()).isFalse();
+ assertThat(ElasticVersion.V5_6.isV6OrLater()).isFalse();
+ assertThat(ElasticVersion.V6_2.isV6OrLater()).isTrue();
+ assertThat(ElasticVersion.V6_3.isV6OrLater()).isTrue();
+ assertThat(ElasticVersion.V6_4.isV6OrLater()).isTrue();
+ assertThat(ElasticVersion.V7_0.isV6OrLater()).isTrue();
+ }
+
+ @Test
+ public void version7() throws Exception {
+ assertThat(ElasticVersion.V5_6.isV7OrLater()).isFalse();
+ assertThat(ElasticVersion.V6_2.isV7OrLater()).isFalse();
+ assertThat(ElasticVersion.V6_3.isV7OrLater()).isFalse();
+ assertThat(ElasticVersion.V6_4.isV7OrLater()).isFalse();
+ assertThat(ElasticVersion.V7_0.isV7OrLater()).isTrue();
}
}
diff --git a/plugins/hooks b/plugins/hooks
index de469e8..25ac76f 160000
--- a/plugins/hooks
+++ b/plugins/hooks
@@ -1 +1 @@
-Subproject commit de469e8e2598779773652abb43a0356650e257b3
+Subproject commit 25ac76fe18537c33f9f27c5463a081449c13ba67
diff --git a/resources/com/google/gerrit/reviewdb/server/index_postgres.sql b/resources/com/google/gerrit/reviewdb/server/index_postgres.sql
index f2f24e1..439fed7 100644
--- a/resources/com/google/gerrit/reviewdb/server/index_postgres.sql
+++ b/resources/com/google/gerrit/reviewdb/server/index_postgres.sql
@@ -8,7 +8,6 @@
ALTER TABLE patch_comments CLUSTER ON patch_comments_pkey;
ALTER TABLE patch_set_approvals CLUSTER ON patch_set_approvals_pkey;
-ALTER TABLE account_group_members CLUSTER ON account_group_members_pkey;
CLUSTER;