Merge "Add frontend option to skip diff computations for change details."
diff --git a/.bazelrc b/.bazelrc
index 8b1abd6..d6d4ce6 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -4,7 +4,6 @@
build --action_env=PATH
build --disk_cache=~/.gerritcodereview/bazel-cache/cas
build --java_toolchain //tools:error_prone_warnings_toolchain
-build --incompatible_disallow_load_labels_to_cross_package_boundaries=false
test --build_tests_only
test --test_output=errors
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 5b1c151..91cb87f 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -2046,14 +2046,6 @@
By default unset, meaning no bug report URL will be displayed. Administrators
should set this to the URL of their issue tracker, if necessary.
-[[gerrit.reportBugText]]gerrit.reportBugText::
-+
-Text to be displayed in the link to the bug report URL.
-+
-Only used when `gerrit.reportBugUrl` is set.
-+
-Defaults to "Report Bug".
-
[[gerrit.enableReverseDnsLookup]]gerrit.enableReverseDnsLookup::
+
Enable reverse DNS lookup during computing ref log entry for identified user,
@@ -3516,17 +3508,6 @@
If no groups are added, any user will be allowed to execute
'receive-pack' on the server.
-[[receive.allowPushToRefsChanges]]receive.allowPushToRefsChanges::
-+
-If true, it is possible to push directly to a change using `refs/changes/`.
-The possibility to push to `refs/changes/` is deprecated and it might be
-removed in future releases.
-See link:user-upload.html#manual_replacement_mapping[Manual Replacement Mapping].
-+
-False means pushing to `refs/changes/` is prohibited.
-+
-Defaults to false.
-
[[receive.certNonceSeed]]receive.certNonceSeed::
+
If set to a non-empty value and server-side signed push validation is
@@ -3809,6 +3790,14 @@
Defaults to link:#retry.timeout[`retry.timeout`]; unit suffixes are supported,
and assumes milliseconds if not specified.
+[[retry.retryWithTraceOnFailure]]retry.retryWithTraceOnFailure::
++
+Whether Gerrit should automatically retry operations on failure with tracing
+enabled. The automatically generated traces can help with debugging. Please
+note that only some of the REST endpoints support automatic retry.
++
+By default this is set to false.
+
[[rules]]
=== Section rules
@@ -4571,6 +4560,52 @@
+
By default, true.
+[[tracing.traceid]]
+==== Subsection tracing.<trace-id>
+
+There can be multiple `tracing.<trace-id>` subsections to configure
+automatic tracing of requests. To be traced a request must match all
+conditions of one `tracing.<trace-id>` subsection. The subsection name
+is used as trace ID. Using this trace ID administrators can find
+matching log entries.
+
+[[tracing.traceid.requestType]]tracing.<trace-id>.requestType::
++
+Type of request for which request tracing should be always enabled (can
+be `GIT_RECEIVE`, `GIT_UPLOAD`, `REST` and `SSH`).
++
+May be specified multiple times.
++
+By default, unset (all request types are matched).
+
+[[tracing.traceid.requestUriPattern]]tracing.<trace-id>.requestUriPattern::
++
+Regular expression to match request URIs for which request tracing
+should be always enabled. Request URIs are only available for REST
+requests. Request URIs never include the '/a' prefix.
++
+May be specified multiple times.
++
+By default, unset (all request URIs are matched).
+
+[[tracing.traceid.account]]tracing.<trace-id>.account::
++
+Account ID of an account for which request tracing should be always
+enabled.
++
+May be specified multiple times.
++
+By default, unset (all accounts are matched).
+
+[[tracing.traceid.projectPattern]]tracing.<trace-id>.projectPattern::
++
+Regular expression to match project names for which request tracing
+should be always enabled.
++
+May be specified multiple times.
++
+By default, unset (all projects are matched).
+
[[trackingid]]
=== Section trackingid
diff --git a/Documentation/config-labels.txt b/Documentation/config-labels.txt
index ff43520..9c90ba7 100644
--- a/Documentation/config-labels.txt
+++ b/Documentation/config-labels.txt
@@ -297,12 +297,13 @@
[[label_copyAllScoresOnTrivialRebase]]
=== `label.Label-Name.copyAllScoresOnTrivialRebase`
-If true, all scores for the label are copied forward when a new patch
-set is uploaded that is a trivial rebase. A new patch set is considered
-as trivial rebase if the commit message is the same as in the previous
-patch set and if it has the same code delta as the previous patch set.
-This is the case if the change was rebased onto a different parent, or
-if the parent did not change at all.
+If true, all scores for the label are copied forward when a new patch set is
+uploaded that is a trivial rebase. A new patch set is considered to be trivial
+rebase if the commit message is the same as in the previous patch set and if it
+has the same diff (including context lines) as the previous patch set. This is
+the case if the change was rebased onto a different parent and that rebase did
+not require git to perform any conflict resolution, or if the parent did not
+change at all.
This can be used to enable sticky approvals, reducing turn-around for
trivial rebases prior to submitting a change.
@@ -313,13 +314,13 @@
[[label_copyAllScoresIfNoCodeChange]]
=== `label.Label-Name.copyAllScoresIfNoCodeChange`
-If true, all scores for the label are copied forward when a new patch
-set is uploaded that has the same parent tree as the previous patch
-set and the same code delta as the previous patch set. This means only
-the commit message is different. This can be used to enable sticky
-approvals on labels that only depend on the code, reducing turn-around
-if only the commit message is changed prior to submitting a change.
-For the Verified label that is optionally installed by the
+If true, all scores for the label are copied forward when a new patch set is
+uploaded that has the same parent tree as the previous patch set and the same
+code diff (including context lines) as the previous patch set. This means only
+the commit message is different; the change hasn't even been rebased. This can
+be used to enable sticky approvals on labels that only depend on the code,
+reducing turn-around if only the commit message is changed prior to submitting a
+change. For the Verified label that is optionally installed by the
link:pgm-init.html[init] site program this is enabled by default.
Defaults to false.
diff --git a/Documentation/config-project-config.txt b/Documentation/config-project-config.txt
index 91a054a..08c26d4 100644
--- a/Documentation/config-project-config.txt
+++ b/Documentation/config-project-config.txt
@@ -157,32 +157,6 @@
did what, especially with patches. Default is `INHERIT`, which means that this
property is inherited from the parent project.
-[[receive.requireChangeId]]receive.requireChangeId::
-+
-The `Require Change-Id in commit message` option defines whether a
-link:user-changeid.html[Change-Id] in the commit message is required
-for pushing a commit for review. If this option is set, trying to push
-a commit for review that doesn't contain a Change-Id in the commit
-message fails with link:error-missing-changeid.html[missing Change-Id
-in commit message footer].
-
-It is recommended to set this option and use a
-link:user-changeid.html#create[commit-msg hook] (or other client side
-tooling like EGit) to automatically generate Change-Id's for new
-commits. This way the Change-Id is automatically in place when changes
-are reworked or rebased and uploading new patch sets gets easy.
-
-If this option is not set, commits can be uploaded without a Change-Id,
-but then users have to remember to copy the assigned Change-Id from the
-change screen and insert it manually into the commit message when they
-want to upload a second patch set.
-
-Default is `INHERIT`, which means that this property is inherited from
-the parent project. The global default for new hosts is `true`
-
-This option is deprecated and future releases will behave as if this
-is always `true`.
-
[[receive.maxObjectSizeLimit]]receive.maxObjectSizeLimit::
+
Maximum allowed Git object size that receive-pack will accept. If an object
@@ -321,7 +295,7 @@
- 'action': defines the link:#submit-type[submit type]. Valid
values are 'fast forward only', 'merge if necessary', 'rebase if necessary',
-'merge always' and 'cherry pick'. The default is 'merge if necessary'.
+'rebase always', 'merge always' and 'cherry pick'. The default is 'merge if necessary'.
- 'matchAuthorToCommitterDate': Defines whether to the author date will be changed to match the
submitter date upon submit, so that git log shows when the change was submitted instead of when the
@@ -494,8 +468,9 @@
[[fast_forward_only]]
* Fast Forward Only
+
-With this method no merge commits are produced. All merges must
-be handled on the client, prior to uploading to Gerrit for review.
+With this method Gerrit does not create merge commits on submitting a
+change. Merge commits may still be submitted, but they must be created
+on the client prior to uploading to Gerrit for review.
+
To submit a change, the change must be a strict superset of the
destination branch. That is, the change must already contain the
@@ -545,7 +520,7 @@
branch, then the branch is fast-forwarded to the change. If not,
then the change is automatically rebased and then the branch is
fast-forwarded to the change.
-
++
When Gerrit tries to do a merge, by default the merge will only
succeed if there is no path conflict. A path conflict occurs when
the same file has also been changed on the other side of the merge.
@@ -557,7 +532,7 @@
if fast forward is possible AND like Cherry Pick it ensures footers such as
Change-Id, Reviewed-On, and others are present in resulting commit that is
merged.
-
++
Thus, Rebase Always can be considered similar to Cherry Pick, but with
the important distinction that Rebase Always does not ignore dependencies.
diff --git a/Documentation/dev-plugins.txt b/Documentation/dev-plugins.txt
index 72b92a7..198e000 100644
--- a/Documentation/dev-plugins.txt
+++ b/Documentation/dev-plugins.txt
@@ -2678,7 +2678,7 @@
// Implement your submitability logic here
// Assuming we want to prevent this change from being submitted:
- SubmitRecord record;
+ SubmitRecord record = new SubmitRecord();
record.status = Status.NOT_READY;
return record;
}
@@ -2810,6 +2810,12 @@
end of a request (REST call, SSH call, git push). Implementors can write the
execution times into a performance log for further analysis.
+[[request-listener]]
+== Request Listener
+
+`com.google.gerrit.server.RequestListener` is an extension point that is
+invoked each time the server executes a request from a user.
+
[[plugins_hosting]]
== Plugins source code hosting
diff --git a/Documentation/dev-roles.txt b/Documentation/dev-roles.txt
index b039489..89b1436 100644
--- a/Documentation/dev-roles.txt
+++ b/Documentation/dev-roles.txt
@@ -199,6 +199,8 @@
* create events in the
link:https://calendar.google.com/calendar?cid=Z29vZ2xlLmNvbV91YmIxcGxhNmlqNzg1b3FianI2MWg0dmRpc0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t[
community calendar]
+* discuss with other maintainers on the private maintainers mailing
+ list and Slack channel
In addition, maintainers from Google can:
diff --git a/Documentation/pg-plugin-dev.txt b/Documentation/pg-plugin-dev.txt
index e5404c7..8fb5655 100644
--- a/Documentation/pg-plugin-dev.txt
+++ b/Documentation/pg-plugin-dev.txt
@@ -30,15 +30,13 @@
``` html
<dom-module id="my-plugin">
- <template>
- <script>
- Gerrit.install(plugin => {
- 'use strict';
+ <script>
+ Gerrit.install(plugin => {
+ 'use strict';
- // Your code here.
- });
- </script>
- </template>
+ // Your code here.
+ });
+ </script>
</dom-module>
```
diff --git a/Documentation/pg-plugin-styling.txt b/Documentation/pg-plugin-styling.txt
index c1e398e..2453bad 100644
--- a/Documentation/pg-plugin-styling.txt
+++ b/Documentation/pg-plugin-styling.txt
@@ -25,7 +25,7 @@
<dom-module id="some-style">
<template>
<style>
- :root {
+ html {
--css-mixin-name: {
property: value;
}
diff --git a/Documentation/rest-api-config.txt b/Documentation/rest-api-config.txt
index 3ea3ba1..96b376d 100644
--- a/Documentation/rest-api-config.txt
+++ b/Documentation/rest-api-config.txt
@@ -1799,9 +1799,6 @@
Whether to enable the web UI for editing GPG keys.
|`report_bug_url` |optional|
link:config-gerrit.html#gerrit.reportBugUrl[URL to report bugs].
-|`report_bug_text` |optional, not set if default|
-link:config-gerrit.html#gerrit.reportBugText[Display text for report
-bugs link].
|=================================
[[hit-ration-info]]
diff --git a/Documentation/rest-api-projects.txt b/Documentation/rest-api-projects.txt
index f69c4ae..1544aae 100644
--- a/Documentation/rest-api-projects.txt
+++ b/Documentation/rest-api-projects.txt
@@ -824,11 +824,6 @@
"configured_value": "INHERIT",
"inherited_value": false
},
- "require_change_id": {
- "value": false,
- "configured_value": "FALSE",
- "inherited_value": true
- },
"max_object_size_limit": {
"value": "15m",
"configured_value": "15m",
@@ -887,7 +882,6 @@
"enable_signed_push": "INHERIT",
"require_signed_push": "INHERIT",
"reject_implicit_merges": "INHERIT",
- "require_change_id": "TRUE",
"max_object_size_limit": "10m",
"submit_type": "REBASE_IF_NECESSARY",
"state": "ACTIVE"
@@ -925,11 +919,6 @@
"configured_value": "INHERIT",
"inherited_value": false
},
- "require_change_id": {
- "value": true,
- "configured_value": "TRUE",
- "inherited_value": true
- },
"enable_signed_push": {
"value": true,
"configured_value": "INHERIT",
@@ -3094,12 +3083,6 @@
|`create_new_change_for_all_not_in_target` |optional|
link:#inherited-boolean-info[InheritedBooleanInfo] that tells whether
a new change is created for every commit not in target branch.
-|`require_change_id` |optional|
-link:#inherited-boolean-info[InheritedBooleanInfo] that tells whether a
-valid link:user-changeid.html[Change-Id] footer in any commit uploaded
-for review is required. This does not apply to commits pushed directly
-to a branch or tag. This property is deprecated and will be removed in
-a future release.
|`enable_signed_push`|optional, not set if signed push is disabled|
link:#inherited-boolean-info[InheritedBooleanInfo] that tells whether
signed push validation is enabled on the project.
@@ -3180,14 +3163,6 @@
branch. +
Can be `TRUE`, `FALSE` or `INHERIT`. +
If not set, this setting is not updated.
-|`require_change_id` |optional|
-Whether a valid link:user-changeid.html[Change-Id] footer in any commit
-uploaded for review is required. This does not apply to commits pushed
-directly to a branch or tag. +
-Can be `TRUE`, `FALSE` or `INHERIT`. +
-If not set, this setting is not updated.
-This property is deprecated and will be removed in
-a future release.
|`reject_implicit_merges` |optional|
Whether a check for implicit merges will be performed when changes
are pushed for review. +
@@ -3553,11 +3528,6 @@
Whether content merge should be enabled for the project (`TRUE`,
`FALSE`, `INHERIT`). +
`FALSE`, if the `submit_type` is `FAST_FORWARD_ONLY`.
-|`require_change_id` |`INHERIT` if not set|
-Whether the usage of Change-Ids is required for the project (`TRUE`,
-`FALSE`, `INHERIT`).
-This property is deprecated and will be removed in
-a future release.
|`enable_signed_push` |`INHERIT` if not set|
Whether signed push validation is enabled on the project (`TRUE`,
`FALSE`, `INHERIT`).
diff --git a/Documentation/user-search.txt b/Documentation/user-search.txt
index cc3ac42..bee723e 100644
--- a/Documentation/user-search.txt
+++ b/Documentation/user-search.txt
@@ -53,7 +53,7 @@
+
Amount of time that has expired since the change was last updated
with a review comment or new patch set. The age must be specified
-to include a unit suffix, for example `age:2d`:
+to include a unit suffix, for example `-age:2d`:
+
* s, sec, second, seconds
* m, min, minute, minutes
@@ -63,6 +63,10 @@
* mon, month, months (`1 month` is treated as `30 days`)
* y, year, years (`1 year` is treated as `365 days`)
+`age` can be used both forward and backward looking: `age:2d`
+means 'everything older than 2 days' while `-age:2d` means
+'everything with an age of at most 2 days'.
+
[[assignee]]
assignee:'USER'::
+
diff --git a/Documentation/user-upload.txt b/Documentation/user-upload.txt
index 56602e2..5bf49cd 100644
--- a/Documentation/user-upload.txt
+++ b/Documentation/user-upload.txt
@@ -470,69 +470,6 @@
For more about Change-Ids, see link:user-changeid.html[Change-Id Lines].
-[[manual_replacement_mapping]]
-==== Manual Replacement Mapping
-
-[NOTE]
---
-The remainder of this section describes a manual method of replacing
-changes by matching each commit name to an existing change number.
-End-users should instead prefer to use Change-Id lines in their
-commit messages, as the process is then fully automated by Gerrit
-during normal uploads.
-
-See above for the preferred technique of replacing changes.
-
-Pushing directly to `refs/changes/` is deprecated. If you see the error
-message 'upload to refs/changes not allowed', it means that pushing directly
-to `refs/changes` is disabled on the Gerrit server and the below section does
-not apply to you.
---
-
-To add an additional patch set to a change, replacing it with an
-updated version of the same logical modification, send the new
-commit to the change's ref. For example, to add the commit whose
-SHA-1 starts with `c0ffee` as a new patch set for change number
-`1979`, use the push refspec `c0ffee:refs/changes/1979` as below:
-
-----
- git push ssh://sshusername@hostname:29418/projectname c0ffee:refs/changes/1979
-----
-
-This form can be combined together with `refs/for/'branchname'`
-(above) to simultaneously create new changes and replace changes
-during one network transaction.
-
-For example, consider the following sequence of events:
-
-----
- $ git commit -m A ; # create 3 commits
- $ git commit -m B
- $ git commit -m C
-
- $ git push ... HEAD:refs/for/master ; # upload for review
- ... A is 1500 ...
- ... B is 1501 ...
- ... C is 1502 ...
-
- $ git rebase -i HEAD~3 ; # edit "A", insert D before B
- ; # now series is A'-D-B'-C'
- $ git push ...
- HEAD:refs/for/master
- HEAD~3:refs/changes/1500
- HEAD~1:refs/changes/1501
- HEAD~0:refs/changes/1502 ; # upload replacements
-----
-
-At the final step during the push Gerrit will attach A' as a new
-patch set on change 1500; B' as a new patch set on change 1501; C'
-as a new patch set on 1502; and D will be created as a new change.
-
-Ensuring D is created as a new change requires passing the refspec
-`HEAD:refs/for/branchname`, otherwise Gerrit will ignore D and
-won't do anything with it. For this reason it is a good idea to
-always include the create change refspec when uploading replacements.
-
[[bypass_review]]
=== Bypass Review
diff --git a/WORKSPACE b/WORKSPACE
index 53daa1c..ece7706 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -752,8 +752,8 @@
# Keep this version of Soy synchronized with the version used in Gitiles.
maven_jar(
name = "soy",
- artifact = "com.google.template:soy:2019-04-18",
- sha1 = "5750208855562d74f29eee39ee497d5cf6df1490",
+ artifact = "com.google.template:soy:2019-07-14",
+ sha1 = "547dee679bac6011126f3a54619d3aec336216d0",
)
maven_jar(
@@ -882,30 +882,30 @@
sha1 = "42a25dc3219429f0e5d060061f71acb49bf010a0",
)
-TRUTH_VERS = "0.46"
+TRUTH_VERS = "1.0"
maven_jar(
name = "truth",
artifact = "com.google.truth:truth:" + TRUTH_VERS,
- sha1 = "5907b14d1af802644e7f4fb7230419b709e06c6b",
+ sha1 = "998e5fb3fa31df716574b4c9e8d374855e800451",
)
maven_jar(
name = "truth-java8-extension",
artifact = "com.google.truth.extensions:truth-java8-extension:" + TRUTH_VERS,
- sha1 = "e5ef57a6d1ab57695d373754df1efdddffc8484c",
+ sha1 = "d85fbc1daf0510821f552f2aa71d9605e97aa438",
)
maven_jar(
name = "truth-liteproto-extension",
artifact = "com.google.truth.extensions:truth-liteproto-extension:" + TRUTH_VERS,
- sha1 = "c624d921293426bac9e5c9780b01eaef914c1a22",
+ sha1 = "7a279c50a0f93da15533cef4993b45606cf67d72",
)
maven_jar(
name = "truth-proto-extension",
artifact = "com.google.truth.extensions:truth-proto-extension:" + TRUTH_VERS,
- sha1 = "585a0cedb3dac53ad3349826f163b28e59000d39",
+ sha1 = "8c0c2ea61750f02d0d5ce9c653106b6a5dc82d12",
)
maven_jar(
@@ -1062,8 +1062,8 @@
# and httpasyncclient as necessary.
maven_jar(
name = "elasticsearch-rest-client",
- artifact = "org.elasticsearch.client:elasticsearch-rest-client:7.1.1",
- sha1 = "ca04d8012f92cac561be343b931ec73302b2ff3e",
+ artifact = "org.elasticsearch.client:elasticsearch-rest-client:7.2.0",
+ sha1 = "39cf34068b0af284eaa9b8bd86a131cb24b322d5",
)
maven_jar(
@@ -1072,18 +1072,18 @@
sha1 = "0f5a654e4675769c716e5b387830d19b501ca191",
)
-TESTCONTAINERS_VERSION = "1.11.3"
+TESTCONTAINERS_VERSION = "1.11.4"
maven_jar(
name = "testcontainers",
artifact = "org.testcontainers:testcontainers:" + TESTCONTAINERS_VERSION,
- sha1 = "154b69dd976416734b2fc809fb86e173ad9aa25b",
+ sha1 = "b0c70b1a3608f43deafba7649b344a422a442585",
)
maven_jar(
name = "testcontainers-elasticsearch",
artifact = "org.testcontainers:elasticsearch:" + TESTCONTAINERS_VERSION,
- sha1 = "90713b61f5748d8894c31a20f955bd7f81ac2ece",
+ sha1 = "faab09a8876b8dbb326cbc10bbaa5ea86f5f5299",
)
maven_jar(
diff --git a/java/com/google/gerrit/acceptance/AbstractDaemonTest.java b/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
index 197a6a3..8818ade 100644
--- a/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
+++ b/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
@@ -888,15 +888,6 @@
}
}
- protected void setRequireChangeId(InheritableBoolean value) throws Exception {
- try (MetaDataUpdate md = metaDataUpdateFactory.create(project)) {
- ProjectConfig config = projectConfigFactory.read(md);
- config.getProject().setBooleanConfig(BooleanProjectConfig.REQUIRE_CHANGE_ID, value);
- config.commit(md);
- projectCache.evict(config.getProject());
- }
- }
-
protected PushOneCommit.Result pushTo(String ref) throws Exception {
PushOneCommit push = pushFactory.create(admin.newIdent(), testRepo);
return push.to(ref);
diff --git a/java/com/google/gerrit/acceptance/TestProjectInput.java b/java/com/google/gerrit/acceptance/TestProjectInput.java
index 0a3686b..7deb88a 100644
--- a/java/com/google/gerrit/acceptance/TestProjectInput.java
+++ b/java/com/google/gerrit/acceptance/TestProjectInput.java
@@ -43,8 +43,6 @@
InheritableBoolean useContentMerge() default InheritableBoolean.INHERIT;
- InheritableBoolean requireChangeId() default InheritableBoolean.INHERIT;
-
InheritableBoolean rejectEmptyCommit() default InheritableBoolean.INHERIT;
InheritableBoolean enableSignedPush() default InheritableBoolean.INHERIT;
diff --git a/java/com/google/gerrit/common/data/testing/GroupReferenceSubject.java b/java/com/google/gerrit/common/data/testing/GroupReferenceSubject.java
index b65f64b..8ac0de1 100644
--- a/java/com/google/gerrit/common/data/testing/GroupReferenceSubject.java
+++ b/java/com/google/gerrit/common/data/testing/GroupReferenceSubject.java
@@ -21,6 +21,7 @@
import com.google.common.truth.StringSubject;
import com.google.common.truth.Subject;
import com.google.gerrit.common.data.GroupReference;
+import com.google.gerrit.reviewdb.client.AccountGroup;
public class GroupReferenceSubject extends Subject {
@@ -39,7 +40,7 @@
this.group = group;
}
- public ComparableSubject groupUuid() {
+ public ComparableSubject<AccountGroup.UUID> groupUuid() {
isNotNull();
return check("getUUID()").that(group.getUUID());
}
diff --git a/java/com/google/gerrit/elasticsearch/ElasticVersion.java b/java/com/google/gerrit/elasticsearch/ElasticVersion.java
index 6be41c8..e608e93 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticVersion.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticVersion.java
@@ -26,7 +26,8 @@
V6_6("6.6.*"),
V6_7("6.7.*"),
V7_0("7.0.*"),
- V7_1("7.1.*");
+ V7_1("7.1.*"),
+ V7_2("7.2.*");
private final String version;
private final Pattern pattern;
diff --git a/java/com/google/gerrit/extensions/api/changes/NotifyInfo.java b/java/com/google/gerrit/extensions/api/changes/NotifyInfo.java
index ef49651..14e0cdc 100644
--- a/java/com/google/gerrit/extensions/api/changes/NotifyInfo.java
+++ b/java/com/google/gerrit/extensions/api/changes/NotifyInfo.java
@@ -20,6 +20,10 @@
public class NotifyInfo {
public List<String> accounts;
+ /**
+ * @param accounts may be either just a list of: account IDs, Full names, usernames, or emails.
+ * Also could be a list of those: "Full name <email@example.com>" or "Full name (<ID>)"
+ */
public NotifyInfo(List<String> accounts) {
this.accounts = accounts;
}
diff --git a/java/com/google/gerrit/extensions/api/projects/ConfigInfo.java b/java/com/google/gerrit/extensions/api/projects/ConfigInfo.java
index fb2a0fe..eddfb09 100644
--- a/java/com/google/gerrit/extensions/api/projects/ConfigInfo.java
+++ b/java/com/google/gerrit/extensions/api/projects/ConfigInfo.java
@@ -29,7 +29,6 @@
public InheritedBooleanInfo useContentMerge;
public InheritedBooleanInfo useSignedOffBy;
public InheritedBooleanInfo createNewChangeForAllNotInTarget;
- public InheritedBooleanInfo requireChangeId;
public InheritedBooleanInfo enableSignedPush;
public InheritedBooleanInfo requireSignedPush;
public InheritedBooleanInfo rejectImplicitMerges;
diff --git a/java/com/google/gerrit/extensions/api/projects/ConfigInput.java b/java/com/google/gerrit/extensions/api/projects/ConfigInput.java
index 1a6d77b..44a5258 100644
--- a/java/com/google/gerrit/extensions/api/projects/ConfigInput.java
+++ b/java/com/google/gerrit/extensions/api/projects/ConfigInput.java
@@ -25,7 +25,6 @@
public InheritableBoolean useContentMerge;
public InheritableBoolean useSignedOffBy;
public InheritableBoolean createNewChangeForAllNotInTarget;
- public InheritableBoolean requireChangeId;
public InheritableBoolean enableSignedPush;
public InheritableBoolean requireSignedPush;
public InheritableBoolean rejectImplicitMerges;
diff --git a/java/com/google/gerrit/extensions/api/projects/ProjectInput.java b/java/com/google/gerrit/extensions/api/projects/ProjectInput.java
index e61d316..2dec2b9 100644
--- a/java/com/google/gerrit/extensions/api/projects/ProjectInput.java
+++ b/java/com/google/gerrit/extensions/api/projects/ProjectInput.java
@@ -31,7 +31,6 @@
public InheritableBoolean useContributorAgreements;
public InheritableBoolean useSignedOffBy;
public InheritableBoolean useContentMerge;
- public InheritableBoolean requireChangeId;
public InheritableBoolean createNewChangeForAllNotInTarget;
public InheritableBoolean rejectEmptyCommit;
public InheritableBoolean enableSignedPush;
diff --git a/java/com/google/gerrit/extensions/client/Comment.java b/java/com/google/gerrit/extensions/client/Comment.java
index 3bca4bb..d5fbf89 100644
--- a/java/com/google/gerrit/extensions/client/Comment.java
+++ b/java/com/google/gerrit/extensions/client/Comment.java
@@ -30,7 +30,9 @@
public String path;
public Side side;
public Integer parent;
- public Integer line; // value 0 or null indicates a file comment, normal lines start at 1
+ /** Value 0 or null indicates a file comment, normal lines start at 1. */
+ public Integer line;
+
public Range range;
public String inReplyTo;
public Timestamp updated;
diff --git a/java/com/google/gerrit/extensions/common/AvatarInfo.java b/java/com/google/gerrit/extensions/common/AvatarInfo.java
index 00f1819..de609eb 100644
--- a/java/com/google/gerrit/extensions/common/AvatarInfo.java
+++ b/java/com/google/gerrit/extensions/common/AvatarInfo.java
@@ -21,7 +21,7 @@
* <p>The web UI prefers avatar images to be square, both the height and width of the image should
* be this size. The height is the more important dimension to match than the width.
*/
- public static final int DEFAULT_SIZE = 26;
+ public static final int DEFAULT_SIZE = 32;
public String url;
public Integer height;
diff --git a/java/com/google/gerrit/extensions/common/GerritInfo.java b/java/com/google/gerrit/extensions/common/GerritInfo.java
index 4746273..5c462d9 100644
--- a/java/com/google/gerrit/extensions/common/GerritInfo.java
+++ b/java/com/google/gerrit/extensions/common/GerritInfo.java
@@ -21,6 +21,5 @@
public String docUrl;
public Boolean editGpgKeys;
public String reportBugUrl;
- public String reportBugText;
public String primaryWeblinkName;
}
diff --git a/java/com/google/gerrit/extensions/common/testing/DiffInfoSubject.java b/java/com/google/gerrit/extensions/common/testing/DiffInfoSubject.java
index c94dc27..8853a30 100644
--- a/java/com/google/gerrit/extensions/common/testing/DiffInfoSubject.java
+++ b/java/com/google/gerrit/extensions/common/testing/DiffInfoSubject.java
@@ -21,6 +21,7 @@
import com.google.common.truth.ComparableSubject;
import com.google.common.truth.FailureMetadata;
import com.google.common.truth.Subject;
+import com.google.gerrit.extensions.common.ChangeType;
import com.google.gerrit.extensions.common.DiffInfo;
import com.google.gerrit.extensions.common.DiffInfo.ContentEntry;
import com.google.gerrit.truth.ListSubject;
@@ -45,7 +46,7 @@
.thatCustom(diffInfo.content, ContentEntrySubject.contentEntries());
}
- public ComparableSubject changeType() {
+ public ComparableSubject<ChangeType> changeType() {
isNotNull();
return check("changeType").that(diffInfo.changeType);
}
diff --git a/java/com/google/gerrit/extensions/common/testing/FileInfoSubject.java b/java/com/google/gerrit/extensions/common/testing/FileInfoSubject.java
index 35e67a6..d011d5d 100644
--- a/java/com/google/gerrit/extensions/common/testing/FileInfoSubject.java
+++ b/java/com/google/gerrit/extensions/common/testing/FileInfoSubject.java
@@ -45,7 +45,7 @@
return check("linesDeleted").that(fileInfo.linesDeleted);
}
- public ComparableSubject status() {
+ public ComparableSubject<Character> status() {
isNotNull();
return check("status").that(fileInfo.status);
}
diff --git a/java/com/google/gerrit/extensions/common/testing/GitPersonSubject.java b/java/com/google/gerrit/extensions/common/testing/GitPersonSubject.java
index 5564642..d827d5d 100644
--- a/java/com/google/gerrit/extensions/common/testing/GitPersonSubject.java
+++ b/java/com/google/gerrit/extensions/common/testing/GitPersonSubject.java
@@ -23,6 +23,7 @@
import com.google.common.truth.StringSubject;
import com.google.common.truth.Subject;
import com.google.gerrit.extensions.common.GitPerson;
+import java.sql.Timestamp;
import java.util.Date;
import org.eclipse.jgit.lib.PersonIdent;
@@ -53,7 +54,7 @@
return check("email").that(gitPerson.email);
}
- public ComparableSubject date() {
+ public ComparableSubject<Timestamp> date() {
isNotNull();
return check("date").that(gitPerson.date);
}
diff --git a/java/com/google/gerrit/httpd/BUILD b/java/com/google/gerrit/httpd/BUILD
index 5009211..f86b35d5 100644
--- a/java/com/google/gerrit/httpd/BUILD
+++ b/java/com/google/gerrit/httpd/BUILD
@@ -13,6 +13,7 @@
"//java/com/google/gerrit/exceptions",
"//java/com/google/gerrit/extensions:api",
"//java/com/google/gerrit/git",
+ "//java/com/google/gerrit/index:query_exception",
"//java/com/google/gerrit/json",
"//java/com/google/gerrit/launcher",
"//java/com/google/gerrit/lifecycle",
diff --git a/java/com/google/gerrit/httpd/GitOverHttpServlet.java b/java/com/google/gerrit/httpd/GitOverHttpServlet.java
index 23afbd3..d66e8ac 100644
--- a/java/com/google/gerrit/httpd/GitOverHttpServlet.java
+++ b/java/com/google/gerrit/httpd/GitOverHttpServlet.java
@@ -26,6 +26,8 @@
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.RequestInfo;
+import com.google.gerrit.server.RequestListener;
import com.google.gerrit.server.audit.HttpAuditEvent;
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.git.DefaultAdvertiseRefsHook;
@@ -35,6 +37,7 @@
import com.google.gerrit.server.git.receive.AsyncReceiveCommits;
import com.google.gerrit.server.git.validators.UploadValidators;
import com.google.gerrit.server.group.GroupAuditService;
+import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackend.RefFilterOptions;
import com.google.gerrit.server.permissions.PermissionBackendException;
@@ -339,6 +342,7 @@
private final Provider<CurrentUser> userProvider;
private final GroupAuditService groupAuditService;
private final Metrics metrics;
+ private final PluginSetContext<RequestListener> requestListeners;
@Inject
UploadFilter(
@@ -346,12 +350,14 @@
PermissionBackend permissionBackend,
Provider<CurrentUser> userProvider,
GroupAuditService groupAuditService,
- Metrics metrics) {
+ Metrics metrics,
+ PluginSetContext<RequestListener> requestListeners) {
this.uploadValidatorsFactory = uploadValidatorsFactory;
this.permissionBackend = permissionBackend;
this.userProvider = userProvider;
this.groupAuditService = groupAuditService;
this.metrics = metrics;
+ this.requestListeners = requestListeners;
}
@Override
@@ -369,7 +375,14 @@
HttpServletRequest httpRequest = (HttpServletRequest) request;
String sessionId = httpRequest.getSession().getId();
- try {
+ try (TraceContext traceContext = TraceContext.open()) {
+ RequestInfo requestInfo =
+ RequestInfo.builder(
+ RequestInfo.RequestType.GIT_UPLOAD, userProvider.get(), traceContext)
+ .project(state.getNameKey())
+ .build();
+ requestListeners.runEach(l -> l.onRequest(requestInfo));
+
try {
perm.check(ProjectPermission.RUN_UPLOAD_PACK);
} catch (AuthException e) {
diff --git a/java/com/google/gerrit/httpd/RequestMetrics.java b/java/com/google/gerrit/httpd/RequestMetrics.java
index 2e8e6e7..e0f9b6a 100644
--- a/java/com/google/gerrit/httpd/RequestMetrics.java
+++ b/java/com/google/gerrit/httpd/RequestMetrics.java
@@ -18,6 +18,7 @@
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.MetricMaker;
+import com.google.gerrit.server.logging.Metadata;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -29,7 +30,9 @@
@Inject
public RequestMetrics(MetricMaker metricMaker) {
Field<Integer> statusCodeField =
- Field.ofInteger("status").description("HTTP status code").build();
+ Field.ofInteger("status", Metadata.Builder::httpStatus)
+ .description("HTTP status code")
+ .build();
errors =
metricMaker.newCounter(
diff --git a/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java
index d7e9e44..4c125a7 100644
--- a/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java
+++ b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java
@@ -123,6 +123,15 @@
if (urlParameterMap.containsKey("p2")) {
data.put("polymer2", "true");
}
+ if (urlParameterMap.containsKey("ce")) {
+ data.put("polyfillCE", "true");
+ }
+ if (urlParameterMap.containsKey("sd")) {
+ data.put("polyfillSD", "true");
+ }
+ if (urlParameterMap.containsKey("sc")) {
+ data.put("polyfillSC", "true");
+ }
return data.build();
}
diff --git a/java/com/google/gerrit/httpd/raw/IndexServlet.java b/java/com/google/gerrit/httpd/raw/IndexServlet.java
index 4c9fc3b..a0b41b21 100644
--- a/java/com/google/gerrit/httpd/raw/IndexServlet.java
+++ b/java/com/google/gerrit/httpd/raw/IndexServlet.java
@@ -74,11 +74,7 @@
ImmutableMap<String, Object> templateData =
IndexHtmlUtil.templateData(
gerritApi, canonicalUrl, cdnPath, faviconPath, parameterMap, urlOrdainer);
- renderer =
- soySauce
- .renderTemplate("com.google.gerrit.httpd.raw.Index")
- .setExpectedContentKind(SanitizedContent.ContentKind.HTML)
- .setData(templateData);
+ renderer = soySauce.renderTemplate("com.google.gerrit.httpd.raw.Index").setData(templateData);
} catch (URISyntaxException | RestApiException e) {
throw new IOException(e);
}
@@ -87,7 +83,7 @@
rsp.setContentType("text/html");
rsp.setStatus(SC_OK);
try (OutputStream w = rsp.getOutputStream()) {
- w.write(renderer.render().get().getBytes(UTF_8));
+ w.write(renderer.renderHtml().get().toString().getBytes(UTF_8));
}
}
}
diff --git a/java/com/google/gerrit/httpd/restapi/RestApiMetrics.java b/java/com/google/gerrit/httpd/restapi/RestApiMetrics.java
index 1c34f1d..fc099a6 100644
--- a/java/com/google/gerrit/httpd/restapi/RestApiMetrics.java
+++ b/java/com/google/gerrit/httpd/restapi/RestApiMetrics.java
@@ -25,6 +25,7 @@
import com.google.gerrit.metrics.Histogram1;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.metrics.Timer1;
+import com.google.gerrit.server.logging.Metadata;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -42,7 +43,9 @@
@Inject
RestApiMetrics(MetricMaker metrics) {
Field<String> viewField =
- Field.ofString("view").description("view implementation class").build();
+ Field.ofString("view", Metadata.Builder::className)
+ .description("view implementation class")
+ .build();
count =
metrics.newCounter(
"http/server/rest_api/count",
@@ -54,7 +57,9 @@
"http/server/rest_api/error_count",
new Description("REST API errors by view").setRate(),
viewField,
- Field.ofInteger("error_code").description("HTTP status code").build());
+ Field.ofInteger("error_code", Metadata.Builder::httpStatus)
+ .description("HTTP status code")
+ .build());
serverLatency =
metrics.newTimer(
diff --git a/java/com/google/gerrit/httpd/restapi/RestApiServlet.java b/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
index 592330f..2128777b 100644
--- a/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
+++ b/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
@@ -102,22 +102,30 @@
import com.google.gerrit.httpd.WebSession;
import com.google.gerrit.httpd.restapi.ParameterParser.QueryParams;
import com.google.gerrit.json.OutputFormat;
+import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.OptionUtil;
+import com.google.gerrit.server.RequestInfo;
+import com.google.gerrit.server.RequestListener;
import com.google.gerrit.server.audit.ExtendedHttpAuditEvent;
import com.google.gerrit.server.cache.PerThreadCache;
+import com.google.gerrit.server.change.ChangeFinder;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.group.GroupAuditService;
import com.google.gerrit.server.logging.PerformanceLogContext;
import com.google.gerrit.server.logging.PerformanceLogger;
import com.google.gerrit.server.logging.RequestId;
import com.google.gerrit.server.logging.TraceContext;
+import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.plugincontext.PluginSetContext;
import com.google.gerrit.server.quota.QuotaException;
+import com.google.gerrit.server.restapi.change.ChangesCollection;
+import com.google.gerrit.server.restapi.project.ProjectsCollection;
import com.google.gerrit.server.update.UpdateException;
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.gerrit.util.http.CacheHeaders;
@@ -227,6 +235,7 @@
final Provider<CurrentUser> currentUser;
final DynamicItem<WebSession> webSession;
final Provider<ParameterParser> paramParser;
+ final PluginSetContext<RequestListener> requestListeners;
final PermissionBackend permissionBackend;
final GroupAuditService auditService;
final RestApiMetrics metrics;
@@ -234,27 +243,32 @@
final RestApiQuotaEnforcer quotaChecker;
final Config config;
final DynamicSet<PerformanceLogger> performanceLoggers;
+ final ChangeFinder changeFinder;
@Inject
Globals(
Provider<CurrentUser> currentUser,
DynamicItem<WebSession> webSession,
Provider<ParameterParser> paramParser,
+ PluginSetContext<RequestListener> requestListeners,
PermissionBackend permissionBackend,
GroupAuditService auditService,
RestApiMetrics metrics,
RestApiQuotaEnforcer quotaChecker,
@GerritServerConfig Config config,
- DynamicSet<PerformanceLogger> performanceLoggers) {
+ DynamicSet<PerformanceLogger> performanceLoggers,
+ ChangeFinder changeFinder) {
this.currentUser = currentUser;
this.webSession = webSession;
this.paramParser = paramParser;
+ this.requestListeners = requestListeners;
this.permissionBackend = permissionBackend;
this.auditService = auditService;
this.metrics = metrics;
this.quotaChecker = quotaChecker;
this.config = config;
this.performanceLoggers = performanceLoggers;
+ this.changeFinder = changeFinder;
allowOrigin = makeAllowOrigin(config);
}
@@ -301,6 +315,11 @@
ViewData viewData = null;
try (TraceContext traceContext = enableTracing(req, res)) {
+ List<IdString> path = splitPath(req);
+
+ RequestInfo requestInfo = createRequestInfo(traceContext, requestUri(req), path);
+ globals.requestListeners.runEach(l -> l.onRequest(requestInfo));
+
try (PerThreadCache ignored = PerThreadCache.create()) {
// It's important that the PerformanceLogContext is closed before the response is sent to
// the client. Only this way it is ensured that the invocation of the PerformanceLogger
@@ -329,7 +348,6 @@
}
checkUserSession(req);
- List<IdString> path = splitPath(req);
RestCollection<RestResource, RestResource> rc = members.get();
globals
.permissionBackend
@@ -627,9 +645,7 @@
Throwable t = e.getCause();
if (t instanceof LockFailureException) {
logger.atSevere().withCause(t).log("Error in %s %s", req.getMethod(), uriForLogging(req));
- responseBytes =
- replyError(
- req, res, status = SC_SERVICE_UNAVAILABLE, messageOr(t, "Lock failure"), e);
+ responseBytes = replyError(req, res, status = SC_SERVICE_UNAVAILABLE, "Lock failure", e);
} else {
status = SC_INTERNAL_SERVER_ERROR;
responseBytes = handleException(e, req, res);
@@ -1408,6 +1424,29 @@
return traceContext;
}
+ private RequestInfo createRequestInfo(
+ TraceContext traceContext, String requestUri, List<IdString> path) {
+ RequestInfo.Builder requestInfo =
+ RequestInfo.builder(RequestInfo.RequestType.REST, globals.currentUser.get(), traceContext)
+ .requestUri(requestUri);
+
+ if (path.size() < 1) {
+ return requestInfo.build();
+ }
+
+ RestCollection<?, ?> rootCollection = members.get();
+ String resourceId = path.get(0).get();
+ if (rootCollection instanceof ProjectsCollection) {
+ requestInfo.project(Project.nameKey(resourceId));
+ } else if (rootCollection instanceof ChangesCollection) {
+ ChangeNotes changeNotes = globals.changeFinder.findOne(resourceId);
+ if (changeNotes != null) {
+ requestInfo.project(changeNotes.getProjectName());
+ }
+ }
+ return requestInfo.build();
+ }
+
private boolean isDelete(HttpServletRequest req) {
return "DELETE".equals(req.getMethod());
}
@@ -1492,7 +1531,7 @@
configureCaching(req, res, null, null, c);
checkArgument(statusCode >= 400, "non-error status: %s", statusCode);
res.setStatus(statusCode);
- logger.atFinest().log("REST call failed: %d", statusCode);
+ logger.atFinest().withCause(err).log("REST call failed: %d", statusCode);
return replyText(req, res, true, msg);
}
diff --git a/java/com/google/gerrit/index/query/QueryProcessor.java b/java/com/google/gerrit/index/query/QueryProcessor.java
index 346a306..61d609b 100644
--- a/java/com/google/gerrit/index/query/QueryProcessor.java
+++ b/java/com/google/gerrit/index/query/QueryProcessor.java
@@ -38,6 +38,7 @@
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.metrics.Timer1;
import com.google.gerrit.server.logging.CallerFinder;
+import com.google.gerrit.server.logging.Metadata;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -66,7 +67,9 @@
new Description("Successful query latency, accumulated over the life of the process")
.setCumulative()
.setUnit(Description.Units.MILLISECONDS),
- Field.ofString("index").description("index name").build());
+ Field.ofString("index", Metadata.Builder::indexName)
+ .description("index name")
+ .build());
}
}
diff --git a/java/com/google/gerrit/metrics/Field.java b/java/com/google/gerrit/metrics/Field.java
index ad8eae9..bdae854 100644
--- a/java/com/google/gerrit/metrics/Field.java
+++ b/java/com/google/gerrit/metrics/Field.java
@@ -17,7 +17,9 @@
import static com.google.common.base.Preconditions.checkArgument;
import com.google.auto.value.AutoValue;
+import com.google.gerrit.server.logging.Metadata;
import java.util.Optional;
+import java.util.function.BiConsumer;
import java.util.function.Function;
/**
@@ -27,17 +29,23 @@
*/
@AutoValue
public abstract class Field<T> {
+ public static <T> BiConsumer<Metadata.Builder, T> ignoreMetadata() {
+ return (metadataBuilder, fieldValue) -> {};
+ }
+
/**
* Break down metrics by boolean true/false.
*
* @param name field name
* @return builder for the boolean field
*/
- public static Field.Builder<Boolean> ofBoolean(String name) {
+ public static Field.Builder<Boolean> ofBoolean(
+ String name, BiConsumer<Metadata.Builder, Boolean> metadataMapper) {
return new AutoValue_Field.Builder<Boolean>()
.valueType(Boolean.class)
.formatter(Object::toString)
- .name(name);
+ .name(name)
+ .metadataMapper(metadataMapper);
}
/**
@@ -47,8 +55,15 @@
* @param name field name
* @return builder for the enum field
*/
- public static <E extends Enum<E>> Field.Builder<E> ofEnum(Class<E> enumType, String name) {
- return new AutoValue_Field.Builder<E>().valueType(enumType).formatter(Enum::name).name(name);
+ public static <E extends Enum<E>> Field.Builder<E> ofEnum(
+ Class<E> enumType, String name, BiConsumer<Metadata.Builder, String> metadataMapper) {
+ return new AutoValue_Field.Builder<E>()
+ .valueType(enumType)
+ .formatter(Enum::name)
+ .name(name)
+ .metadataMapper(
+ (metadataBuilder, fieldValue) ->
+ metadataMapper.accept(metadataBuilder, fieldValue.name()));
}
/**
@@ -60,11 +75,13 @@
* @param name field name
* @return builder for the integer field
*/
- public static Field.Builder<Integer> ofInteger(String name) {
+ public static Field.Builder<Integer> ofInteger(
+ String name, BiConsumer<Metadata.Builder, Integer> metadataMapper) {
return new AutoValue_Field.Builder<Integer>()
.valueType(Integer.class)
.formatter(Object::toString)
- .name(name);
+ .name(name)
+ .metadataMapper(metadataMapper);
}
/**
@@ -76,11 +93,13 @@
* @param name field name
* @return builder for the string field
*/
- public static Field.Builder<String> ofString(String name) {
+ public static Field.Builder<String> ofString(
+ String name, BiConsumer<Metadata.Builder, String> metadataMapper) {
return new AutoValue_Field.Builder<String>()
.valueType(String.class)
.formatter(s -> s)
- .name(name);
+ .name(name)
+ .metadataMapper(metadataMapper);
}
/** @return name of this field within the metric. */
@@ -89,6 +108,9 @@
/** @return type of value used within the field. */
public abstract Class<T> valueType();
+ /** @return mapper that maps a field value to a field in the {@link Metadata} class. */
+ public abstract BiConsumer<Metadata.Builder, T> metadataMapper();
+
/** @return description text for the field explaining its range of values. */
public abstract Optional<String> description();
@@ -103,6 +125,8 @@
abstract Builder<T> formatter(Function<T, String> formatter);
+ abstract Builder<T> metadataMapper(BiConsumer<Metadata.Builder, T> metadataMapper);
+
public abstract Builder<T> description(String description);
abstract Field<T> autoBuild();
diff --git a/java/com/google/gerrit/metrics/Timer1.java b/java/com/google/gerrit/metrics/Timer1.java
index c420e9a..a8fb1a2 100644
--- a/java/com/google/gerrit/metrics/Timer1.java
+++ b/java/com/google/gerrit/metrics/Timer1.java
@@ -19,6 +19,7 @@
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.extensions.registration.RegistrationHandle;
import com.google.gerrit.server.logging.LoggingContext;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.PerformanceLogRecord;
import java.util.concurrent.TimeUnit;
@@ -80,9 +81,12 @@
public final void record(F1 fieldValue, long value, TimeUnit unit) {
long durationMs = unit.toMillis(value);
+ Metadata.Builder metadataBuilder = Metadata.builder();
+ field.metadataMapper().accept(metadataBuilder, fieldValue);
+ Metadata metadata = metadataBuilder.build();
+
LoggingContext.getInstance()
- .addPerformanceLogRecord(
- () -> PerformanceLogRecord.create(name, durationMs, field.name(), fieldValue));
+ .addPerformanceLogRecord(() -> PerformanceLogRecord.create(name, durationMs, metadata));
logger.atFinest().log("%s (%s = %s) took %dms", name, field.name(), fieldValue, durationMs);
doRecord(fieldValue, value, unit);
diff --git a/java/com/google/gerrit/metrics/Timer2.java b/java/com/google/gerrit/metrics/Timer2.java
index fef2d9a..8a4a793 100644
--- a/java/com/google/gerrit/metrics/Timer2.java
+++ b/java/com/google/gerrit/metrics/Timer2.java
@@ -19,6 +19,7 @@
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.extensions.registration.RegistrationHandle;
import com.google.gerrit.server.logging.LoggingContext;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.PerformanceLogRecord;
import java.util.concurrent.TimeUnit;
@@ -87,11 +88,13 @@
public final void record(F1 fieldValue1, F2 fieldValue2, long value, TimeUnit unit) {
long durationMs = unit.toMillis(value);
+ Metadata.Builder metadataBuilder = Metadata.builder();
+ field1.metadataMapper().accept(metadataBuilder, fieldValue1);
+ field2.metadataMapper().accept(metadataBuilder, fieldValue2);
+ Metadata metadata = metadataBuilder.build();
+
LoggingContext.getInstance()
- .addPerformanceLogRecord(
- () ->
- PerformanceLogRecord.create(
- name, durationMs, field1.name(), fieldValue1, field2.name(), fieldValue2));
+ .addPerformanceLogRecord(() -> PerformanceLogRecord.create(name, durationMs, metadata));
logger.atFinest().log(
"%s (%s = %s, %s = %s) took %dms",
diff --git a/java/com/google/gerrit/metrics/Timer3.java b/java/com/google/gerrit/metrics/Timer3.java
index 40c4882..2044da6 100644
--- a/java/com/google/gerrit/metrics/Timer3.java
+++ b/java/com/google/gerrit/metrics/Timer3.java
@@ -19,6 +19,7 @@
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.extensions.registration.RegistrationHandle;
import com.google.gerrit.server.logging.LoggingContext;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.PerformanceLogRecord;
import java.util.concurrent.TimeUnit;
@@ -95,18 +96,14 @@
F1 fieldValue1, F2 fieldValue2, F3 fieldValue3, long value, TimeUnit unit) {
long durationMs = unit.toMillis(value);
+ Metadata.Builder metadataBuilder = Metadata.builder();
+ field1.metadataMapper().accept(metadataBuilder, fieldValue1);
+ field2.metadataMapper().accept(metadataBuilder, fieldValue2);
+ field3.metadataMapper().accept(metadataBuilder, fieldValue3);
+ Metadata metadata = metadataBuilder.build();
+
LoggingContext.getInstance()
- .addPerformanceLogRecord(
- () ->
- PerformanceLogRecord.create(
- name,
- durationMs,
- field1.name(),
- fieldValue1,
- field2.name(),
- fieldValue2,
- field3.name(),
- fieldValue3));
+ .addPerformanceLogRecord(() -> PerformanceLogRecord.create(name, durationMs, metadata));
logger.atFinest().log(
"%s (%s = %s, %s = %s, %s = %s) took %dms",
diff --git a/java/com/google/gerrit/metrics/proc/ProcMetricModule.java b/java/com/google/gerrit/metrics/proc/ProcMetricModule.java
index 55a9ec3..d9781b5 100644
--- a/java/com/google/gerrit/metrics/proc/ProcMetricModule.java
+++ b/java/com/google/gerrit/metrics/proc/ProcMetricModule.java
@@ -23,6 +23,7 @@
import com.google.gerrit.metrics.Description.Units;
import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.MetricMaker;
+import com.google.gerrit.server.logging.Metadata;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
@@ -149,7 +150,9 @@
private void procJvmGc(MetricMaker metrics) {
Field<String> gcNameField =
- Field.ofString("gc_name").description("The name of the garbage collector").build();
+ Field.ofString("gc_name", Metadata.Builder::garbageCollectorName)
+ .description("The name of the garbage collector")
+ .build();
CallbackMetric1<String, Long> gcCount =
metrics.newCallbackMetric(
diff --git a/java/com/google/gerrit/pgm/init/BaseInit.java b/java/com/google/gerrit/pgm/init/BaseInit.java
index 7575fdb..a7a8c58 100644
--- a/java/com/google/gerrit/pgm/init/BaseInit.java
+++ b/java/com/google/gerrit/pgm/init/BaseInit.java
@@ -34,7 +34,6 @@
import com.google.gerrit.pgm.init.index.elasticsearch.ElasticIndexModuleOnInit;
import com.google.gerrit.pgm.init.index.lucene.LuceneIndexModuleOnInit;
import com.google.gerrit.pgm.util.SiteProgram;
-import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.GerritServerConfigModule;
import com.google.gerrit.server.config.SitePath;
import com.google.gerrit.server.config.SitePaths;
@@ -52,7 +51,6 @@
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
-import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
import com.google.inject.spi.Message;
@@ -69,7 +67,6 @@
import java.util.Collections;
import java.util.List;
import java.util.Set;
-import org.eclipse.jgit.lib.Config;
/** Initialize a new Gerrit installation. */
public class BaseInit extends SiteProgram {
@@ -80,7 +77,6 @@
private final List<String> pluginsToInstall;
private Injector sysInjector;
- private Config config;
protected BaseInit(PluginsDistribution pluginsDistribution, List<String> pluginsToInstall) {
this.standalone = true;
@@ -125,9 +121,6 @@
try {
run.upgradeSchema();
} catch (StorageException e) {
- if (config.getBoolean("container", "slave", false)) {
- throw e;
- }
String msg = "Couldn't upgrade schema. Expected if slave and read-only database";
System.err.println(msg);
logger.atWarning().withCause(e).log(msg);
@@ -419,7 +412,6 @@
}
});
Injector dbInjector = createDbInjector();
- config = dbInjector.getInstance(Key.get(Config.class, GerritServerConfig.class));
IndexType indexType = IndexModule.getIndexType(dbInjector);
if (indexType.isLucene()) {
diff --git a/java/com/google/gerrit/pgm/init/InitAdminUser.java b/java/com/google/gerrit/pgm/init/InitAdminUser.java
index 674f9c1..45c5ea6 100644
--- a/java/com/google/gerrit/pgm/init/InitAdminUser.java
+++ b/java/com/google/gerrit/pgm/init/InitAdminUser.java
@@ -20,7 +20,6 @@
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.exceptions.NoSuchGroupException;
import com.google.gerrit.extensions.client.AuthType;
-import com.google.gerrit.pgm.init.api.AllUsersNameOnInitProvider;
import com.google.gerrit.pgm.init.api.ConsoleUI;
import com.google.gerrit.pgm.init.api.InitFlags;
import com.google.gerrit.pgm.init.api.InitStep;
@@ -29,7 +28,6 @@
import com.google.gerrit.server.account.AccountSshKey;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.account.externalids.ExternalId;
-import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.index.account.AccountIndex;
import com.google.gerrit.server.index.account.AccountIndexCollection;
@@ -49,7 +47,6 @@
public class InitAdminUser implements InitStep {
private final InitFlags flags;
private final ConsoleUI ui;
- private final AllUsersNameOnInitProvider allUsers;
private final AccountsOnInit accounts;
private final VersionedAuthorizedKeysOnInit.Factory authorizedKeysFactory;
private final ExternalIdsOnInit externalIds;
@@ -62,7 +59,6 @@
InitAdminUser(
InitFlags flags,
ConsoleUI ui,
- AllUsersNameOnInitProvider allUsers,
AccountsOnInit accounts,
VersionedAuthorizedKeysOnInit.Factory authorizedKeysFactory,
ExternalIdsOnInit externalIds,
@@ -70,7 +66,6 @@
GroupsOnInit groupsOnInit) {
this.flags = flags;
this.ui = ui;
- this.allUsers = allUsers;
this.accounts = accounts;
this.authorizedKeysFactory = authorizedKeysFactory;
this.externalIds = externalIds;
@@ -140,7 +135,7 @@
authorizedKeys.save("Add SSH key for initial admin user\n");
}
- AccountState as = AccountState.forAccount(new AllUsersName(allUsers.get()), a, extIds);
+ AccountState as = AccountState.forAccount(a, extIds);
for (AccountIndex accountIndex : accountIndexCollection.getWriteIndexes()) {
accountIndex.replace(as);
}
diff --git a/java/com/google/gerrit/reviewdb/client/BooleanProjectConfig.java b/java/com/google/gerrit/reviewdb/client/BooleanProjectConfig.java
index a70d254..bea5abe 100644
--- a/java/com/google/gerrit/reviewdb/client/BooleanProjectConfig.java
+++ b/java/com/google/gerrit/reviewdb/client/BooleanProjectConfig.java
@@ -32,7 +32,6 @@
USE_CONTRIBUTOR_AGREEMENTS("receive", "requireContributorAgreement"),
USE_SIGNED_OFF_BY("receive", "requireSignedOffBy"),
USE_CONTENT_MERGE("submit", "mergeContent"),
- REQUIRE_CHANGE_ID("receive", "requireChangeId"),
CREATE_NEW_CHANGE_FOR_ALL_NOT_IN_TARGET("receive", "createNewChangeForAllNotInTarget"),
ENABLE_SIGNED_PUSH("receive", "enableSignedPush"),
REQUIRE_SIGNED_PUSH("receive", "requireSignedPush"),
diff --git a/java/com/google/gerrit/reviewdb/client/Comment.java b/java/com/google/gerrit/reviewdb/client/Comment.java
index d1f97fb..94e7583 100644
--- a/java/com/google/gerrit/reviewdb/client/Comment.java
+++ b/java/com/google/gerrit/reviewdb/client/Comment.java
@@ -185,7 +185,9 @@
}
public Key key;
+ /** The line number (1-based) to which the comment refers, or 0 for a file comment. */
public int lineNbr;
+
public Identity author;
protected Identity realAuthor;
public Timestamp writtenOn;
diff --git a/java/com/google/gerrit/server/ApprovalCopier.java b/java/com/google/gerrit/server/ApprovalCopier.java
index 979cc11..85a6079 100644
--- a/java/com/google/gerrit/server/ApprovalCopier.java
+++ b/java/com/google/gerrit/server/ApprovalCopier.java
@@ -73,49 +73,27 @@
Iterable<PatchSetApproval> getForPatchSet(
ChangeNotes notes, PatchSet.Id psId, @Nullable RevWalk rw, @Nullable Config repoConfig) {
- return getForPatchSet(notes, psId, rw, repoConfig, Collections.emptyList());
- }
- Iterable<PatchSetApproval> getForPatchSet(
- ChangeNotes notes,
- PatchSet.Id psId,
- @Nullable RevWalk rw,
- @Nullable Config repoConfig,
- Iterable<PatchSetApproval> dontCopy) {
PatchSet ps = psUtil.get(notes, psId);
if (ps == null) {
return Collections.emptyList();
}
- return getForPatchSet(notes, ps, rw, repoConfig, dontCopy);
- }
- private Iterable<PatchSetApproval> getForPatchSet(
- ChangeNotes notes,
- PatchSet ps,
- @Nullable RevWalk rw,
- @Nullable Config repoConfig,
- Iterable<PatchSetApproval> dontCopy) {
- requireNonNull(ps, "ps should not be null");
ChangeData cd = changeDataFactory.create(notes);
try {
ProjectState project = projectCache.checkedGet(cd.change().getDest().project());
ListMultimap<PatchSet.Id, PatchSetApproval> all = cd.approvals();
requireNonNull(all, "all should not be null");
- Table<String, Account.Id, PatchSetApproval> wontCopy = HashBasedTable.create();
- for (PatchSetApproval psa : dontCopy) {
- wontCopy.put(psa.label(), psa.accountId(), psa);
- }
-
Table<String, Account.Id, PatchSetApproval> byUser = HashBasedTable.create();
for (PatchSetApproval psa : all.get(ps.id())) {
- if (!wontCopy.contains(psa.label(), psa.accountId())) {
- byUser.put(psa.label(), psa.accountId(), psa);
- }
+ byUser.put(psa.label(), psa.accountId(), psa);
}
TreeMap<Integer, PatchSet> patchSets = getPatchSets(cd);
+ Table<String, Account.Id, PatchSetApproval> wontCopy = HashBasedTable.create();
+
// Walk patch sets strictly less than current in descending order.
Collection<PatchSet> allPrior =
patchSets.descendingMap().tailMap(ps.id().get(), false).values();
diff --git a/java/com/google/gerrit/server/RequestInfo.java b/java/com/google/gerrit/server/RequestInfo.java
new file mode 100644
index 0000000..f5749fc
--- /dev/null
+++ b/java/com/google/gerrit/server/RequestInfo.java
@@ -0,0 +1,96 @@
+// Copyright (C) 2019 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;
+
+import com.google.auto.value.AutoValue;
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.logging.TraceContext;
+import java.util.Optional;
+
+/** Information about a request that was received from a user. */
+@AutoValue
+public abstract class RequestInfo {
+ /** Channel through which a user request was received. */
+ public enum RequestType {
+ /** request type for git push */
+ GIT_RECEIVE,
+
+ /** request type for git fetch */
+ GIT_UPLOAD,
+
+ /** request type for call to REST API */
+ REST,
+
+ /** request type for call to SSH API */
+ SSH
+ }
+
+ /**
+ * Type of the request, telling through which channel the request was coming in.
+ *
+ * <p>See {@link RequestType} for the types that are used by Gerrit core. Other request types are
+ * possible, e.g. if a plugin supports receiving requests through another channel.
+ */
+ public abstract String requestType();
+
+ /**
+ * Request URI.
+ *
+ * <p>Only set if request type is {@link RequestType#REST}.
+ *
+ * <p>Never includes the "/a" prefix.
+ */
+ public abstract Optional<String> requestUri();
+
+ /** The user that has sent the request. */
+ public abstract CurrentUser callingUser();
+
+ /** The trace context of the request. */
+ public abstract TraceContext traceContext();
+
+ /**
+ * The name of the project for which the request is being done. Only available if the request is
+ * tied to a project or change. If a project is available it's not guaranteed that it actually
+ * exists (e.g. if a user made a request for a project that doesn't exist).
+ */
+ public abstract Optional<Project.NameKey> project();
+
+ public static RequestInfo.Builder builder(
+ RequestType requestType, CurrentUser callingUser, TraceContext traceContext) {
+ return new AutoValue_RequestInfo.Builder()
+ .requestType(requestType)
+ .callingUser(callingUser)
+ .traceContext(traceContext);
+ }
+
+ @AutoValue.Builder
+ public abstract static class Builder {
+ public abstract Builder requestType(String requestType);
+
+ public Builder requestType(RequestType requestType) {
+ return requestType(requestType.name());
+ }
+
+ public abstract Builder requestUri(String requestUri);
+
+ public abstract Builder callingUser(CurrentUser callingUser);
+
+ public abstract Builder traceContext(TraceContext traceContext);
+
+ public abstract Builder project(Project.NameKey projectName);
+
+ public abstract RequestInfo build();
+ }
+}
diff --git a/java/com/google/gerrit/server/RequestListener.java b/java/com/google/gerrit/server/RequestListener.java
new file mode 100644
index 0000000..461b91a
--- /dev/null
+++ b/java/com/google/gerrit/server/RequestListener.java
@@ -0,0 +1,22 @@
+// Copyright (C) 2019 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;
+
+import com.google.gerrit.extensions.annotations.ExtensionPoint;
+
+@ExtensionPoint
+public interface RequestListener {
+ void onRequest(RequestInfo requestInfo);
+}
diff --git a/java/com/google/gerrit/server/StarredChangesUtil.java b/java/com/google/gerrit/server/StarredChangesUtil.java
index b81e0bd..2cb670e 100644
--- a/java/com/google/gerrit/server/StarredChangesUtil.java
+++ b/java/com/google/gerrit/server/StarredChangesUtil.java
@@ -42,6 +42,7 @@
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.index.change.ChangeField;
import com.google.gerrit.server.index.change.ChangeIndexer;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.gerrit.server.project.NoSuchChangeException;
@@ -376,7 +377,9 @@
}
public static StarRef readLabels(Repository repo, String refName) throws IOException {
- try (TraceTimer traceTimer = TraceContext.newTimer("Read star labels", "ref", refName)) {
+ try (TraceTimer traceTimer =
+ TraceContext.newTimer(
+ "Read star labels", Metadata.builder().noteDbRefName(refName).build())) {
Ref ref = repo.exactRef(refName);
if (ref == null) {
return StarRef.MISSING;
@@ -451,7 +454,8 @@
throws IOException, InvalidLabelsException {
try (TraceTimer traceTimer =
TraceContext.newTimer(
- "Update star labels", "ref", refName, "labelCount", labels.size());
+ "Update star labels",
+ Metadata.builder().noteDbRefName(refName).resourceCount(labels.size()).build());
RevWalk rw = new RevWalk(repo)) {
RefUpdate u = repo.updateRef(refName);
u.setExpectedOldObjectId(oldObjectId);
@@ -488,7 +492,9 @@
return;
}
- try (TraceTimer traceTimer = TraceContext.newTimer("Delete star labels", "ref", refName)) {
+ try (TraceTimer traceTimer =
+ TraceContext.newTimer(
+ "Delete star labels", Metadata.builder().noteDbRefName(refName).build())) {
RefUpdate u = repo.updateRef(refName);
u.setForceUpdate(true);
u.setExpectedOldObjectId(oldObjectId);
diff --git a/java/com/google/gerrit/server/TraceRequestListener.java b/java/com/google/gerrit/server/TraceRequestListener.java
new file mode 100644
index 0000000..773f712
--- /dev/null
+++ b/java/com/google/gerrit/server/TraceRequestListener.java
@@ -0,0 +1,228 @@
+// Copyright (C) 2019 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;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.flogger.FluentLogger;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.gerrit.server.logging.RequestId;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import java.util.Optional;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.lib.Config;
+
+/**
+ * Request listener that sets additional logging tags and enables tracing automatically if the
+ * request matches any tracing configuration in gerrit.config (see description of
+ * 'tracing.<trace-id>' subsection in config-gerrit.txt).
+ */
+@Singleton
+public class TraceRequestListener implements RequestListener {
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+
+ private final Config cfg;
+ private final ImmutableList<TraceConfig> traceConfigs;
+
+ @Inject
+ TraceRequestListener(@GerritServerConfig Config cfg) {
+ this.cfg = cfg;
+ this.traceConfigs = parseTraceConfigs();
+ }
+
+ @Override
+ public void onRequest(RequestInfo requestInfo) {
+ requestInfo.project().ifPresent(p -> requestInfo.traceContext().addTag("project", p));
+ traceConfigs.stream()
+ .filter(traceConfig -> traceConfig.matches(requestInfo))
+ .forEach(
+ traceConfig ->
+ requestInfo
+ .traceContext()
+ .forceLogging()
+ .addTag(RequestId.Type.TRACE_ID, traceConfig.traceId()));
+ }
+
+ private ImmutableList<TraceConfig> parseTraceConfigs() {
+ ImmutableList.Builder<TraceConfig> traceConfigs = ImmutableList.builder();
+
+ for (String traceId : cfg.getSubsections("tracing")) {
+ try {
+ TraceConfig.Builder traceConfig = TraceConfig.builder();
+ traceConfig.traceId(traceId);
+ traceConfig.requestTypes(parseRequestTypes(traceId));
+ traceConfig.requestUriPatterns(parseRequestUriPatterns(traceId));
+ traceConfig.accountIds(parseAccounts(traceId));
+ traceConfig.projectPatterns(parseProjectPatterns(traceId));
+ traceConfigs.add(traceConfig.build());
+ } catch (ConfigInvalidException e) {
+ logger.atWarning().log("Ignoring invalid tracing configuration:\n %s", e.getMessage());
+ }
+ }
+
+ return traceConfigs.build();
+ }
+
+ private ImmutableSet<String> parseRequestTypes(String traceId) {
+ return ImmutableSet.copyOf(cfg.getStringList("tracing", traceId, "requestType"));
+ }
+
+ private ImmutableSet<Pattern> parseRequestUriPatterns(String traceId)
+ throws ConfigInvalidException {
+ return parsePatterns(traceId, "requestUriPattern");
+ }
+
+ private ImmutableSet<Account.Id> parseAccounts(String traceId) throws ConfigInvalidException {
+ ImmutableSet.Builder<Account.Id> accountIds = ImmutableSet.builder();
+ String[] accounts = cfg.getStringList("tracing", traceId, "account");
+ for (String account : accounts) {
+ Optional<Account.Id> accountId = Account.Id.tryParse(account);
+ if (!accountId.isPresent()) {
+ throw new ConfigInvalidException(
+ String.format(
+ "Invalid tracing config ('tracing.%s.account = %s'): invalid account ID",
+ traceId, account));
+ }
+ accountIds.add(accountId.get());
+ }
+ return accountIds.build();
+ }
+
+ private ImmutableSet<Pattern> parseProjectPatterns(String traceId) throws ConfigInvalidException {
+ return parsePatterns(traceId, "projectPattern");
+ }
+
+ private ImmutableSet<Pattern> parsePatterns(String traceId, String name)
+ throws ConfigInvalidException {
+ ImmutableSet.Builder<Pattern> patterns = ImmutableSet.builder();
+ String[] patternRegExs = cfg.getStringList("tracing", traceId, name);
+ for (String patternRegEx : patternRegExs) {
+ try {
+ patterns.add(Pattern.compile(patternRegEx));
+ } catch (PatternSyntaxException e) {
+ throw new ConfigInvalidException(
+ String.format(
+ "Invalid tracing config ('tracing.%s.%s = %s'): %s",
+ traceId, name, patternRegEx, e.getMessage()));
+ }
+ }
+ return patterns.build();
+ }
+
+ @AutoValue
+ abstract static class TraceConfig {
+ /** ID for the trace */
+ abstract String traceId();
+
+ /** request types that should be traced */
+ abstract ImmutableSet<String> requestTypes();
+
+ /** pattern matching request URIs */
+ abstract ImmutableSet<Pattern> requestUriPatterns();
+
+ /** accounts IDs matching calling user */
+ abstract ImmutableSet<Account.Id> accountIds();
+
+ /** pattern matching projects names */
+ abstract ImmutableSet<Pattern> projectPatterns();
+
+ static Builder builder() {
+ return new AutoValue_TraceRequestListener_TraceConfig.Builder();
+ }
+
+ /**
+ * Whether this trace config matches a given request.
+ *
+ * @param requestInfo request info
+ * @return whether this trace config matches
+ */
+ boolean matches(RequestInfo requestInfo) {
+ // If in the trace config request types are set and none of them matches, then the request is
+ // not matched.
+ if (!requestTypes().isEmpty()
+ && requestTypes().stream()
+ .noneMatch(type -> type.equalsIgnoreCase(requestInfo.requestType()))) {
+ return false;
+ }
+
+ // If in the trace config request URI patterns are set and none of them matches, then the
+ // request is not matched.
+ if (!requestUriPatterns().isEmpty()) {
+ if (!requestInfo.requestUri().isPresent()) {
+ // The request has no request URI, hence it cannot match a request URI pattern.
+ return false;
+ }
+
+ if (requestUriPatterns().stream()
+ .noneMatch(p -> p.matcher(requestInfo.requestUri().get()).matches())) {
+ return false;
+ }
+ }
+
+ // If in the trace config accounts are set and none of them matches, then the request is not
+ // matched.
+ if (!accountIds().isEmpty()) {
+ try {
+ if (accountIds().stream()
+ .noneMatch(id -> id.equals(requestInfo.callingUser().getAccountId()))) {
+ return false;
+ }
+ } catch (UnsupportedOperationException e) {
+ // The calling user is not logged in, hence it cannot match an account.
+ return false;
+ }
+ }
+
+ // If in the trace config project patterns are set and none of them matches, then the request
+ // is not matched.
+ if (!projectPatterns().isEmpty()) {
+ if (!requestInfo.project().isPresent()) {
+ // The request is not for a project, hence it cannot match a project pattern.
+ return false;
+ }
+
+ if (projectPatterns().stream()
+ .noneMatch(p -> p.matcher(requestInfo.project().get().get()).matches())) {
+ return false;
+ }
+ }
+
+ // For any match criteria (request type, request URI pattern, account, project pattern) that
+ // was specified in the trace config, at least one of the configured value matched the
+ // request.
+ return true;
+ }
+
+ @AutoValue.Builder
+ abstract static class Builder {
+ abstract Builder traceId(String traceId);
+
+ abstract Builder requestTypes(ImmutableSet<String> requestTypes);
+
+ abstract Builder requestUriPatterns(ImmutableSet<Pattern> requestUriPatterns);
+
+ abstract Builder accountIds(ImmutableSet<Account.Id> accountIds);
+
+ abstract Builder projectPatterns(ImmutableSet<Pattern> projectPatterns);
+
+ abstract TraceConfig build();
+ }
+ }
+}
diff --git a/java/com/google/gerrit/server/account/AccountCacheImpl.java b/java/com/google/gerrit/server/account/AccountCacheImpl.java
index 3f3f27d..3d81052 100644
--- a/java/com/google/gerrit/server/account/AccountCacheImpl.java
+++ b/java/com/google/gerrit/server/account/AccountCacheImpl.java
@@ -26,7 +26,7 @@
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIds;
import com.google.gerrit.server.cache.CacheModule;
-import com.google.gerrit.server.config.AllUsersName;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.gerrit.server.util.time.TimeUtil;
@@ -68,18 +68,15 @@
};
}
- private final AllUsersName allUsersName;
private final ExternalIds externalIds;
private final LoadingCache<Account.Id, Optional<AccountState>> byId;
private final ExecutorService executor;
@Inject
AccountCacheImpl(
- AllUsersName allUsersName,
ExternalIds externalIds,
@Named(BYID_NAME) LoadingCache<Account.Id, Optional<AccountState>> byId,
@FanOutExecutor ExecutorService executor) {
- this.allUsersName = allUsersName;
this.externalIds = externalIds;
this.byId = byId;
this.executor = executor;
@@ -170,7 +167,7 @@
private AccountState missing(Account.Id accountId) {
Account account = new Account(accountId, TimeUtil.nowTs());
account.setActive(false);
- return AccountState.forAccount(allUsersName, account);
+ return AccountState.forAccount(account);
}
static class ByIdLoader extends CacheLoader<Account.Id, Optional<AccountState>> {
@@ -183,7 +180,9 @@
@Override
public Optional<AccountState> load(Account.Id who) throws Exception {
- try (TraceTimer timer = TraceContext.newTimer("Loading account", "accountId", who)) {
+ try (TraceTimer timer =
+ TraceContext.newTimer(
+ "Loading account", Metadata.builder().accountId(who.get()).build())) {
return accounts.get(who);
}
}
diff --git a/java/com/google/gerrit/server/account/AccountState.java b/java/com/google/gerrit/server/account/AccountState.java
index 46fde8c..556185e 100644
--- a/java/com/google/gerrit/server/account/AccountState.java
+++ b/java/com/google/gerrit/server/account/AccountState.java
@@ -36,7 +36,6 @@
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIdNotes;
import com.google.gerrit.server.account.externalids.ExternalIds;
-import com.google.gerrit.server.config.AllUsersName;
import java.io.IOException;
import java.util.Collection;
import java.util.Optional;
@@ -56,16 +55,14 @@
/**
* Creates an AccountState from the given account config.
*
- * @param allUsersName the name of the All-Users repository
* @param externalIds class to access external IDs
* @param accountConfig the account config, must already be loaded
* @return the account state, {@link Optional#empty()} if the account doesn't exist
* @throws IOException if accessing the external IDs fails
*/
public static Optional<AccountState> fromAccountConfig(
- AllUsersName allUsersName, ExternalIds externalIds, AccountConfig accountConfig)
- throws IOException {
- return fromAccountConfig(allUsersName, externalIds, accountConfig, null);
+ ExternalIds externalIds, AccountConfig accountConfig) throws IOException {
+ return fromAccountConfig(externalIds, accountConfig, null);
}
/**
@@ -78,7 +75,6 @@
* updated the revision of the external IDs branch in account config is outdated. Hence after
* updating external IDs the external ID notes must be provided.
*
- * @param allUsersName the name of the All-Users repository
* @param externalIds class to access external IDs
* @param accountConfig the account config, must already be loaded
* @param extIdNotes external ID notes, must already be loaded, may be {@code null}
@@ -86,10 +82,7 @@
* @throws IOException if accessing the external IDs fails
*/
public static Optional<AccountState> fromAccountConfig(
- AllUsersName allUsersName,
- ExternalIds externalIds,
- AccountConfig accountConfig,
- @Nullable ExternalIdNotes extIdNotes)
+ ExternalIds externalIds, AccountConfig accountConfig, @Nullable ExternalIdNotes extIdNotes)
throws IOException {
if (!accountConfig.getLoadedAccount().isPresent()) {
return Optional.empty();
@@ -115,39 +108,29 @@
return Optional.of(
new AccountState(
- allUsersName,
- account,
- extIds,
- projectWatches,
- generalPreferences,
- diffPreferences,
- editPreferences));
+ account, extIds, projectWatches, generalPreferences, diffPreferences, editPreferences));
}
/**
* Creates an AccountState for a given account with no external IDs, no project watches and
* default preferences.
*
- * @param allUsersName the name of the All-Users repository
* @param account the account
* @return the account state
*/
- public static AccountState forAccount(AllUsersName allUsersName, Account account) {
- return forAccount(allUsersName, account, ImmutableSet.of());
+ public static AccountState forAccount(Account account) {
+ return forAccount(account, ImmutableSet.of());
}
/**
* Creates an AccountState for a given account with no project watches and default preferences.
*
- * @param allUsersName the name of the All-Users repository
* @param account the account
* @param extIds the external IDs
* @return the account state
*/
- public static AccountState forAccount(
- AllUsersName allUsersName, Account account, Collection<ExternalId> extIds) {
+ public static AccountState forAccount(Account account, Collection<ExternalId> extIds) {
return new AccountState(
- allUsersName,
account,
ImmutableSet.copyOf(extIds),
ImmutableMap.of(),
@@ -156,7 +139,6 @@
EditPreferencesInfo.defaults());
}
- private final AllUsersName allUsersName;
private final Account account;
private final ImmutableSet<ExternalId> externalIds;
private final Optional<String> userName;
@@ -167,14 +149,12 @@
private Cache<IdentifiedUser.PropertyKey<Object>, Object> properties;
private AccountState(
- AllUsersName allUsersName,
Account account,
ImmutableSet<ExternalId> externalIds,
ImmutableMap<ProjectWatchKey, ImmutableSet<NotifyType>> projectWatches,
GeneralPreferencesInfo generalPreferences,
DiffPreferencesInfo diffPreferences,
EditPreferencesInfo editPreferences) {
- this.allUsersName = allUsersName;
this.account = account;
this.externalIds = externalIds;
this.userName = ExternalId.getUserName(externalIds);
@@ -184,10 +164,6 @@
this.editPreferences = editPreferences;
}
- public AllUsersName getAllUsersNameForIndexing() {
- return allUsersName;
- }
-
/** Get the cached account metadata. */
public Account getAccount() {
return account;
diff --git a/java/com/google/gerrit/server/account/Accounts.java b/java/com/google/gerrit/server/account/Accounts.java
index f3758bf..dbe7ba7 100644
--- a/java/com/google/gerrit/server/account/Accounts.java
+++ b/java/com/google/gerrit/server/account/Accounts.java
@@ -134,9 +134,7 @@
private Optional<AccountState> read(Repository allUsersRepository, Account.Id accountId)
throws IOException, ConfigInvalidException {
return AccountState.fromAccountConfig(
- allUsersName,
- externalIds,
- new AccountConfig(accountId, allUsersName, allUsersRepository).load());
+ externalIds, new AccountConfig(accountId, allUsersName, allUsersRepository).load());
}
public static Stream<Account.Id> readUserRefs(Repository repo) throws IOException {
diff --git a/java/com/google/gerrit/server/account/AccountsUpdate.java b/java/com/google/gerrit/server/account/AccountsUpdate.java
index 20a1c97..2920cef 100644
--- a/java/com/google/gerrit/server/account/AccountsUpdate.java
+++ b/java/com/google/gerrit/server/account/AccountsUpdate.java
@@ -321,7 +321,7 @@
AccountConfig accountConfig = read(r, accountId);
Account account =
accountConfig.getNewAccount(new Timestamp(committerIdent.getWhen().getTime()));
- AccountState accountState = AccountState.forAccount(allUsersName, account);
+ AccountState accountState = AccountState.forAccount(account);
InternalAccountUpdate.Builder updateBuilder = InternalAccountUpdate.builder();
updater.update(accountState, updateBuilder);
@@ -330,7 +330,7 @@
ExternalIdNotes extIdNotes =
createExternalIdNotes(r, accountConfig.getExternalIdsRev(), accountId, update);
UpdatedAccount updatedAccounts =
- new UpdatedAccount(allUsersName, externalIds, message, accountConfig, extIdNotes);
+ new UpdatedAccount(externalIds, message, accountConfig, extIdNotes);
updatedAccounts.setCreated(true);
return updatedAccounts;
})
@@ -377,7 +377,7 @@
r -> {
AccountConfig accountConfig = read(r, accountId);
Optional<AccountState> account =
- AccountState.fromAccountConfig(allUsersName, externalIds, accountConfig);
+ AccountState.fromAccountConfig(externalIds, accountConfig);
if (!account.isPresent()) {
return null;
}
@@ -390,7 +390,7 @@
ExternalIdNotes extIdNotes =
createExternalIdNotes(r, accountConfig.getExternalIdsRev(), accountId, update);
UpdatedAccount updatedAccounts =
- new UpdatedAccount(allUsersName, externalIds, message, accountConfig, extIdNotes);
+ new UpdatedAccount(externalIds, message, accountConfig, extIdNotes);
return updatedAccounts;
});
}
@@ -561,7 +561,6 @@
}
private static class UpdatedAccount {
- private final AllUsersName allUsersName;
private final ExternalIds externalIds;
private final String message;
private final AccountConfig accountConfig;
@@ -570,13 +569,11 @@
private boolean created;
private UpdatedAccount(
- AllUsersName allUsersName,
ExternalIds externalIds,
String message,
AccountConfig accountConfig,
ExternalIdNotes extIdNotes) {
checkState(!Strings.isNullOrEmpty(message), "message for account update must be set");
- this.allUsersName = requireNonNull(allUsersName);
this.externalIds = requireNonNull(externalIds);
this.message = requireNonNull(message);
this.accountConfig = requireNonNull(accountConfig);
@@ -592,8 +589,7 @@
}
public AccountState getAccount() throws IOException {
- return AccountState.fromAccountConfig(allUsersName, externalIds, accountConfig, extIdNotes)
- .get();
+ return AccountState.fromAccountConfig(externalIds, accountConfig, extIdNotes).get();
}
public ExternalIdNotes getExternalIdNotes() {
diff --git a/java/com/google/gerrit/server/account/GroupCacheImpl.java b/java/com/google/gerrit/server/account/GroupCacheImpl.java
index 7ed7ebc..4618835 100644
--- a/java/com/google/gerrit/server/account/GroupCacheImpl.java
+++ b/java/com/google/gerrit/server/account/GroupCacheImpl.java
@@ -21,6 +21,7 @@
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.group.db.Groups;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.gerrit.server.query.group.InternalGroupQuery;
@@ -149,7 +150,9 @@
@Override
public Optional<InternalGroup> load(AccountGroup.Id key) throws Exception {
- try (TraceTimer timer = TraceContext.newTimer("Loading group by ID", "groupId", key)) {
+ try (TraceTimer timer =
+ TraceContext.newTimer(
+ "Loading group by ID", Metadata.builder().groupId(key.get()).build())) {
return groupQueryProvider.get().byId(key);
}
}
@@ -165,7 +168,9 @@
@Override
public Optional<InternalGroup> load(String name) throws Exception {
- try (TraceTimer timer = TraceContext.newTimer("Loading group by name", "groupName", name)) {
+ try (TraceTimer timer =
+ TraceContext.newTimer(
+ "Loading group by name", Metadata.builder().groupName(name).build())) {
return groupQueryProvider.get().byName(AccountGroup.nameKey(name));
}
}
@@ -181,7 +186,9 @@
@Override
public Optional<InternalGroup> load(String uuid) throws Exception {
- try (TraceTimer timer = TraceContext.newTimer("Loading group by UUID", "groupUuid", uuid)) {
+ try (TraceTimer timer =
+ TraceContext.newTimer(
+ "Loading group by UUID", Metadata.builder().groupUuid(uuid).build())) {
return groups.getGroup(AccountGroup.uuid(uuid));
}
}
diff --git a/java/com/google/gerrit/server/account/GroupIncludeCacheImpl.java b/java/com/google/gerrit/server/account/GroupIncludeCacheImpl.java
index 3507ba2..f3c19a8 100644
--- a/java/com/google/gerrit/server/account/GroupIncludeCacheImpl.java
+++ b/java/com/google/gerrit/server/account/GroupIncludeCacheImpl.java
@@ -27,6 +27,7 @@
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.group.db.Groups;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.gerrit.server.query.group.InternalGroupQuery;
@@ -153,7 +154,8 @@
@Override
public ImmutableSet<AccountGroup.UUID> load(Account.Id memberId) {
try (TraceTimer timer =
- TraceContext.newTimer("Loading groups with member", "memberId", memberId)) {
+ TraceContext.newTimer(
+ "Loading groups with member", Metadata.builder().accountId(memberId.get()).build())) {
return groupQueryProvider.get().byMember(memberId).stream()
.map(InternalGroup::getGroupUUID)
.collect(toImmutableSet());
@@ -172,7 +174,9 @@
@Override
public ImmutableList<AccountGroup.UUID> load(AccountGroup.UUID key) {
- try (TraceTimer timer = TraceContext.newTimer("Loading parent groups", "groupUuid", key)) {
+ try (TraceTimer timer =
+ TraceContext.newTimer(
+ "Loading parent groups", Metadata.builder().groupUuid(key.get()).build())) {
return groupQueryProvider.get().bySubgroup(key).stream()
.map(InternalGroup::getGroupUUID)
.collect(toImmutableList());
diff --git a/java/com/google/gerrit/server/account/InternalAccountDirectory.java b/java/com/google/gerrit/server/account/InternalAccountDirectory.java
index 49afaf2..99ad570 100644
--- a/java/com/google/gerrit/server/account/InternalAccountDirectory.java
+++ b/java/com/google/gerrit/server/account/InternalAccountDirectory.java
@@ -150,20 +150,19 @@
if (options.contains(FillOptions.AVATARS)) {
AvatarProvider ap = avatar.get();
if (ap != null) {
- info.avatars = new ArrayList<>(3);
+ info.avatars = new ArrayList<>();
IdentifiedUser user = userFactory.create(account.getId());
- // GWT UI uses DEFAULT_SIZE (26px).
+ // PolyGerrit UI uses the following sizes for avatars:
+ // - 32px for avatars next to names e.g. on the dashboard. This is also Gerrit's default.
+ // - 56px for the user's own avatar in the menu
+ // - 100ox for other user's avatars on dashboards
+ // - 120px for the user's own profile settings page
addAvatar(ap, info, user, AvatarInfo.DEFAULT_SIZE);
-
- // PolyGerrit UI prefers 32px and 100px.
if (!info.avatars.isEmpty()) {
- if (32 != AvatarInfo.DEFAULT_SIZE) {
- addAvatar(ap, info, user, 32);
- }
- if (100 != AvatarInfo.DEFAULT_SIZE) {
- addAvatar(ap, info, user, 100);
- }
+ addAvatar(ap, info, user, 56);
+ addAvatar(ap, info, user, 100);
+ addAvatar(ap, info, user, 120);
}
}
}
diff --git a/java/com/google/gerrit/server/account/externalids/ExternalIdCacheImpl.java b/java/com/google/gerrit/server/account/externalids/ExternalIdCacheImpl.java
index ad861c0..25fca4d 100644
--- a/java/com/google/gerrit/server/account/externalids/ExternalIdCacheImpl.java
+++ b/java/com/google/gerrit/server/account/externalids/ExternalIdCacheImpl.java
@@ -22,6 +22,7 @@
import com.google.common.collect.SetMultimap;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.inject.Inject;
@@ -157,7 +158,9 @@
@Override
public AllExternalIds load(ObjectId notesRev) throws Exception {
- try (TraceTimer timer = TraceContext.newTimer("Loading external IDs", "revision", notesRev)) {
+ try (TraceTimer timer =
+ TraceContext.newTimer(
+ "Loading external IDs", Metadata.builder().revision(notesRev.name()).build())) {
ImmutableSet<ExternalId> externalIds = externalIdReader.all(notesRev);
externalIds.forEach(ExternalId::checkThatBlobIdIsSet);
return AllExternalIds.create(externalIds);
diff --git a/java/com/google/gerrit/server/auth/ldap/LdapRealm.java b/java/com/google/gerrit/server/auth/ldap/LdapRealm.java
index c12aaf5..3b84fb8 100644
--- a/java/com/google/gerrit/server/auth/ldap/LdapRealm.java
+++ b/java/com/google/gerrit/server/auth/ldap/LdapRealm.java
@@ -37,6 +37,7 @@
import com.google.gerrit.server.auth.NoSuchUserException;
import com.google.gerrit.server.config.AuthConfig;
import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.inject.Inject;
@@ -354,7 +355,8 @@
@Override
public Optional<Account.Id> load(String username) throws Exception {
try (TraceTimer timer =
- TraceContext.newTimer("Loading account for username", "username", username)) {
+ TraceContext.newTimer(
+ "Loading account for username", Metadata.builder().username(username).build())) {
return externalIds
.get(ExternalId.Key.create(SCHEME_GERRIT, username))
.map(ExternalId::accountId);
@@ -373,7 +375,9 @@
@Override
public Set<AccountGroup.UUID> load(String username) throws Exception {
try (TraceTimer timer =
- TraceContext.newTimer("Loading group for member with username", "username", username)) {
+ TraceContext.newTimer(
+ "Loading group for member with username",
+ Metadata.builder().username(username).build())) {
final DirContext ctx = helper.open();
try {
return helper.queryForGroups(ctx, username, null);
@@ -394,7 +398,9 @@
@Override
public Boolean load(String groupDn) throws Exception {
- try (TraceTimer timer = TraceContext.newTimer("Loading groupDn", "groupDn", groupDn)) {
+ try (TraceTimer timer =
+ TraceContext.newTimer(
+ "Loading groupDn", Metadata.builder().authDomainName(groupDn).build())) {
final DirContext ctx = helper.open();
try {
Name compositeGroupName = new CompositeName().add(groupDn);
diff --git a/java/com/google/gerrit/server/cache/CacheMetrics.java b/java/com/google/gerrit/server/cache/CacheMetrics.java
index 502dfa4..1ef5a3b 100644
--- a/java/com/google/gerrit/server/cache/CacheMetrics.java
+++ b/java/com/google/gerrit/server/cache/CacheMetrics.java
@@ -25,6 +25,7 @@
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.MetricMaker;
+import com.google.gerrit.server.logging.Metadata;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.util.Set;
@@ -33,7 +34,7 @@
public class CacheMetrics {
@Inject
public CacheMetrics(MetricMaker metrics, DynamicMap<Cache<?, ?>> cacheMap) {
- Field<String> F_NAME = Field.ofString("cache_name").build();
+ Field<String> F_NAME = Field.ofString("cache_name", Metadata.Builder::cacheName).build();
CallbackMetric1<String, Long> memEnt =
metrics.newCallbackMetric(
diff --git a/java/com/google/gerrit/server/cache/h2/H2CacheImpl.java b/java/com/google/gerrit/server/cache/h2/H2CacheImpl.java
index 2b44019..ef4e44c 100644
--- a/java/com/google/gerrit/server/cache/h2/H2CacheImpl.java
+++ b/java/com/google/gerrit/server/cache/h2/H2CacheImpl.java
@@ -26,6 +26,7 @@
import com.google.gerrit.common.Nullable;
import com.google.gerrit.server.cache.PersistentCache;
import com.google.gerrit.server.cache.serialize.CacheSerializer;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.gerrit.server.util.time.TimeUtil;
@@ -237,7 +238,9 @@
@Override
public ValueHolder<V> load(K key) throws Exception {
- try (TraceTimer timer = TraceContext.newTimer("Loading value from cache", "key", key)) {
+ try (TraceTimer timer =
+ TraceContext.newTimer(
+ "Loading value from cache", Metadata.builder().cacheKey(key.toString()).build())) {
if (store.mightContain(key)) {
ValueHolder<V> h = store.getIfPresent(key);
if (h != null) {
diff --git a/java/com/google/gerrit/server/change/ChangeFinder.java b/java/com/google/gerrit/server/change/ChangeFinder.java
index 1cdb621..2d4f105 100644
--- a/java/com/google/gerrit/server/change/ChangeFinder.java
+++ b/java/com/google/gerrit/server/change/ChangeFinder.java
@@ -34,6 +34,7 @@
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.config.ConfigUtil;
import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.query.change.ChangeData;
@@ -98,7 +99,8 @@
new Description("Total number of API calls per identifier type.")
.setRate()
.setUnit("requests"),
- Field.ofEnum(ChangeIdType.class, "change_id_type").build());
+ Field.ofEnum(ChangeIdType.class, "change_id_type", Metadata.Builder::changeIdType)
+ .build());
List<ChangeIdType> configuredChangeIdTypes =
ConfigUtil.getEnumList(config, "change", "api", "allowedIdentifier", ChangeIdType.ALL);
// Ensure that PROJECT_NUMERIC_ID can't be removed
diff --git a/java/com/google/gerrit/server/config/GerritGlobalModule.java b/java/com/google/gerrit/server/config/GerritGlobalModule.java
index afe4e52..bbc5748 100644
--- a/java/com/google/gerrit/server/config/GerritGlobalModule.java
+++ b/java/com/google/gerrit/server/config/GerritGlobalModule.java
@@ -79,6 +79,8 @@
import com.google.gerrit.server.CreateGroupPermissionSyncer;
import com.google.gerrit.server.DynamicOptions;
import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.RequestListener;
+import com.google.gerrit.server.TraceRequestListener;
import com.google.gerrit.server.account.AccountCacheImpl;
import com.google.gerrit.server.account.AccountControl;
import com.google.gerrit.server.account.AccountDeactivator;
@@ -384,6 +386,8 @@
DynamicSet.setOf(binder(), SubmitRule.class);
DynamicSet.setOf(binder(), QuotaEnforcer.class);
DynamicSet.setOf(binder(), PerformanceLogger.class);
+ DynamicSet.setOf(binder(), RequestListener.class);
+ DynamicSet.bind(binder(), RequestListener.class).to(TraceRequestListener.class);
DynamicMap.mapOf(binder(), MailFilter.class);
bind(MailFilter.class).annotatedWith(Exports.named("ListMailFilter")).to(ListMailFilter.class);
diff --git a/java/com/google/gerrit/server/events/EventsMetrics.java b/java/com/google/gerrit/server/events/EventsMetrics.java
index ae70bab..3c87cca 100644
--- a/java/com/google/gerrit/server/events/EventsMetrics.java
+++ b/java/com/google/gerrit/server/events/EventsMetrics.java
@@ -18,6 +18,7 @@
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.MetricMaker;
+import com.google.gerrit.server.logging.Metadata;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -31,7 +32,7 @@
metricMaker.newCounter(
"events",
new Description("Triggered events").setRate().setUnit("triggered events"),
- Field.ofString("type").build());
+ Field.ofString("type", Metadata.Builder::eventType).build());
}
@Override
diff --git a/java/com/google/gerrit/server/extensions/webui/UiActions.java b/java/com/google/gerrit/server/extensions/webui/UiActions.java
index 41fcd95..0bc3d5c 100644
--- a/java/com/google/gerrit/server/extensions/webui/UiActions.java
+++ b/java/com/google/gerrit/server/extensions/webui/UiActions.java
@@ -37,6 +37,7 @@
import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.metrics.Timer1;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendCondition;
@@ -71,7 +72,7 @@
new com.google.gerrit.metrics.Description("Latency for RestView#getDescription calls")
.setCumulative()
.setUnit(Units.MILLISECONDS),
- Field.ofString("view").build());
+ Field.ofString("view", Metadata.Builder::restViewName).build());
}
public <R extends RestResource> Iterable<UiAction.Description> from(
diff --git a/java/com/google/gerrit/server/git/DefaultAdvertiseRefsHook.java b/java/com/google/gerrit/server/git/DefaultAdvertiseRefsHook.java
index a8594e7..d1a6df6 100644
--- a/java/com/google/gerrit/server/git/DefaultAdvertiseRefsHook.java
+++ b/java/com/google/gerrit/server/git/DefaultAdvertiseRefsHook.java
@@ -15,6 +15,7 @@
package com.google.gerrit.server.git;
import com.google.common.collect.ImmutableList;
+import com.google.common.flogger.FluentLogger;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import java.io.IOException;
@@ -32,6 +33,8 @@
* implements {@link org.eclipse.jgit.transport.AdvertiseRefsHook}.
*/
public class DefaultAdvertiseRefsHook extends AbstractAdvertiseRefsHook {
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+
private final PermissionBackend.ForProject perm;
private final PermissionBackend.RefFilterOptions opts;
@@ -44,6 +47,7 @@
@Override
protected Map<String, Ref> getAdvertisedRefs(Repository repo, RevWalk revWalk)
throws ServiceMayNotContinueException {
+ logger.atFine().log("ref filter options = %s", opts);
try {
List<String> prefixes =
!opts.prefixes().isEmpty() ? opts.prefixes() : ImmutableList.of(RefDatabase.ALL);
diff --git a/java/com/google/gerrit/server/git/MergeUtil.java b/java/com/google/gerrit/server/git/MergeUtil.java
index 4088c81..e464e81 100644
--- a/java/com/google/gerrit/server/git/MergeUtil.java
+++ b/java/com/google/gerrit/server/git/MergeUtil.java
@@ -17,15 +17,17 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
+import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet;
import static com.google.gerrit.git.ObjectIds.abbreviateName;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.util.Comparator.naturalOrder;
import static java.util.Objects.requireNonNull;
+import static java.util.stream.Collectors.joining;
-import com.google.common.base.Joiner;
import com.google.common.base.Strings;
-import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.common.flogger.FluentLogger;
@@ -68,7 +70,6 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
-import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -847,26 +848,22 @@
return String.format("Merge \"%s\"", c.getShortMessage());
}
- LinkedHashSet<String> topics = new LinkedHashSet<>(4);
- for (CodeReviewCommit c : merged) {
- if (!Strings.isNullOrEmpty(c.change().getTopic())) {
- topics.add(c.change().getTopic());
- }
- }
+ ImmutableSortedSet<String> topics =
+ merged.stream()
+ .map(c -> c.change().getTopic())
+ .filter(t -> !Strings.isNullOrEmpty(t))
+ .map(t -> "\"" + t + "\"")
+ .collect(toImmutableSortedSet(naturalOrder()));
- if (topics.size() == 1) {
- return String.format("Merge changes from topic \"%s\"", Iterables.getFirst(topics, null));
- } else if (topics.size() > 1) {
- return String.format("Merge changes from topics \"%s\"", Joiner.on("\", \"").join(topics));
- } else {
+ if (!topics.isEmpty()) {
return String.format(
- "Merge changes %s%s",
- FluentIterable.from(merged)
- .limit(5)
- .transform(c -> c.change().getKey().abbreviate())
- .join(Joiner.on(',')),
- merged.size() > 5 ? ", ..." : "");
+ "Merge changes from topic%s %s",
+ topics.size() > 1 ? "s" : "", topics.stream().collect(joining(", ")));
}
+ return merged.stream()
+ .limit(5)
+ .map(c -> c.change().getKey().abbreviate())
+ .collect(joining(",", "Merge changes ", merged.size() > 5 ? ", ..." : ""));
}
public ThreeWayMerger newThreeWayMerger(ObjectInserter inserter, Config repoConfig) {
diff --git a/java/com/google/gerrit/server/git/NotifyConfig.java b/java/com/google/gerrit/server/git/NotifyConfig.java
index d39cf12..2ca2744a 100644
--- a/java/com/google/gerrit/server/git/NotifyConfig.java
+++ b/java/com/google/gerrit/server/git/NotifyConfig.java
@@ -14,6 +14,7 @@
package com.google.gerrit.server.git;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.mail.Address;
@@ -113,6 +114,13 @@
@Override
public String toString() {
- return "NotifyConfig[" + name + " = " + addresses + " + " + groups + "]";
+ return MoreObjects.toStringHelper(this)
+ .add("name", name)
+ .add("addresses", addresses)
+ .add("groups", groups)
+ .add("header", header)
+ .add("types", types)
+ .add("filter", filter)
+ .toString();
}
}
diff --git a/java/com/google/gerrit/server/git/PureRevertCache.java b/java/com/google/gerrit/server/git/PureRevertCache.java
index 4937713..6679b52 100644
--- a/java/com/google/gerrit/server/git/PureRevertCache.java
+++ b/java/com/google/gerrit/server/git/PureRevertCache.java
@@ -27,6 +27,7 @@
import com.google.gerrit.server.cache.serialize.BooleanCacheSerializer;
import com.google.gerrit.server.cache.serialize.ObjectIdConverter;
import com.google.gerrit.server.cache.serialize.ProtobufSerializer;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.project.ProjectCache;
@@ -35,7 +36,6 @@
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.google.protobuf.ByteString;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
@@ -49,6 +49,7 @@
import org.eclipse.jgit.merge.ThreeWayMerger;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.util.io.DisabledOutputStream;
/** Computes and caches if a change is a pure revert of another change. */
@Singleton
@@ -151,7 +152,9 @@
@Override
public Boolean load(PureRevertKeyProto key) throws BadRequestException, IOException {
try (TraceContext.TraceTimer ignored =
- TraceContext.newTimer("Loading pure revert", "key", key)) {
+ TraceContext.newTimer(
+ "Loading pure revert",
+ Metadata.builder().cacheKey(key.toString()).projectName(key.getProject()).build())) {
ObjectId original = ObjectIdConverter.create().fromByteString(key.getClaimedOriginal());
ObjectId revert = ObjectIdConverter.create().fromByteString(key.getClaimedRevert());
Project.NameKey project = Project.nameKey(key.getProject());
@@ -185,9 +188,8 @@
}
// Any differences between claimed original's parent and the rebase result indicate that
- // the
- // claimedRevert is not a pure revert but made content changes
- try (DiffFormatter df = new DiffFormatter(new ByteArrayOutputStream())) {
+ // the claimedRevert is not a pure revert but made content changes
+ try (DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE)) {
df.setReader(oi.newReader(), repo.getConfig());
List<DiffEntry> entries =
df.scan(claimedOriginalCommit.getParent(0), merger.getResultTreeId());
diff --git a/java/com/google/gerrit/server/git/SearchingChangeCacheImpl.java b/java/com/google/gerrit/server/git/SearchingChangeCacheImpl.java
index 15284fe..44c0ee3 100644
--- a/java/com/google/gerrit/server/git/SearchingChangeCacheImpl.java
+++ b/java/com/google/gerrit/server/git/SearchingChangeCacheImpl.java
@@ -28,6 +28,7 @@
import com.google.gerrit.server.ReviewerSet;
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.index.change.ChangeField;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.gerrit.server.query.change.ChangeData;
@@ -153,7 +154,8 @@
@Override
public List<CachedChange> load(Project.NameKey key) throws Exception {
try (TraceTimer timer =
- TraceContext.newTimer("Loading changes of project", "projectName", key);
+ TraceContext.newTimer(
+ "Loading changes of project", Metadata.builder().projectName(key.get()).build());
ManualRequestContext ctx = requestContext.open()) {
List<ChangeData> cds =
queryProvider
diff --git a/java/com/google/gerrit/server/git/UploadPackMetricsHook.java b/java/com/google/gerrit/server/git/UploadPackMetricsHook.java
index 8be68bf..4afff2b 100644
--- a/java/com/google/gerrit/server/git/UploadPackMetricsHook.java
+++ b/java/com/google/gerrit/server/git/UploadPackMetricsHook.java
@@ -23,6 +23,7 @@
import com.google.gerrit.metrics.Histogram1;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.metrics.Timer1;
+import com.google.gerrit.server.logging.Metadata;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.eclipse.jgit.storage.pack.PackStatistics;
@@ -43,7 +44,8 @@
@Inject
UploadPackMetricsHook(MetricMaker metricMaker) {
- Field<Operation> operationField = Field.ofEnum(Operation.class, "operation").build();
+ Field<Operation> operationField =
+ Field.ofEnum(Operation.class, "operation", Metadata.Builder::gitOperation).build();
requestCount =
metricMaker.newCounter(
"git/upload-pack/request_count",
diff --git a/java/com/google/gerrit/server/git/meta/VersionedMetaData.java b/java/com/google/gerrit/server/git/meta/VersionedMetaData.java
index 6356068..f2180d7 100644
--- a/java/com/google/gerrit/server/git/meta/VersionedMetaData.java
+++ b/java/com/google/gerrit/server/git/meta/VersionedMetaData.java
@@ -21,6 +21,7 @@
import com.google.gerrit.git.LockFailureException;
import com.google.gerrit.git.ObjectIds;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import java.io.BufferedReader;
@@ -500,14 +501,12 @@
try (TraceTimer timer =
TraceContext.newTimer(
"Read file",
- "fileName",
- fileName,
- "ref",
- getRefName(),
- "projectName",
- projectName,
- "revision",
- revision.name());
+ Metadata.builder()
+ .projectName(projectName.get())
+ .noteDbRefName(getRefName())
+ .revision(revision.name())
+ .noteDbFilePath(fileName)
+ .build());
TreeWalk tw = TreeWalk.forPath(reader, fileName, revision.getTree())) {
if (tw != null) {
ObjectLoader obj = reader.open(tw.getObjectId(0), Constants.OBJ_BLOB);
@@ -582,7 +581,12 @@
protected void saveFile(String fileName, byte[] raw) throws IOException {
try (TraceTimer timer =
TraceContext.newTimer(
- "Save file", "fileName", fileName, "ref", getRefName(), "projectName", projectName)) {
+ "Save file",
+ Metadata.builder()
+ .projectName(projectName.get())
+ .noteDbRefName(getRefName())
+ .noteDbFilePath(fileName)
+ .build())) {
DirCacheEditor editor = newTree.editor();
if (raw != null && 0 < raw.length) {
final ObjectId blobId = inserter.insert(Constants.OBJ_BLOB, raw);
diff --git a/java/com/google/gerrit/server/git/receive/AsyncReceiveCommits.java b/java/com/google/gerrit/server/git/receive/AsyncReceiveCommits.java
index 64aecf5..bce5b0a 100644
--- a/java/com/google/gerrit/server/git/receive/AsyncReceiveCommits.java
+++ b/java/com/google/gerrit/server/git/receive/AsyncReceiveCommits.java
@@ -38,6 +38,7 @@
import com.google.gerrit.server.git.MultiProgressMonitor;
import com.google.gerrit.server.git.ProjectRunnable;
import com.google.gerrit.server.git.TransferConfig;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.ProjectPermission;
@@ -199,12 +200,12 @@
metricMaker.newHistogram(
"receivecommits/changes_per_push",
new Description("number of changes uploaded in a single push.").setCumulative(),
- Field.ofEnum(PushType.class, "type")
+ Field.ofEnum(PushType.class, "type", Metadata.Builder::pushType)
.description("type of push (create/replace, autoclose)")
.build());
Field<PushType> pushTypeField =
- Field.ofEnum(PushType.class, "type")
+ Field.ofEnum(PushType.class, "type", Metadata.Builder::pushType)
.description("type of push (create/replace, autoclose, normal)")
.build();
diff --git a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
index 1444070..f8e6751 100644
--- a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
+++ b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
@@ -15,7 +15,6 @@
package com.google.gerrit.server.git.receive;
import static com.google.common.base.MoreObjects.firstNonNull;
-import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
@@ -68,6 +67,7 @@
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.extensions.api.changes.HashtagsInput;
import com.google.gerrit.extensions.api.changes.NotifyHandling;
+import com.google.gerrit.extensions.api.changes.NotifyInfo;
import com.google.gerrit.extensions.api.changes.RecipientType;
import com.google.gerrit.extensions.api.changes.SubmitInput;
import com.google.gerrit.extensions.api.projects.ProjectConfigEntryType;
@@ -101,6 +101,8 @@
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.PublishCommentUtil;
+import com.google.gerrit.server.RequestInfo;
+import com.google.gerrit.server.RequestListener;
import com.google.gerrit.server.account.AccountResolver;
import com.google.gerrit.server.change.ChangeInserter;
import com.google.gerrit.server.change.NotifyResolver;
@@ -126,6 +128,7 @@
import com.google.gerrit.server.git.validators.RefOperationValidators;
import com.google.gerrit.server.git.validators.ValidationMessage;
import com.google.gerrit.server.index.change.ChangeIndexer;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.PerformanceLogContext;
import com.google.gerrit.server.logging.PerformanceLogger;
import com.google.gerrit.server.logging.RequestId;
@@ -195,7 +198,6 @@
import java.util.TreeSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
-import java.util.regex.Matcher;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.jgit.errors.ConfigInvalidException;
@@ -329,6 +331,7 @@
private final ReceiveConfig receiveConfig;
private final RefOperationValidators.Factory refValidatorsFactory;
private final ReplaceOp.Factory replaceOpFactory;
+ private final PluginSetContext<RequestListener> requestListeners;
private final RetryHelper retryHelper;
private final RequestScopePropagator requestScopePropagator;
private final Sequences seq;
@@ -346,7 +349,6 @@
// Immutable fields derived from constructor arguments.
private final boolean allowProjectOwnersToChangeParent;
- private final boolean allowPushToRefsChanges;
private final LabelTypes labelTypes;
private final NoteMap rejectCommits;
private final PermissionBackend.ForProject permissions;
@@ -408,6 +410,7 @@
ReceiveConfig receiveConfig,
RefOperationValidators.Factory refValidatorsFactory,
ReplaceOp.Factory replaceOpFactory,
+ PluginSetContext<RequestListener> requestListeners,
RetryHelper retryHelper,
RequestScopePropagator requestScopePropagator,
Sequences seq,
@@ -453,6 +456,7 @@
this.receiveConfig = receiveConfig;
this.refValidatorsFactory = refValidatorsFactory;
this.replaceOpFactory = replaceOpFactory;
+ this.requestListeners = requestListeners;
this.retryHelper = retryHelper;
this.requestScopePropagator = requestScopePropagator;
this.seq = seq;
@@ -468,7 +472,6 @@
this.receivePack = rp;
// Immutable fields derived from constructor arguments.
- allowPushToRefsChanges = config.getBoolean("receive", "allowPushToRefsChanges", false);
repo = rp.getRepository();
project = projectState.getProject();
labelTypes = projectState.getLabelTypes();
@@ -529,14 +532,21 @@
void processCommands(Collection<ReceiveCommand> commands, MultiProgressMonitor progress) {
parsePushOptions();
+ int commandCount = commands.size();
try (TraceContext traceContext =
TraceContext.newTrace(
tracePushOption.isPresent(),
tracePushOption.orElse(null),
(tagName, traceId) -> addMessage(tagName + ": " + traceId));
- TraceTimer traceTimer = newTimer("processCommands", "commandCount", commands.size());
+ TraceTimer traceTimer =
+ newTimer("processCommands", Metadata.builder().resourceCount(commandCount));
PerformanceLogContext performanceLogContext =
new PerformanceLogContext(config, performanceLoggers)) {
+ RequestInfo requestInfo =
+ RequestInfo.builder(RequestInfo.RequestType.GIT_RECEIVE, user, traceContext)
+ .project(project.getNameKey())
+ .build();
+ requestListeners.runEach(l -> l.onRequest(requestInfo));
traceContext.addTag(RequestId.Type.RECEIVE_ID, new RequestId(project.getNameKey().get()));
// Log the push options here, rather than in parsePushOptions(), so that they are included
@@ -576,23 +586,17 @@
logger.atFine().log("Parsing %d commands", commands.size());
List<ReceiveCommand> magicCommands = new ArrayList<>();
- List<ReceiveCommand> directPatchSetPushCommands = new ArrayList<>();
List<ReceiveCommand> regularCommands = new ArrayList<>();
for (ReceiveCommand cmd : commands) {
if (MagicBranch.isMagicBranch(cmd.getRefName())) {
magicCommands.add(cmd);
- } else if (isDirectChangesPush(cmd.getRefName())) {
- directPatchSetPushCommands.add(cmd);
} else {
regularCommands.add(cmd);
}
}
- int commandTypes =
- (magicCommands.isEmpty() ? 0 : 1)
- + (directPatchSetPushCommands.isEmpty() ? 0 : 1)
- + (regularCommands.isEmpty() ? 0 : 1);
+ int commandTypes = (magicCommands.isEmpty() ? 0 : 1) + (regularCommands.isEmpty() ? 0 : 1);
if (commandTypes > 1) {
rejectRemaining(commands, "cannot combine normal pushes and magic pushes");
@@ -605,8 +609,6 @@
return;
}
- parseDirectChangesPushCommands(directPatchSetPushCommands);
-
boolean first = true;
for (ReceiveCommand cmd : magicCommands) {
if (first) {
@@ -656,7 +658,8 @@
private void handleRegularCommands(List<ReceiveCommand> cmds, MultiProgressMonitor progress)
throws PermissionBackendException, IOException, NoSuchProjectException {
- try (TraceTimer traceTimer = newTimer("handleRegularCommands", "commandCount", cmds.size())) {
+ try (TraceTimer traceTimer =
+ newTimer("handleRegularCommands", Metadata.builder().resourceCount(cmds.size()))) {
resultChangeIds.setMagicPush(false);
for (ReceiveCommand cmd : cmds) {
parseRegularCommand(cmd);
@@ -840,7 +843,8 @@
private void insertChangesAndPatchSets(List<CreateRequest> newChanges, Task replaceProgress) {
try (TraceTimer traceTimer =
- newTimer("insertChangesAndPatchSets", "changeCount", newChanges.size())) {
+ newTimer(
+ "insertChangesAndPatchSets", Metadata.builder().resourceCount(newChanges.size()))) {
ReceiveCommand magicBranchCmd = magicBranch != null ? magicBranch.cmd : null;
if (magicBranchCmd != null && magicBranchCmd.getResult() != NOT_ATTEMPTED) {
logger.atWarning().log(
@@ -984,37 +988,6 @@
}
}
- private static boolean isDirectChangesPush(String refname) {
- Matcher m = NEW_PATCHSET_PATTERN.matcher(refname);
- return m.matches();
- }
-
- private void parseDirectChangesPushCommands(List<ReceiveCommand> cmds) {
- try (TraceTimer traceTimer =
- newTimer("parseDirectChangesPushCommands", "commandCount", cmds.size())) {
- for (ReceiveCommand cmd : cmds) {
- parseDirectChangesPush(cmd);
- }
- }
- }
-
- private void parseDirectChangesPush(ReceiveCommand cmd) {
- if (allowPushToRefsChanges) {
- try (TraceTimer traceTimer = newTimer("parseDirectChangesPush")) {
- Matcher m = NEW_PATCHSET_PATTERN.matcher(cmd.getRefName());
- checkArgument(m.matches());
-
- // The referenced change must exist and must still be open.
- Change.Id changeId = Change.Id.parse(m.group(1));
- parseReplaceCommand(cmd, changeId);
- messages.add(
- new ValidationMessage("warning: pushes to refs/changes are deprecated", false));
- }
- } else {
- reject(cmd, "upload to refs/changes not allowed");
- }
- }
-
// Wrap ReceiveCommand so the progress counter works automatically.
private ReceiveCommand wrapReceiveCommand(ReceiveCommand cmd, Task progress) {
String refname = cmd.getRefName();
@@ -1415,10 +1388,13 @@
static class MagicBranchInput {
private static final Splitter COMMAS = Splitter.on(',').omitEmptyStrings();
+ private final IdentifiedUser user;
+ private final ProjectState projectState;
+ private final boolean defaultPublishComments;
+
boolean deprecatedTopicSeen;
final ReceiveCommand cmd;
final LabelTypes labelTypes;
- private final boolean defaultPublishComments;
/**
* Result of running {@link CommentValidator}-s on drafts that are published with the commit
* (which happens iff {@code --publish-comments} is set). Remains {@code true} if none are
@@ -1582,7 +1558,10 @@
@Option(name = "--create-cod-token", usage = "create a token for consistency-on-demand")
private boolean createCodToken;
- MagicBranchInput(IdentifiedUser user, ReceiveCommand cmd, LabelTypes labelTypes) {
+ MagicBranchInput(
+ IdentifiedUser user, ProjectState projectState, ReceiveCommand cmd, LabelTypes labelTypes) {
+ this.user = user;
+ this.projectState = projectState;
this.deprecatedTopicSeen = false;
this.cmd = cmd;
this.draft = cmd.getRefName().startsWith(MagicBranch.NEW_DRAFT_CHANGE);
@@ -1695,9 +1674,24 @@
return ref.substring(0, split);
}
+ public boolean shouldSetWorkInProgressOnNewChanges() {
+ // When wip or ready explicitly provided, leave it as is.
+ if (workInProgress) {
+ return true;
+ }
+ if (ready) {
+ return false;
+ }
+
+ return projectState.is(BooleanProjectConfig.WORK_IN_PROGRESS_BY_DEFAULT)
+ || firstNonNull(user.state().getGeneralPreferences().workInProgressByDefault, false);
+ }
+
NotifyResolver.Result getNotifyForNewChange() {
return NotifyResolver.Result.create(
- firstNonNull(notifyHandling, workInProgress ? NotifyHandling.OWNER : NotifyHandling.ALL),
+ firstNonNull(
+ notifyHandling,
+ shouldSetWorkInProgressOnNewChanges() ? NotifyHandling.OWNER : NotifyHandling.ALL),
ImmutableSetMultimap.<RecipientType, Account.Id>builder()
.putAll(RecipientType.TO, notifyTo)
.putAll(RecipientType.CC, notifyCc)
@@ -1726,7 +1720,7 @@
private void parseMagicBranch(ReceiveCommand cmd) throws PermissionBackendException {
try (TraceTimer traceTimer = newTimer("parseMagicBranch")) {
logger.atFine().log("Found magic branch %s", cmd.getRefName());
- MagicBranchInput magicBranch = new MagicBranchInput(user, cmd, labelTypes);
+ MagicBranchInput magicBranch = new MagicBranchInput(user, projectState, cmd, labelTypes);
String ref;
magicBranch.cmdLineParser = optionParserFactory.create(magicBranch);
@@ -1934,7 +1928,8 @@
// looking to see if we can compute a merge base between the new
// commits and the target branch head.
private boolean validateConnected(ReceiveCommand cmd, BranchNameKey dest, RevCommit tip) {
- try (TraceTimer traceTimer = newTimer("validateConnected", "branch", dest.branch())) {
+ try (TraceTimer traceTimer =
+ newTimer("validateConnected", Metadata.builder().branchName(dest.branch()))) {
RevWalk walk = receivePack.getRevWalk();
try {
Ref targetRef = receivePack.getAdvertisedRefs().get(dest.branch());
@@ -1992,64 +1987,6 @@
return receivePack.getRevWalk().parseCommit(r.getObjectId());
}
- // Handle an upload to refs/changes/XX/CHANGED-NUMBER.
- private void parseReplaceCommand(ReceiveCommand cmd, Change.Id changeId) {
- try (TraceTimer traceTimer = newTimer("parseReplaceCommand")) {
- logger.atFine().log("Parsing replace command");
- if (cmd.getType() != ReceiveCommand.Type.CREATE) {
- reject(cmd, "invalid usage");
- return;
- }
-
- RevCommit newCommit;
- try {
- newCommit = receivePack.getRevWalk().parseCommit(cmd.getNewId());
- logger.atFine().log("Replacing with %s", newCommit);
- } catch (IOException e) {
- logger.atSevere().withCause(e).log("Cannot parse %s as commit", cmd.getNewId().name());
- reject(cmd, "invalid commit");
- return;
- }
-
- Change changeEnt;
- try {
- changeEnt = notesFactory.createChecked(project.getNameKey(), changeId).getChange();
- } catch (NoSuchChangeException e) {
- logger.atSevere().withCause(e).log("Change not found %s", changeId);
- reject(cmd, "change " + changeId + " not found");
- return;
- } catch (StorageException e) {
- logger.atSevere().withCause(e).log("Cannot lookup existing change %s", changeId);
- reject(cmd, "database error");
- return;
- }
- if (!project.getNameKey().equals(changeEnt.getProject())) {
- reject(cmd, "change " + changeId + " does not belong to project " + project.getName());
- return;
- }
-
- BranchCommitValidator validator =
- commitValidatorFactory.create(projectState, changeEnt.getDest(), user);
- try {
- BranchCommitValidator.Result validationResult =
- validator.validateCommit(
- receivePack.getRevWalk().getObjectReader(),
- cmd,
- newCommit,
- false,
- rejectCommits,
- changeEnt);
- messages.addAll(validationResult.messages());
- if (validationResult.isValid()) {
- logger.atFine().log("Replacing change %s", changeEnt.getId());
- requestReplaceAndValidateComments(cmd, true, changeEnt, newCommit);
- }
- } catch (IOException e) {
- reject(cmd, "I/O exception validating commit");
- }
- }
- }
-
/**
* Update an existing change. If draft comments are to be published, these are validated and may
* be withheld.
@@ -2484,7 +2421,8 @@
// Mark all branch tips as uninteresting in the given revwalk,
// so we get only the new commits when walking rw.
private void markHeadsAsUninteresting(RevWalk rw, @Nullable String forRef) {
- try (TraceTimer traceTimer = newTimer("markHeadsAsUninteresting", "forRef", forRef)) {
+ try (TraceTimer traceTimer =
+ newTimer("markHeadsAsUninteresting", Metadata.builder().branchName(forRef))) {
int i = 0;
for (Ref ref : allRefs().values()) {
if ((ref.getName().startsWith(R_HEADS) || ref.getName().equals(forRef))
@@ -2549,15 +2487,13 @@
private void setChangeId(int id) {
try (TraceTimer traceTimer = newTimer(CreateRequest.class, "setChangeId")) {
- possiblyOverrideWorkInProgress();
-
changeId = Change.id(id);
ins =
changeInserterFactory
.create(changeId, commit, refName)
.setTopic(magicBranch.topic)
.setPrivate(setChangeAsPrivate)
- .setWorkInProgress(magicBranch.workInProgress)
+ .setWorkInProgress(magicBranch.shouldSetWorkInProgressOnNewChanges())
// Changes already validated in validateNewCommits.
.setValidate(false);
@@ -2571,16 +2507,6 @@
}
}
- private void possiblyOverrideWorkInProgress() {
- // When wip or ready explicitly provided, leave it as is.
- if (magicBranch.workInProgress || magicBranch.ready) {
- return;
- }
- magicBranch.workInProgress =
- projectState.is(BooleanProjectConfig.WORK_IN_PROGRESS_BY_DEFAULT)
- || firstNonNull(user.state().getGeneralPreferences().workInProgressByDefault, false);
- }
-
private void addOps(BatchUpdate bu) throws RestApiException {
try (TraceTimer traceTimer = newTimer(CreateRequest.class, "addOps")) {
checkState(changeId != null, "must call setChangeId before addOps");
@@ -2679,14 +2605,27 @@
"Processing submit with tip change %s (%s)",
tipChange.getId(), magicBranch.cmd.getNewId());
try (MergeOp op = mergeOpProvider.get()) {
- op.merge(tipChange, user, false, new SubmitInput(), false);
+ SubmitInput submitInput = new SubmitInput();
+ submitInput.notify = magicBranch.notifyHandling;
+ submitInput.notifyDetails = new HashMap<>();
+ submitInput.notifyDetails.put(
+ RecipientType.TO,
+ new NotifyInfo(magicBranch.notifyTo.stream().map(Object::toString).collect(toList())));
+ submitInput.notifyDetails.put(
+ RecipientType.CC,
+ new NotifyInfo(magicBranch.notifyCc.stream().map(Object::toString).collect(toList())));
+ submitInput.notifyDetails.put(
+ RecipientType.BCC,
+ new NotifyInfo(magicBranch.notifyBcc.stream().map(Object::toString).collect(toList())));
+ op.merge(tipChange, user, false, submitInput, false);
}
}
}
private void preparePatchSetsForReplace(List<CreateRequest> newChanges) {
try (TraceTimer traceTimer =
- newTimer("preparePatchSetsForReplace", "changeCount", newChanges.size())) {
+ newTimer(
+ "preparePatchSetsForReplace", Metadata.builder().resourceCount(newChanges.size()))) {
try {
readChangesForReplace();
for (ReplaceRequest req : replaceByChange.values()) {
@@ -3210,7 +3149,7 @@
private void validateRegularPushCommits(BranchNameKey branch, ReceiveCommand cmd)
throws PermissionBackendException {
try (TraceTimer traceTimer =
- newTimer("validateRegularPushCommits", "branch", branch.branch())) {
+ newTimer("validateRegularPushCommits", Metadata.builder().branchName(branch.branch()))) {
boolean skipValidation =
!RefNames.REFS_CONFIG.equals(cmd.getRefName())
&& !(MagicBranch.isMagicBranch(cmd.getRefName())
@@ -3412,7 +3351,8 @@
}
private Map<Change.Key, ChangeNotes> openChangesByKeyByBranch(BranchNameKey branch) {
- try (TraceTimer traceTimer = newTimer("openChangesByKeyByBranch", "branch", branch.branch())) {
+ try (TraceTimer traceTimer =
+ newTimer("openChangesByKeyByBranch", Metadata.builder().branchName(branch.branch()))) {
Map<Change.Key, ChangeNotes> r = new HashMap<>();
for (ChangeData cd : queryProvider.get().byBranchOpen(branch)) {
try {
@@ -3437,16 +3377,16 @@
}
private TraceTimer newTimer(Class<?> clazz, String name) {
- return TraceContext.newTimer(clazz.getSimpleName() + "#" + name, "projectName", project);
+ return newTimer(clazz, name, Metadata.builder());
}
- private TraceTimer newTimer(String name, String key, @Nullable Object value) {
- return newTimer(getClass(), name, key, value);
+ private TraceTimer newTimer(String name, Metadata.Builder metadataBuilder) {
+ return newTimer(getClass(), name, metadataBuilder);
}
- private TraceTimer newTimer(Class<?> clazz, String name, String key, @Nullable Object value) {
- return TraceContext.newTimer(
- clazz.getSimpleName() + "#" + name, "projectName", project, key, value);
+ private TraceTimer newTimer(Class<?> clazz, String name, Metadata.Builder metadataBuilder) {
+ metadataBuilder.projectName(project.getName());
+ return TraceContext.newTimer(clazz.getSimpleName() + "#" + name, metadataBuilder.build());
}
private static void reject(ReceiveCommand cmd, String why) {
diff --git a/java/com/google/gerrit/server/git/validators/CommitValidators.java b/java/com/google/gerrit/server/git/validators/CommitValidators.java
index a9a1a5d..02a24f7 100644
--- a/java/com/google/gerrit/server/git/validators/CommitValidators.java
+++ b/java/com/google/gerrit/server/git/validators/CommitValidators.java
@@ -146,12 +146,7 @@
new CommitterUploaderValidator(user, perm, urlFormatter.get()),
new SignedOffByValidator(user, perm, projectState),
new ChangeIdValidator(
- projectState,
- user,
- urlFormatter.get(),
- installCommitMsgHookCommand,
- sshInfo,
- change),
+ user, urlFormatter.get(), installCommitMsgHookCommand, sshInfo, change),
new ConfigValidator(projectConfigFactory, branch, user, rw, allUsers, allProjects),
new BannedCommitsValidator(rejectCommits),
new PluginCommitValidationListener(pluginValidators, skipValidation),
@@ -178,12 +173,7 @@
new AuthorUploaderValidator(user, perm, urlFormatter.get()),
new SignedOffByValidator(user, perm, projectCache.checkedGet(branch.project())),
new ChangeIdValidator(
- projectState,
- user,
- urlFormatter.get(),
- installCommitMsgHookCommand,
- sshInfo,
- change),
+ user, urlFormatter.get(), installCommitMsgHookCommand, sshInfo, change),
new ConfigValidator(projectConfigFactory, branch, user, rw, allUsers, allProjects),
new PluginCommitValidationListener(pluginValidators),
new ExternalIdUpdateListener(allUsers, externalIdsConsistencyChecker),
@@ -257,7 +247,6 @@
private static final Pattern CHANGE_ID = Pattern.compile(CHANGE_ID_PATTERN);
- private final ProjectState projectState;
private final UrlFormatter urlFormatter;
private final String installCommitMsgHookCommand;
private final SshInfo sshInfo;
@@ -265,13 +254,11 @@
private final Change change;
public ChangeIdValidator(
- ProjectState projectState,
IdentifiedUser user,
UrlFormatter urlFormatter,
String installCommitMsgHookCommand,
SshInfo sshInfo,
Change change) {
- this.projectState = projectState;
this.urlFormatter = urlFormatter;
this.installCommitMsgHookCommand = installCommitMsgHookCommand;
this.sshInfo = sshInfo;
@@ -307,10 +294,8 @@
Type.ERROR));
throw new CommitValidationException(CHANGE_ID_ABOVE_FOOTER_MSG, messages);
}
- if (projectState.is(BooleanProjectConfig.REQUIRE_CHANGE_ID)) {
- messages.add(getMissingChangeIdErrorMsg(MISSING_CHANGE_ID_MSG));
- throw new CommitValidationException(MISSING_CHANGE_ID_MSG, messages);
- }
+ messages.add(getMissingChangeIdErrorMsg(MISSING_CHANGE_ID_MSG));
+ throw new CommitValidationException(MISSING_CHANGE_ID_MSG, messages);
} else if (idList.size() > 1) {
throw new CommitValidationException(MULTIPLE_CHANGE_ID_MSG, messages);
} else {
diff --git a/java/com/google/gerrit/server/group/db/GroupsUpdate.java b/java/com/google/gerrit/server/group/db/GroupsUpdate.java
index 2f9ce01..ed7eab8 100644
--- a/java/com/google/gerrit/server/group/db/GroupsUpdate.java
+++ b/java/com/google/gerrit/server/group/db/GroupsUpdate.java
@@ -42,6 +42,7 @@
import com.google.gerrit.server.group.GroupAuditService;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.index.group.GroupIndexer;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.gerrit.server.update.RetryHelper;
@@ -266,8 +267,9 @@
try (TraceTimer timer =
TraceContext.newTimer(
"Creating group",
- "groupName",
- groupUpdate.getName().orElseGet(groupCreation::getNameKey))) {
+ Metadata.builder()
+ .groupName(groupUpdate.getName().orElseGet(groupCreation::getNameKey).get())
+ .build())) {
InternalGroup createdGroup = createGroupInNoteDbWithRetry(groupCreation, groupUpdate);
evictCachesOnGroupCreation(createdGroup);
dispatchAuditEventsOnGroupCreation(createdGroup);
@@ -287,7 +289,9 @@
*/
public void updateGroup(AccountGroup.UUID groupUuid, InternalGroupUpdate groupUpdate)
throws DuplicateKeyException, IOException, NoSuchGroupException, ConfigInvalidException {
- try (TraceTimer timer = TraceContext.newTimer("Updating group", "groupUuid", groupUuid)) {
+ try (TraceTimer timer =
+ TraceContext.newTimer(
+ "Updating group", Metadata.builder().groupUuid(groupUuid.get()).build())) {
Optional<Timestamp> updatedOn = groupUpdate.getUpdatedOn();
if (!updatedOn.isPresent()) {
updatedOn = Optional.of(TimeUtil.nowTs());
diff --git a/java/com/google/gerrit/server/group/testing/InternalGroupSubject.java b/java/com/google/gerrit/server/group/testing/InternalGroupSubject.java
index 79bd005..a2f6002 100644
--- a/java/com/google/gerrit/server/group/testing/InternalGroupSubject.java
+++ b/java/com/google/gerrit/server/group/testing/InternalGroupSubject.java
@@ -22,7 +22,10 @@
import com.google.common.truth.IterableSubject;
import com.google.common.truth.StringSubject;
import com.google.common.truth.Subject;
+import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.group.InternalGroup;
+import java.sql.Timestamp;
+import org.eclipse.jgit.lib.ObjectId;
public class InternalGroupSubject extends Subject {
@@ -41,12 +44,12 @@
this.group = group;
}
- public ComparableSubject groupUuid() {
+ public ComparableSubject<AccountGroup.UUID> groupUuid() {
isNotNull();
return check("getGroupUUID()").that(group.getGroupUUID());
}
- public ComparableSubject nameKey() {
+ public ComparableSubject<AccountGroup.NameKey> nameKey() {
isNotNull();
return check("getNameKey()").that(group.getNameKey());
}
@@ -66,7 +69,7 @@
return check("getDescription()").that(group.getDescription());
}
- public ComparableSubject ownerGroupUuid() {
+ public ComparableSubject<AccountGroup.UUID> ownerGroupUuid() {
isNotNull();
return check("getOwnerGroupUUID()").that(group.getOwnerGroupUUID());
}
@@ -76,7 +79,7 @@
return check("isVisibleToAll()").that(group.isVisibleToAll());
}
- public ComparableSubject createdOn() {
+ public ComparableSubject<Timestamp> createdOn() {
isNotNull();
return check("getCreatedOn()").that(group.getCreatedOn());
}
@@ -91,7 +94,7 @@
return check("getSubgroups()").that(group.getSubgroups());
}
- public ComparableSubject refState() {
+ public ComparableSubject<ObjectId> refState() {
isNotNull();
return check("getRefState()").that(group.getRefState());
}
diff --git a/java/com/google/gerrit/server/index/OnlineReindexMode.java b/java/com/google/gerrit/server/index/OnlineReindexMode.java
new file mode 100644
index 0000000..123229a
--- /dev/null
+++ b/java/com/google/gerrit/server/index/OnlineReindexMode.java
@@ -0,0 +1,33 @@
+// Copyright (C) 2019 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.index;
+
+import java.util.Optional;
+
+public class OnlineReindexMode {
+ private static ThreadLocal<Boolean> isOnlineReindex = new ThreadLocal<>();
+
+ public static boolean isActive() {
+ return Optional.ofNullable(isOnlineReindex.get()).orElse(Boolean.FALSE);
+ }
+
+ public static void begin() {
+ isOnlineReindex.set(Boolean.TRUE);
+ }
+
+ public static void end() {
+ isOnlineReindex.set(Boolean.FALSE);
+ }
+}
diff --git a/java/com/google/gerrit/server/index/account/AccountField.java b/java/com/google/gerrit/server/index/account/AccountField.java
index ab3a96d..b881a35 100644
--- a/java/com/google/gerrit/server/index/account/AccountField.java
+++ b/java/com/google/gerrit/server/index/account/AccountField.java
@@ -31,6 +31,8 @@
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.account.externalids.ExternalId;
+import com.google.gerrit.server.config.AllUsersName;
+import com.google.gerrit.server.config.AllUsersNameProvider;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Collections;
@@ -144,7 +146,11 @@
RefState.create(
RefNames.refsUsers(a.getAccount().getId()),
ObjectId.fromString(a.getAccount().getMetaId()))
- .toByteArray(a.getAllUsersNameForIndexing()));
+ // We use the default AllUsers name to avoid having to pass around that
+ // variable just for indexing.
+ // This field is only used for staleness detection which will discover the
+ // default name and replace it with the actually configured name.
+ .toByteArray(new AllUsersName(AllUsersNameProvider.DEFAULT)));
});
/**
diff --git a/java/com/google/gerrit/server/index/account/AccountIndexerImpl.java b/java/com/google/gerrit/server/index/account/AccountIndexerImpl.java
index da22eac..5c2f551 100644
--- a/java/com/google/gerrit/server/index/account/AccountIndexerImpl.java
+++ b/java/com/google/gerrit/server/index/account/AccountIndexerImpl.java
@@ -23,6 +23,7 @@
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountState;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.gerrit.server.plugincontext.PluginSetContext;
@@ -91,20 +92,20 @@
try (TraceTimer traceTimer =
TraceContext.newTimer(
"Replacing account in index",
- "accountId",
- id.get(),
- "indexVersion",
- i.getSchema().getVersion())) {
+ Metadata.builder()
+ .accountId(id.get())
+ .indexVersion(i.getSchema().getVersion())
+ .build())) {
i.replace(accountState.get());
}
} else {
try (TraceTimer traceTimer =
TraceContext.newTimer(
"Deleting account in index",
- "accountId",
- id.get(),
- "indexVersion",
- i.getSchema().getVersion())) {
+ Metadata.builder()
+ .accountId(id.get())
+ .indexVersion(i.getSchema().getVersion())
+ .build())) {
i.delete(id);
}
}
diff --git a/java/com/google/gerrit/server/index/account/StalenessChecker.java b/java/com/google/gerrit/server/index/account/StalenessChecker.java
index 4664700..0423bb9 100644
--- a/java/com/google/gerrit/server/index/account/StalenessChecker.java
+++ b/java/com/google/gerrit/server/index/account/StalenessChecker.java
@@ -32,6 +32,7 @@
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIds;
import com.google.gerrit.server.config.AllUsersName;
+import com.google.gerrit.server.config.AllUsersNameProvider;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.index.IndexUtils;
import com.google.inject.Inject;
@@ -106,7 +107,11 @@
for (Map.Entry<Project.NameKey, RefState> e :
RefState.parseStates(result.get().getValue(AccountField.REF_STATE)).entries()) {
- try (Repository repo = repoManager.openRepository(e.getKey())) {
+ // Custom All-Users repository names are not indexed. Instead, the default name is used.
+ // Therefore, defer to the currently configured All-Users name.
+ Project.NameKey repoName =
+ e.getKey().get().equals(AllUsersNameProvider.DEFAULT) ? allUsersName : e.getKey();
+ try (Repository repo = repoManager.openRepository(repoName)) {
if (!e.getValue().match(repo)) {
// Ref was modified since the account was indexed.
return true;
diff --git a/java/com/google/gerrit/server/index/change/AllChangesIndexer.java b/java/com/google/gerrit/server/index/change/AllChangesIndexer.java
index 3015187..dde7c1f 100644
--- a/java/com/google/gerrit/server/index/change/AllChangesIndexer.java
+++ b/java/com/google/gerrit/server/index/change/AllChangesIndexer.java
@@ -34,6 +34,7 @@
import com.google.gerrit.server.git.MultiProgressMonitor;
import com.google.gerrit.server.git.MultiProgressMonitor.Task;
import com.google.gerrit.server.index.IndexExecutor;
+import com.google.gerrit.server.index.OnlineReindexMode;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeNotes.Factory.ChangeNotesResult;
import com.google.gerrit.server.project.ProjectCache;
@@ -214,6 +215,8 @@
@Override
public Void call() throws Exception {
try (Repository repo = repoManager.openRepository(project)) {
+ OnlineReindexMode.begin();
+
// Order of scanning changes is undefined. This is ok if we assume that packfile locality is
// not important for indexing, since sites should have a fully populated DiffSummary cache.
// It does mean that reindexing after invalidating the DiffSummary cache will be expensive,
@@ -222,6 +225,8 @@
notesFactory.scan(repo, project).forEach(r -> index(r));
} catch (RepositoryNotFoundException rnfe) {
logger.atSevere().log(rnfe.getMessage());
+ } finally {
+ OnlineReindexMode.end();
}
return null;
}
diff --git a/java/com/google/gerrit/server/index/change/ChangeIndexer.java b/java/com/google/gerrit/server/index/change/ChangeIndexer.java
index c2fbb85..87ee27f 100644
--- a/java/com/google/gerrit/server/index/change/ChangeIndexer.java
+++ b/java/com/google/gerrit/server/index/change/ChangeIndexer.java
@@ -28,6 +28,7 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.index.IndexExecutor;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.gerrit.server.plugincontext.PluginSetContext;
@@ -187,10 +188,10 @@
try (TraceTimer traceTimer =
TraceContext.newTimer(
"Replacing change in index",
- "changeId",
- cd.getId().get(),
- "indexVersion",
- i.getSchema().getVersion())) {
+ Metadata.builder()
+ .changeId(cd.getId().get())
+ .indexVersion(i.getSchema().getVersion())
+ .build())) {
i.replace(cd);
}
}
@@ -378,10 +379,10 @@
try (TraceTimer traceTimer =
TraceContext.newTimer(
"Deleting change in index",
- "changeId",
- id.get(),
- "indexVersion",
- i.getSchema().getVersion())) {
+ Metadata.builder()
+ .changeId(id.get())
+ .indexVersion(i.getSchema().getVersion())
+ .build())) {
i.delete(id);
}
}
diff --git a/java/com/google/gerrit/server/index/group/GroupIndexerImpl.java b/java/com/google/gerrit/server/index/group/GroupIndexerImpl.java
index c49a55e..8bcc52c 100644
--- a/java/com/google/gerrit/server/index/group/GroupIndexerImpl.java
+++ b/java/com/google/gerrit/server/index/group/GroupIndexerImpl.java
@@ -23,6 +23,7 @@
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.group.InternalGroup;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.gerrit.server.plugincontext.PluginSetContext;
@@ -91,20 +92,20 @@
try (TraceTimer traceTimer =
TraceContext.newTimer(
"Replacing group",
- "groupUuid",
- uuid.get(),
- "indexVersion",
- i.getSchema().getVersion())) {
+ Metadata.builder()
+ .groupUuid(uuid.get())
+ .indexVersion(i.getSchema().getVersion())
+ .build())) {
i.replace(internalGroup.get());
}
} else {
try (TraceTimer traceTimer =
TraceContext.newTimer(
"Deleting group",
- "groupUuid",
- uuid.get(),
- "indexVersion",
- i.getSchema().getVersion())) {
+ Metadata.builder()
+ .groupUuid(uuid.get())
+ .indexVersion(i.getSchema().getVersion())
+ .build())) {
i.delete(uuid);
}
}
diff --git a/java/com/google/gerrit/server/index/project/ProjectIndexerImpl.java b/java/com/google/gerrit/server/index/project/ProjectIndexerImpl.java
index 5f022f2..199119a 100644
--- a/java/com/google/gerrit/server/index/project/ProjectIndexerImpl.java
+++ b/java/com/google/gerrit/server/index/project/ProjectIndexerImpl.java
@@ -23,6 +23,7 @@
import com.google.gerrit.index.project.ProjectIndexCollection;
import com.google.gerrit.index.project.ProjectIndexer;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.gerrit.server.plugincontext.PluginSetContext;
@@ -79,10 +80,10 @@
try (TraceTimer traceTimer =
TraceContext.newTimer(
"Replacing project",
- "projectName",
- nameKey.get(),
- "indexVersion",
- i.getSchema().getVersion())) {
+ Metadata.builder()
+ .projectName(nameKey.get())
+ .indexVersion(i.getSchema().getVersion())
+ .build())) {
i.replace(projectData);
}
}
@@ -93,10 +94,10 @@
try (TraceTimer traceTimer =
TraceContext.newTimer(
"Deleting project",
- "projectName",
- nameKey.get(),
- "indexVersion",
- i.getSchema().getVersion())) {
+ Metadata.builder()
+ .projectName(nameKey.get())
+ .indexVersion(i.getSchema().getVersion())
+ .build())) {
i.delete(nameKey);
}
}
diff --git a/java/com/google/gerrit/server/logging/Metadata.java b/java/com/google/gerrit/server/logging/Metadata.java
new file mode 100644
index 0000000..400f48f
--- /dev/null
+++ b/java/com/google/gerrit/server/logging/Metadata.java
@@ -0,0 +1,218 @@
+// Copyright (C) 2019 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.logging;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
+import com.google.gerrit.common.Nullable;
+import java.util.Optional;
+
+/** Metadata that is provided to {@link PerformanceLogger}s as context for performance records. */
+@AutoValue
+public abstract class Metadata {
+ // The numeric ID of an account.
+ public abstract Optional<Integer> accountId();
+
+ // The type of an action (ACCOUNT_UPDATE, CHANGE_UPDATE, GROUP_UPDATE, INDEX_QUERY,
+ // PLUGIN_UPDATE).
+ public abstract Optional<String> actionType();
+
+ // An authentication domain name.
+ public abstract Optional<String> authDomainName();
+
+ // The name of a branch.
+ public abstract Optional<String> branchName();
+
+ // Key of an entity in a cache.
+ public abstract Optional<String> cacheKey();
+
+ // The name of a cache.
+ public abstract Optional<String> cacheName();
+
+ // The name of the implementation class.
+ public abstract Optional<String> className();
+
+ // The numeric ID of a change.
+ public abstract Optional<Integer> changeId();
+
+ // The type of change ID which the user used to identify a change (e.g. numeric ID, triplet etc.).
+ public abstract Optional<String> changeIdType();
+
+ // The type of an event.
+ public abstract Optional<String> eventType();
+
+ // The value of the @Export annotation which was used to register a plugin extension.
+ public abstract Optional<String> exportValue();
+
+ // Path of a file in a repository.
+ public abstract Optional<String> filePath();
+
+ // Garbage collector name.
+ public abstract Optional<String> garbageCollectorName();
+
+ // Git operation (CLONE, FETCH).
+ public abstract Optional<String> gitOperation();
+
+ // The numeric ID of an internal group.
+ public abstract Optional<Integer> groupId();
+
+ // The name of a group.
+ public abstract Optional<String> groupName();
+
+ // The UUID of a group.
+ public abstract Optional<String> groupUuid();
+
+ // HTTP status response code.
+ public abstract Optional<Integer> httpStatus();
+
+ // The name of a secondary index.
+ public abstract Optional<String> indexName();
+
+ // The version of a secondary index.
+ public abstract Optional<Integer> indexVersion();
+
+ // The name of the implementation method.
+ public abstract Optional<String> methodName();
+
+ // Boolean: one or more
+ public abstract Optional<Boolean> multiple();
+
+ // Path of a metadata file in NoteDb.
+ public abstract Optional<String> noteDbFilePath();
+
+ // Name of a metadata ref in NoteDb.
+ public abstract Optional<String> noteDbRefName();
+
+ // Type of a sequence in NoteDb (ACCOUNTS, CHANGES, GROUPS).
+ public abstract Optional<String> noteDbSequenceType();
+
+ // Name of a "table" in NoteDb (if set, always CHANGES).
+ public abstract Optional<String> noteDbTable();
+
+ // The ID of a patch set.
+ public abstract Optional<Integer> patchSetId();
+
+ // Plugin metadata that doesn't fit into any other category.
+ public abstract ImmutableList<PluginMetadata> pluginMetadata();
+
+ // The name of a plugin.
+ public abstract Optional<String> pluginName();
+
+ // The name of a Gerrit project (aka Git repository).
+ public abstract Optional<String> projectName();
+
+ // The type of a Git push to Gerrit (CREATE_REPLACE, NORMAL, AUTOCLOSE).
+ public abstract Optional<String> pushType();
+
+ // The number of resources that is processed.
+ public abstract Optional<Integer> resourceCount();
+
+ // The name of a REST view.
+ public abstract Optional<String> restViewName();
+
+ // The SHA1 of Git commit.
+ public abstract Optional<String> revision();
+
+ // The username of an account.
+ public abstract Optional<String> username();
+
+ public static Metadata.Builder builder() {
+ return new AutoValue_Metadata.Builder();
+ }
+
+ public static Metadata empty() {
+ return builder().build();
+ }
+
+ @AutoValue.Builder
+ public abstract static class Builder {
+ public abstract Builder accountId(int accountId);
+
+ public abstract Builder actionType(@Nullable String actionType);
+
+ public abstract Builder authDomainName(@Nullable String authDomainName);
+
+ public abstract Builder branchName(@Nullable String branchName);
+
+ public abstract Builder cacheKey(@Nullable String cacheKey);
+
+ public abstract Builder cacheName(@Nullable String cacheName);
+
+ public abstract Builder className(@Nullable String className);
+
+ public abstract Builder changeId(int changeId);
+
+ public abstract Builder changeIdType(@Nullable String changeIdType);
+
+ public abstract Builder eventType(@Nullable String eventType);
+
+ public abstract Builder exportValue(@Nullable String exportValue);
+
+ public abstract Builder filePath(@Nullable String filePath);
+
+ public abstract Builder garbageCollectorName(@Nullable String garbageCollectorName);
+
+ public abstract Builder gitOperation(@Nullable String gitOperation);
+
+ public abstract Builder groupId(int groupId);
+
+ public abstract Builder groupName(@Nullable String groupName);
+
+ public abstract Builder groupUuid(@Nullable String groupUuid);
+
+ public abstract Builder httpStatus(int httpStatus);
+
+ public abstract Builder indexName(@Nullable String indexName);
+
+ public abstract Builder indexVersion(int indexVersion);
+
+ public abstract Builder methodName(@Nullable String methodName);
+
+ public abstract Builder multiple(boolean multiple);
+
+ public abstract Builder noteDbFilePath(@Nullable String noteDbFilePath);
+
+ public abstract Builder noteDbRefName(@Nullable String noteDbRefName);
+
+ public abstract Builder noteDbSequenceType(@Nullable String noteDbSequenceType);
+
+ public abstract Builder noteDbTable(@Nullable String noteDbTable);
+
+ public abstract Builder patchSetId(int patchSetId);
+
+ abstract ImmutableList.Builder<PluginMetadata> pluginMetadataBuilder();
+
+ public Builder addPluginMetadata(PluginMetadata pluginMetadata) {
+ pluginMetadataBuilder().add(pluginMetadata);
+ return this;
+ }
+
+ public abstract Builder pluginName(@Nullable String pluginName);
+
+ public abstract Builder projectName(@Nullable String projectName);
+
+ public abstract Builder pushType(@Nullable String pushType);
+
+ public abstract Builder resourceCount(int resourceCount);
+
+ public abstract Builder restViewName(@Nullable String restViewName);
+
+ public abstract Builder revision(@Nullable String revision);
+
+ public abstract Builder username(@Nullable String username);
+
+ public abstract Metadata build();
+ }
+}
diff --git a/java/com/google/gerrit/server/logging/PerformanceLogRecord.java b/java/com/google/gerrit/server/logging/PerformanceLogRecord.java
index d30f862..046eeb3 100644
--- a/java/com/google/gerrit/server/logging/PerformanceLogRecord.java
+++ b/java/com/google/gerrit/server/logging/PerformanceLogRecord.java
@@ -14,16 +14,14 @@
package com.google.gerrit.server.logging;
-import static java.util.Objects.requireNonNull;
-
import com.google.auto.value.AutoValue;
-import com.google.gerrit.common.Nullable;
+import java.util.Optional;
/**
* The record of an operation for which the execution time was measured.
*
- * <p>Meta data is stored in separate key/value fields to avoid expensive instantiations of Map
- * objects.
+ * <p>Metadata to provide additional context can be included by providing a {@link Metadata}
+ * instance.
*/
@AutoValue
public abstract class PerformanceLogRecord {
@@ -35,8 +33,7 @@
* @return the performance log record
*/
public static PerformanceLogRecord create(String operation, long durationMs) {
- return new AutoValue_PerformanceLogRecord(
- operation, durationMs, null, null, null, null, null, null, null, null);
+ return new AutoValue_PerformanceLogRecord(operation, durationMs, Optional.empty());
}
/**
@@ -44,175 +41,22 @@
*
* @param operation the name of operation the is was performed
* @param durationMs the execution time in milliseconds
- * @param key meta data key
- * @param value meta data value
+ * @param metadata metadata
* @return the performance log record
*/
- public static PerformanceLogRecord create(
- String operation, long durationMs, String key, @Nullable Object value) {
- return new AutoValue_PerformanceLogRecord(
- operation, durationMs, requireNonNull(key), value, null, null, null, null, null, null);
- }
-
- /**
- * Creates a performance log record with meta data.
- *
- * @param operation the name of operation the is was performed
- * @param durationMs the execution time in milliseconds
- * @param key1 first meta data key
- * @param value1 first meta data value
- * @param key2 second meta data key
- * @param value2 second meta data value
- * @return the performance log record
- */
- public static PerformanceLogRecord create(
- String operation,
- long durationMs,
- String key1,
- @Nullable Object value1,
- String key2,
- @Nullable Object value2) {
- return new AutoValue_PerformanceLogRecord(
- operation,
- durationMs,
- requireNonNull(key1),
- value1,
- requireNonNull(key2),
- value2,
- null,
- null,
- null,
- null);
- }
-
- /**
- * Creates a performance log record with meta data.
- *
- * @param operation the name of operation the is was performed
- * @param durationMs the execution time in milliseconds
- * @param key1 first meta data key
- * @param value1 first meta data value
- * @param key2 second meta data key
- * @param value2 second meta data value
- * @param key3 third meta data key
- * @param value3 third meta data value
- * @return the performance log record
- */
- public static PerformanceLogRecord create(
- String operation,
- long durationMs,
- String key1,
- @Nullable Object value1,
- String key2,
- @Nullable Object value2,
- String key3,
- @Nullable Object value3) {
- return new AutoValue_PerformanceLogRecord(
- operation,
- durationMs,
- requireNonNull(key1),
- value1,
- requireNonNull(key2),
- value2,
- requireNonNull(key3),
- value3,
- null,
- null);
- }
-
- /**
- * Creates a performance log record with meta data.
- *
- * @param operation the name of operation the is was performed
- * @param durationMs the execution time in milliseconds
- * @param key1 first meta data key
- * @param value1 first meta data value
- * @param key2 second meta data key
- * @param value2 second meta data value
- * @param key3 third meta data key
- * @param value3 third meta data value
- * @param key4 forth meta data key
- * @param value4 forth meta data value
- * @return the performance log record
- */
- public static PerformanceLogRecord create(
- String operation,
- long durationMs,
- String key1,
- @Nullable Object value1,
- String key2,
- @Nullable Object value2,
- String key3,
- @Nullable Object value3,
- String key4,
- @Nullable Object value4) {
- return new AutoValue_PerformanceLogRecord(
- operation,
- durationMs,
- requireNonNull(key1),
- value1,
- requireNonNull(key2),
- value2,
- requireNonNull(key3),
- value3,
- requireNonNull(key4),
- value4);
+ public static PerformanceLogRecord create(String operation, long durationMs, Metadata metadata) {
+ return new AutoValue_PerformanceLogRecord(operation, durationMs, Optional.of(metadata));
}
public abstract String operation();
public abstract long durationMs();
- @Nullable
- public abstract String key1();
-
- @Nullable
- public abstract Object value1();
-
- @Nullable
- public abstract String key2();
-
- @Nullable
- public abstract Object value2();
-
- @Nullable
- public abstract String key3();
-
- @Nullable
- public abstract Object value3();
-
- @Nullable
- public abstract String key4();
-
- @Nullable
- public abstract Object value4();
+ public abstract Optional<Metadata> metadata();
void writeTo(PerformanceLogger performanceLogger) {
- if (key4() != null) {
- requireNonNull(key1());
- requireNonNull(key2());
- requireNonNull(key3());
- performanceLogger.log(
- operation(),
- durationMs(),
- key1(),
- value1(),
- key2(),
- value2(),
- key3(),
- value3(),
- key4(),
- value4());
- } else if (key3() != null) {
- requireNonNull(key1());
- requireNonNull(key2());
- performanceLogger.log(
- operation(), durationMs(), key1(), value1(), key2(), value2(), key3(), value3());
- } else if (key2() != null) {
- requireNonNull(key1());
- performanceLogger.log(operation(), durationMs(), key1(), value1(), key2(), value2());
- } else if (key1() != null) {
- performanceLogger.log(operation(), durationMs(), key1(), value1());
+ if (metadata().isPresent()) {
+ performanceLogger.log(operation(), durationMs(), metadata().get());
} else {
performanceLogger.log(operation(), durationMs());
}
diff --git a/java/com/google/gerrit/server/logging/PerformanceLogger.java b/java/com/google/gerrit/server/logging/PerformanceLogger.java
index 3e33a3a..74a1684 100644
--- a/java/com/google/gerrit/server/logging/PerformanceLogger.java
+++ b/java/com/google/gerrit/server/logging/PerformanceLogger.java
@@ -14,11 +14,7 @@
package com.google.gerrit.server.logging;
-import com.google.common.collect.ImmutableMap;
-import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.annotations.ExtensionPoint;
-import java.util.Map;
-import java.util.Optional;
/**
* Extension point for logging performance records.
@@ -29,7 +25,7 @@
* performance log for further analysis.
*
* <p>For optimal performance implementors should overwrite the default <code>log</code> methods to
- * avoid unneeded instantiation of Map objects.
+ * avoid an unneeded instantiation of Metadata.
*/
@ExtensionPoint
public interface PerformanceLogger {
@@ -40,7 +36,7 @@
* @param durationMs time that the execution of the operation took (in milliseconds)
*/
default void log(String operation, long durationMs) {
- log(operation, durationMs, ImmutableMap.of());
+ log(operation, durationMs, Metadata.empty());
}
/**
@@ -48,117 +44,7 @@
*
* @param operation operation that was performed
* @param durationMs time that the execution of the operation took (in milliseconds)
- * @param key meta data key
- * @param value meta data value
+ * @param metadata metadata
*/
- default void log(String operation, long durationMs, String key, @Nullable Object value) {
- log(operation, durationMs, ImmutableMap.of(key, Optional.ofNullable(value)));
- }
-
- /**
- * Record the execution time of an operation in a performance log.
- *
- * @param operation operation that was performed
- * @param durationMs time that the execution of the operation took (in milliseconds)
- * @param key1 first meta data key
- * @param value1 first meta data value
- * @param key2 second meta data key
- * @param value2 second meta data value
- */
- default void log(
- String operation,
- long durationMs,
- String key1,
- @Nullable Object value1,
- String key2,
- @Nullable Object value2) {
- log(
- operation,
- durationMs,
- ImmutableMap.of(key1, Optional.ofNullable(value1), key2, Optional.ofNullable(value2)));
- }
-
- /**
- * Record the execution time of an operation in a performance log.
- *
- * @param operation operation that was performed
- * @param durationMs time that the execution of the operation took (in milliseconds)
- * @param key1 first meta data key
- * @param value1 first meta data value
- * @param key2 second meta data key
- * @param value2 second meta data value
- * @param key3 third meta data key
- * @param value3 third meta data value
- */
- default void log(
- String operation,
- long durationMs,
- String key1,
- @Nullable Object value1,
- String key2,
- @Nullable Object value2,
- String key3,
- @Nullable Object value3) {
- log(
- operation,
- durationMs,
- ImmutableMap.of(
- key1,
- Optional.ofNullable(value1),
- key2,
- Optional.ofNullable(value2),
- key3,
- Optional.ofNullable(value3)));
- }
-
- /**
- * Record the execution time of an operation in a performance log.
- *
- * @param operation operation that was performed
- * @param durationMs time that the execution of the operation took (in milliseconds)
- * @param key1 first meta data key
- * @param value1 first meta data value
- * @param key2 second meta data key
- * @param value2 second meta data value
- * @param key3 third meta data key
- * @param value3 third meta data value
- * @param key4 fourth meta data key
- * @param value4 fourth meta data value
- */
- default void log(
- String operation,
- long durationMs,
- String key1,
- @Nullable Object value1,
- String key2,
- @Nullable Object value2,
- String key3,
- @Nullable Object value3,
- String key4,
- @Nullable Object value4) {
- log(
- operation,
- durationMs,
- ImmutableMap.of(
- key1,
- Optional.ofNullable(value1),
- key2,
- Optional.ofNullable(value2),
- key3,
- Optional.ofNullable(value3),
- key4,
- Optional.ofNullable(value4)));
- }
-
- /**
- * Record the execution time of an operation in a performance log.
- *
- * <p>For small numbers of meta data entries the instantiation of a map should avoided by using
- * one of the <code>log</code> methods that allows to pass in meta data entries directly.
- *
- * @param operation operation that was performed
- * @param durationMs time that the execution of the operation took (in milliseconds)
- * @param metaData key-value map with meta data
- */
- void log(String operation, long durationMs, Map<String, Optional<Object>> metaData);
+ void log(String operation, long durationMs, Metadata metadata);
}
diff --git a/java/com/google/gerrit/server/logging/PluginMetadata.java b/java/com/google/gerrit/server/logging/PluginMetadata.java
new file mode 100644
index 0000000..21f7359
--- /dev/null
+++ b/java/com/google/gerrit/server/logging/PluginMetadata.java
@@ -0,0 +1,39 @@
+// Copyright (C) 2019 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.logging;
+
+import com.google.auto.value.AutoValue;
+import com.google.gerrit.common.Nullable;
+import java.util.Optional;
+
+/**
+ * Key-value pair for custom metadata that is provided by plugins.
+ *
+ * <p>PluginMetadata allows plugins to include custom metadata into the {@link Metadata} instances
+ * that are provided as context for performance tracing.
+ *
+ * <p>Plugins should use PluginMetadata only for metadata kinds that are not known to Gerrit core
+ * (metadata for which {@link Metadata} doesn't have a dedicated field).
+ */
+@AutoValue
+public abstract class PluginMetadata {
+ public static PluginMetadata create(String key, @Nullable String value) {
+ return new AutoValue_PluginMetadata(key, Optional.ofNullable(value));
+ }
+
+ public abstract String key();
+
+ public abstract Optional<String> value();
+}
diff --git a/java/com/google/gerrit/server/logging/TraceContext.java b/java/com/google/gerrit/server/logging/TraceContext.java
index b018da4..06db7b4 100644
--- a/java/com/google/gerrit/server/logging/TraceContext.java
+++ b/java/com/google/gerrit/server/logging/TraceContext.java
@@ -166,105 +166,13 @@
* Opens a new timer that logs the time for an operation if request tracing is enabled.
*
* @param operation the name of operation the is being performed
- * @param key meta data key
- * @param value meta data value
+ * @param metadata metadata
* @return the trace timer
*/
- public static TraceTimer newTimer(String operation, String key, @Nullable Object value) {
+ public static TraceTimer newTimer(String operation, Metadata metadata) {
return new TraceTimer(
requireNonNull(operation, "operation is required"),
- requireNonNull(key, "key is required"),
- value);
- }
-
- /**
- * Opens a new timer that logs the time for an operation if request tracing is enabled.
- *
- * @param operation the name of operation the is being performed
- * @param key1 first meta data key
- * @param value1 first meta data value
- * @param key2 second meta data key
- * @param value2 second meta data value
- * @return the trace timer
- */
- public static TraceTimer newTimer(
- String operation,
- String key1,
- @Nullable Object value1,
- String key2,
- @Nullable Object value2) {
- return new TraceTimer(
- requireNonNull(operation, "operation is required"),
- requireNonNull(key1, "key1 is required"),
- value1,
- requireNonNull(key2, "key2 is required"),
- value2);
- }
-
- /**
- * Opens a new timer that logs the time for an operation if request tracing is enabled.
- *
- * @param operation the name of operation the is being performed
- * @param key1 first meta data key
- * @param value1 first meta data value
- * @param key2 second meta data key
- * @param value2 second meta data value
- * @param key3 third meta data key
- * @param value3 third meta data value
- * @return the trace timer
- */
- public static TraceTimer newTimer(
- String operation,
- String key1,
- @Nullable Object value1,
- String key2,
- @Nullable Object value2,
- String key3,
- @Nullable Object value3) {
- return new TraceTimer(
- requireNonNull(operation, "operation is required"),
- requireNonNull(key1, "key1 is required"),
- value1,
- requireNonNull(key2, "key2 is required"),
- value2,
- requireNonNull(key3, "key3 is required"),
- value3);
- }
-
- /**
- * Opens a new timer that logs the time for an operation if request tracing is enabled.
- *
- * @param operation the name of operation the is being performed
- * @param key1 first meta data key
- * @param value1 first meta data value
- * @param key2 second meta data key
- * @param value2 second meta data value
- * @param key3 third meta data key
- * @param value3 third meta data value
- * @param key4 fourth meta data key
- * @param value4 fourth meta data value
- * @return the trace timer
- */
- public static TraceTimer newTimer(
- String operation,
- String key1,
- @Nullable Object value1,
- String key2,
- @Nullable Object value2,
- String key3,
- @Nullable Object value3,
- String key4,
- @Nullable Object value4) {
- return new TraceTimer(
- requireNonNull(operation, "operation is required"),
- requireNonNull(key1, "key1 is required"),
- value1,
- requireNonNull(key2, "key2 is required"),
- value2,
- requireNonNull(key3, "key3 is required"),
- value3,
- requireNonNull(key4, "key4 is required"),
- value4);
+ requireNonNull(metadata, "metadata is required"));
}
public static class TraceTimer implements AutoCloseable {
@@ -282,76 +190,13 @@
});
}
- private TraceTimer(String operation, String key, @Nullable Object value) {
+ private TraceTimer(String operation, Metadata metadata) {
this(
elapsedMs -> {
LoggingContext.getInstance()
.addPerformanceLogRecord(
- () -> PerformanceLogRecord.create(operation, elapsedMs, key, value));
- logger.atFine().log("%s (%s=%s) (%d ms)", operation, key, value, elapsedMs);
- });
- }
-
- private TraceTimer(
- String operation,
- String key1,
- @Nullable Object value1,
- String key2,
- @Nullable Object value2) {
- this(
- elapsedMs -> {
- LoggingContext.getInstance()
- .addPerformanceLogRecord(
- () ->
- PerformanceLogRecord.create(
- operation, elapsedMs, key1, value1, key2, value2));
- logger.atFine().log(
- "%s (%s=%s, %s=%s) (%d ms)", operation, key1, value1, key2, value2, elapsedMs);
- });
- }
-
- private TraceTimer(
- String operation,
- String key1,
- @Nullable Object value1,
- String key2,
- @Nullable Object value2,
- String key3,
- @Nullable Object value3) {
- this(
- elapsedMs -> {
- LoggingContext.getInstance()
- .addPerformanceLogRecord(
- () ->
- PerformanceLogRecord.create(
- operation, elapsedMs, key1, value1, key2, value2, key3, value3));
- logger.atFine().log(
- "%s (%s=%s, %s=%s, %s=%s) (%d ms)",
- operation, key1, value1, key2, value2, key3, value3, elapsedMs);
- });
- }
-
- private TraceTimer(
- String operation,
- String key1,
- @Nullable Object value1,
- String key2,
- @Nullable Object value2,
- String key3,
- @Nullable Object value3,
- String key4,
- @Nullable Object value4) {
- this(
- elapsedMs -> {
- LoggingContext.getInstance()
- .addPerformanceLogRecord(
- () ->
- PerformanceLogRecord.create(
- operation, elapsedMs, key1, value1, key2, value2, key3, value3, key4,
- value4));
- logger.atFine().log(
- "%s (%s=%s, %s=%s, %s=%s, %s=%s) (%d ms)",
- operation, key1, value1, key2, value2, key3, value3, key4, value4, elapsedMs);
+ () -> PerformanceLogRecord.create(operation, elapsedMs, metadata));
+ logger.atFine().log("%s (%s) (%d ms)", operation, metadata, elapsedMs);
});
}
@@ -398,6 +243,15 @@
return this;
}
+ public boolean isTracing() {
+ return LoggingContext.getInstance().isLoggingForced();
+ }
+
+ public Optional<String> getTraceId() {
+ return LoggingContext.getInstance().getTagsAsMap().get(RequestId.Type.TRACE_ID.name()).stream()
+ .findFirst();
+ }
+
@Override
public void close() {
for (Table.Cell<String, String, Boolean> cell : tags.cellSet()) {
diff --git a/java/com/google/gerrit/server/mail/send/CommentSender.java b/java/com/google/gerrit/server/mail/send/CommentSender.java
index f8c29b3..4f6a341 100644
--- a/java/com/google/gerrit/server/mail/send/CommentSender.java
+++ b/java/com/google/gerrit/server/mail/send/CommentSender.java
@@ -17,7 +17,6 @@
import static java.util.stream.Collectors.toList;
import com.google.common.base.Strings;
-import com.google.common.collect.Ordering;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.data.FilenameComparator;
import com.google.gerrit.exceptions.EmailException;
@@ -55,7 +54,6 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import java.util.Set;
import org.apache.james.mime4j.dom.field.FieldName;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Repository;
@@ -128,14 +126,6 @@
public void setComments(List<Comment> comments) {
inlineComments = comments;
-
- Set<String> paths = new HashSet<>();
- for (Comment c : comments) {
- if (!Patch.isMagic(c.key.filename)) {
- paths.add(c.key.filename);
- }
- }
- changeData.setCurrentFilePaths(Ordering.natural().sortedCopy(paths));
}
public void setPatchSetComment(String comment) {
@@ -534,7 +524,8 @@
} catch (IndexOutOfBoundsException err) {
// Default to the empty string if the given line number does not appear
// in the file.
- logger.atFine().withCause(err).log("Failed to get line number of file on side %d", side);
+ logger.atFine().withCause(err).log(
+ "Failed to get line number %d of file on side %d", lineNbr, side);
return "";
} catch (NoSuchEntityException err) {
// Default to the empty string if the side cannot be found.
diff --git a/java/com/google/gerrit/server/mail/send/OutgoingEmail.java b/java/com/google/gerrit/server/mail/send/OutgoingEmail.java
index 4313473..e56a38f 100644
--- a/java/com/google/gerrit/server/mail/send/OutgoingEmail.java
+++ b/java/com/google/gerrit/server/mail/send/OutgoingEmail.java
@@ -34,7 +34,7 @@
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.validators.OutgoingEmailValidationListener;
import com.google.gerrit.server.validators.ValidationException;
-import com.google.template.soy.data.SanitizedContent;
+import com.google.template.soy.jbcsrc.api.SoySauce;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
@@ -54,6 +54,7 @@
/** Sends an email to one or more interested parties. */
public abstract class OutgoingEmail {
+ private static final String SOY_TEMPLATE_NAMESPACE = "com.google.gerrit.server.mail.template.";
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
protected String messageClass;
@@ -536,21 +537,19 @@
return args.instanceNameProvider.get();
}
- private String soyTemplate(String name, SanitizedContent.ContentKind kind) {
- return args.soySauce
- .renderTemplate("com.google.gerrit.server.mail.template." + name)
- .setExpectedContentKind(kind)
- .setData(soyContext)
- .render()
- .get();
- }
-
+ /** Renders a soy template of kind="text". */
protected String textTemplate(String name) {
- return soyTemplate(name, SanitizedContent.ContentKind.TEXT);
+ return configureRenderer(name).renderText().get();
}
+ /** Renders a soy template of kind="html". */
protected String soyHtmlTemplate(String name) {
- return soyTemplate(name, SanitizedContent.ContentKind.HTML);
+ return configureRenderer(name).renderHtml().get().toString();
+ }
+
+ /** Configures a soy renderer for the given template name and rendering data map. */
+ private SoySauce.Renderer configureRenderer(String templateName) {
+ return args.soySauce.renderTemplate(SOY_TEMPLATE_NAMESPACE + templateName).setData(soyContext);
}
protected void removeUser(Account user) {
diff --git a/java/com/google/gerrit/server/mail/send/ProjectWatch.java b/java/com/google/gerrit/server/mail/send/ProjectWatch.java
index fd006c2..eb3b831 100644
--- a/java/com/google/gerrit/server/mail/send/ProjectWatch.java
+++ b/java/com/google/gerrit/server/mail/send/ProjectWatch.java
@@ -97,9 +97,9 @@
for (NotifyConfig nc : state.getConfig().getNotifyConfigs()) {
if (nc.isNotify(type)) {
try {
- add(matching, nc);
+ add(matching, state.getNameKey(), nc);
} catch (QueryParseException e) {
- logger.atWarning().log(
+ logger.atInfo().log(
"Project %s has invalid notify %s filter \"%s\": %s",
state.getName(), nc.getName(), nc.getFilter(), e.getMessage());
}
@@ -146,17 +146,27 @@
}
}
- private void add(Watchers matching, NotifyConfig nc) throws QueryParseException {
- for (GroupReference ref : nc.getGroups()) {
- CurrentUser user = new SingleGroupUser(ref.getUUID());
+ private void add(Watchers matching, Project.NameKey projectName, NotifyConfig nc)
+ throws QueryParseException {
+ logger.atFine().log("Checking watchers for notify config %s from project %s", nc, projectName);
+ for (GroupReference groupRef : nc.getGroups()) {
+ CurrentUser user = new SingleGroupUser(groupRef.getUUID());
if (filterMatch(user, nc.getFilter())) {
- deliverToMembers(matching.list(nc.getHeader()), ref.getUUID());
+ deliverToMembers(matching.list(nc.getHeader()), groupRef.getUUID());
+ logger.atFine().log("Added watchers for group %s", groupRef);
+ } else {
+ logger.atFine().log("The filter did not match for group %s; skip notification", groupRef);
}
}
if (!nc.getAddresses().isEmpty()) {
if (filterMatch(null, nc.getFilter())) {
matching.list(nc.getHeader()).emails.addAll(nc.getAddresses());
+ logger.atFine().log("Added watchers for these addresses: %s", nc.getAddresses());
+ } else {
+ logger.atFine().log(
+ "The filter did not match; skip notification for these addresses: %s",
+ nc.getAddresses());
}
}
}
@@ -172,19 +182,24 @@
AccountGroup.UUID uuid = q.remove(q.size() - 1);
GroupDescription.Basic group = args.groupBackend.get(uuid);
if (group == null) {
+ logger.atFine().log("group %s not found, skip notification", uuid);
continue;
}
if (!Strings.isNullOrEmpty(group.getEmailAddress())) {
// If the group has an email address, do not expand membership.
matching.emails.add(new Address(group.getEmailAddress()));
+ logger.atFine().log(
+ "notify group email address %s; skip expanding to members", group.getEmailAddress());
continue;
}
if (!(group instanceof GroupDescription.Internal)) {
// Non-internal groups cannot be expanded by the server.
+ logger.atFine().log("group %s is not an internal group, skip notification", uuid);
continue;
}
+ logger.atFine().log("adding the members of group %s as watchers", uuid);
GroupDescription.Internal ig = (GroupDescription.Internal) group;
matching.accounts.addAll(ig.getMembers());
for (AccountGroup.UUID m : ig.getSubgroups()) {
@@ -201,8 +216,9 @@
ProjectWatchKey key,
Set<NotifyType> watchedTypes,
NotifyType type) {
- IdentifiedUser user = args.identifiedUserFactory.create(accountId);
+ logger.atFine().log("Checking project watch %s of account %s", key, accountId);
+ IdentifiedUser user = args.identifiedUserFactory.create(accountId);
try {
if (filterMatch(user, key.filter())) {
// If we are set to notify on this type, add the user.
@@ -210,10 +226,14 @@
if (watchedTypes.contains(type)) {
matching.bcc.accounts.add(accountId);
}
+ logger.atFine().log("Added account %s as watcher", accountId);
return true;
}
+ logger.atFine().log("The filter did not match for account %s; skip notification", accountId);
} catch (QueryParseException e) {
// Ignore broken filter expressions.
+ logger.atInfo().log(
+ "Account %s has invalid filter in project watch %s: %s", accountId, key, e.getMessage());
}
return false;
}
diff --git a/java/com/google/gerrit/server/notedb/NoteDbMetrics.java b/java/com/google/gerrit/server/notedb/NoteDbMetrics.java
index 7df4c3d..18ffd17 100644
--- a/java/com/google/gerrit/server/notedb/NoteDbMetrics.java
+++ b/java/com/google/gerrit/server/notedb/NoteDbMetrics.java
@@ -19,6 +19,7 @@
import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.metrics.Timer1;
+import com.google.gerrit.server.logging.Metadata;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -45,7 +46,8 @@
@Inject
NoteDbMetrics(MetricMaker metrics) {
- Field<NoteDbTable> tableField = Field.ofEnum(NoteDbTable.class, "table").build();
+ Field<NoteDbTable> tableField =
+ Field.ofEnum(NoteDbTable.class, "table", Metadata.Builder::noteDbTable).build();
updateLatency =
metrics.newTimer(
diff --git a/java/com/google/gerrit/server/notedb/Sequences.java b/java/com/google/gerrit/server/notedb/Sequences.java
index c989af4..73cc600 100644
--- a/java/com/google/gerrit/server/notedb/Sequences.java
+++ b/java/com/google/gerrit/server/notedb/Sequences.java
@@ -25,6 +25,7 @@
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.logging.Metadata;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.eclipse.jgit.lib.Config;
@@ -95,8 +96,9 @@
new Description("Latency of requesting IDs from repo sequences")
.setCumulative()
.setUnit(Units.MILLISECONDS),
- Field.ofEnum(SequenceType.class, "sequence").build(),
- Field.ofBoolean("multiple").build());
+ Field.ofEnum(SequenceType.class, "sequence", Metadata.Builder::noteDbSequenceType)
+ .build(),
+ Field.ofBoolean("multiple", Metadata.Builder::multiple).build());
}
public int nextAccountId() {
diff --git a/java/com/google/gerrit/server/patch/PatchFile.java b/java/com/google/gerrit/server/patch/PatchFile.java
index ec02485..80f9ba0 100644
--- a/java/com/google/gerrit/server/patch/PatchFile.java
+++ b/java/com/google/gerrit/server/patch/PatchFile.java
@@ -96,6 +96,14 @@
}
}
+ private String getOldName() {
+ String name = entry.getOldName();
+ if (name != null) {
+ return name;
+ }
+ return entry.getNewName();
+ }
+
/**
* Extract a line from the file, as a string.
*
@@ -109,7 +117,7 @@
switch (file) {
case 0:
if (a == null) {
- a = load(aTree, entry.getOldName());
+ a = load(aTree, getOldName());
}
return a.getString(line - 1);
@@ -124,33 +132,6 @@
}
}
- /**
- * Return number of lines in file.
- *
- * @param file the file index to extract.
- * @return number of lines in file.
- * @throws IOException the patch or complete file content cannot be read.
- * @throws NoSuchEntityException the file is not exist.
- */
- public int getLineCount(int file) throws IOException, NoSuchEntityException {
- switch (file) {
- case 0:
- if (a == null) {
- a = load(aTree, entry.getOldName());
- }
- return a.size();
-
- case 1:
- if (b == null) {
- b = load(bTree, entry.getNewName());
- }
- return b.size();
-
- default:
- throw new NoSuchEntityException();
- }
- }
-
private Text load(ObjectId tree, String path)
throws MissingObjectException, IncorrectObjectTypeException, CorruptObjectException,
IOException {
diff --git a/java/com/google/gerrit/server/permissions/DefaultRefFilter.java b/java/com/google/gerrit/server/permissions/DefaultRefFilter.java
index 5c17be8..858edf2 100644
--- a/java/com/google/gerrit/server/permissions/DefaultRefFilter.java
+++ b/java/com/google/gerrit/server/permissions/DefaultRefFilter.java
@@ -208,7 +208,7 @@
logger.atFinest().log("Filter refs (refs = %s)", refs);
if (projectState.isAllUsers()) {
- refs = addUsersSelfSymref(refs);
+ refs = addUsersSelfSymref(repo, refs);
}
// TODO(hiesel): Remove when optimization is done.
@@ -397,19 +397,24 @@
return refs;
}
- private Map<String, Ref> addUsersSelfSymref(Map<String, Ref> refs) {
+ private Map<String, Ref> addUsersSelfSymref(Repository repo, Map<String, Ref> refs)
+ throws PermissionBackendException {
if (user.isIdentifiedUser()) {
String refName = RefNames.refsUsers(user.getAccountId());
- Ref r = refs.get(refName);
- if (r == null) {
- logger.atWarning().log("User ref %s not found", refName);
- return refs;
- }
+ try {
+ Ref r = repo.exactRef(refName);
+ if (r == null) {
+ logger.atWarning().log("User ref %s not found", refName);
+ return refs;
+ }
- SymbolicRef s = new SymbolicRef(REFS_USERS_SELF, r);
- refs = new HashMap<>(refs);
- refs.put(s.getName(), s);
- logger.atFinest().log("Added %s as alias for user ref %s", REFS_USERS_SELF, refName);
+ SymbolicRef s = new SymbolicRef(REFS_USERS_SELF, r);
+ refs = new HashMap<>(refs);
+ refs.put(s.getName(), s);
+ logger.atFinest().log("Added %s as alias for user ref %s", REFS_USERS_SELF, refName);
+ } catch (IOException e) {
+ throw new PermissionBackendException(e);
+ }
}
return refs;
}
diff --git a/java/com/google/gerrit/server/plugincontext/PluginContext.java b/java/com/google/gerrit/server/plugincontext/PluginContext.java
index bb51a03..266eb92 100644
--- a/java/com/google/gerrit/server/plugincontext/PluginContext.java
+++ b/java/com/google/gerrit/server/plugincontext/PluginContext.java
@@ -30,6 +30,7 @@
import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.metrics.Timer3;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -118,9 +119,12 @@
@Inject
PluginMetrics(MetricMaker metricMaker) {
- Field<String> pluginNameField = Field.ofString("plugin_name").build();
- Field<String> classNameField = Field.ofString("class_name").build();
- Field<String> exportNameField = Field.ofString("export_name").build();
+ Field<String> pluginNameField =
+ Field.ofString("plugin_name", Metadata.Builder::pluginName).build();
+ Field<String> classNameField =
+ Field.ofString("class_name", Metadata.Builder::className).build();
+ Field<String> exportValueField =
+ Field.ofString("export_value", Metadata.Builder::exportValue).build();
this.latency =
metricMaker.newTimer(
@@ -130,14 +134,14 @@
.setUnit(Units.MILLISECONDS),
pluginNameField,
classNameField,
- exportNameField);
+ exportValueField);
this.errorCount =
metricMaker.newCounter(
"plugin/error_count",
new Description("Number of plugin errors").setCumulative().setUnit("errors"),
pluginNameField,
classNameField,
- exportNameField);
+ exportValueField);
}
Timer3.Context<String, String, String> startLatency(Extension<?> extension) {
diff --git a/java/com/google/gerrit/server/project/BooleanProjectConfigTransformations.java b/java/com/google/gerrit/server/project/BooleanProjectConfigTransformations.java
index 79eccbb..1328f6b 100644
--- a/java/com/google/gerrit/server/project/BooleanProjectConfigTransformations.java
+++ b/java/com/google/gerrit/server/project/BooleanProjectConfigTransformations.java
@@ -39,9 +39,6 @@
BooleanProjectConfig.USE_CONTENT_MERGE,
new Mapper(i -> i.useContentMerge, (i, v) -> i.useContentMerge = v))
.put(
- BooleanProjectConfig.REQUIRE_CHANGE_ID,
- new Mapper(i -> i.requireChangeId, (i, v) -> i.requireChangeId = v))
- .put(
BooleanProjectConfig.CREATE_NEW_CHANGE_FOR_ALL_NOT_IN_TARGET,
new Mapper(
i -> i.createNewChangeForAllNotInTarget,
diff --git a/java/com/google/gerrit/server/project/CreateProjectArgs.java b/java/com/google/gerrit/server/project/CreateProjectArgs.java
index 7405df1..9ae3b2c 100644
--- a/java/com/google/gerrit/server/project/CreateProjectArgs.java
+++ b/java/com/google/gerrit/server/project/CreateProjectArgs.java
@@ -33,7 +33,6 @@
public List<String> branch;
public InheritableBoolean contentMerge;
public InheritableBoolean newChangeForAllNotInTarget;
- public InheritableBoolean changeIdRequired;
public InheritableBoolean rejectEmptyCommit;
public InheritableBoolean enableSignedPush;
public InheritableBoolean requireSignedPush;
@@ -44,7 +43,6 @@
contributorAgreements = InheritableBoolean.INHERIT;
signedOffBy = InheritableBoolean.INHERIT;
contentMerge = InheritableBoolean.INHERIT;
- changeIdRequired = InheritableBoolean.INHERIT;
newChangeForAllNotInTarget = InheritableBoolean.INHERIT;
enableSignedPush = InheritableBoolean.INHERIT;
requireSignedPush = InheritableBoolean.INHERIT;
diff --git a/java/com/google/gerrit/server/project/ProjectCacheImpl.java b/java/com/google/gerrit/server/project/ProjectCacheImpl.java
index 3fc634d..0bfd36d 100644
--- a/java/com/google/gerrit/server/project/ProjectCacheImpl.java
+++ b/java/com/google/gerrit/server/project/ProjectCacheImpl.java
@@ -36,6 +36,7 @@
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.inject.Inject;
@@ -294,7 +295,8 @@
@Override
public ProjectState load(String projectName) throws Exception {
try (TraceTimer timer =
- TraceContext.newTimer("Loading project", "projectName", projectName)) {
+ TraceContext.newTimer(
+ "Loading project", Metadata.builder().projectName(projectName).build())) {
long now = clock.read();
Project.NameKey key = Project.nameKey(projectName);
try (Repository git = mgr.openRepository(key)) {
diff --git a/java/com/google/gerrit/server/project/ProjectCreator.java b/java/com/google/gerrit/server/project/ProjectCreator.java
index b50b046..d468b44 100644
--- a/java/com/google/gerrit/server/project/ProjectCreator.java
+++ b/java/com/google/gerrit/server/project/ProjectCreator.java
@@ -152,7 +152,6 @@
newProject.setBooleanConfig(
BooleanProjectConfig.CREATE_NEW_CHANGE_FOR_ALL_NOT_IN_TARGET,
args.newChangeForAllNotInTarget);
- newProject.setBooleanConfig(BooleanProjectConfig.REQUIRE_CHANGE_ID, args.changeIdRequired);
newProject.setBooleanConfig(BooleanProjectConfig.REJECT_EMPTY_COMMIT, args.rejectEmptyCommit);
newProject.setMaxObjectSizeLimit(args.maxObjectSizeLimit);
newProject.setBooleanConfig(BooleanProjectConfig.ENABLE_SIGNED_PUSH, args.enableSignedPush);
diff --git a/java/com/google/gerrit/server/project/ProjectState.java b/java/com/google/gerrit/server/project/ProjectState.java
index 782ae84..a43047f 100644
--- a/java/com/google/gerrit/server/project/ProjectState.java
+++ b/java/com/google/gerrit/server/project/ProjectState.java
@@ -48,6 +48,7 @@
import com.google.gerrit.server.git.BranchOrderSection;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.TransferConfig;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@@ -135,7 +136,7 @@
new Description("Latency for access computations in ProjectState")
.setCumulative()
.setUnit(Units.NANOSECONDS),
- Field.ofString("method").build());
+ Field.ofString("method", Metadata.Builder::methodName).build());
if (isAllProjects && !Permission.canBeOnAllProjects(AccessSection.ALL, Permission.OWNER)) {
localOwners = Collections.emptySet();
diff --git a/java/com/google/gerrit/server/project/SubmitRuleEvaluator.java b/java/com/google/gerrit/server/project/SubmitRuleEvaluator.java
index 85d91e7..1b1869c 100644
--- a/java/com/google/gerrit/server/project/SubmitRuleEvaluator.java
+++ b/java/com/google/gerrit/server/project/SubmitRuleEvaluator.java
@@ -20,6 +20,7 @@
import com.google.gerrit.common.data.SubmitTypeRecord;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.server.index.OnlineReindexMode;
import com.google.gerrit.server.plugincontext.PluginSetContext;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.rules.PrologRule;
@@ -102,7 +103,7 @@
return ruleError("Error looking up change " + cd.getId(), e);
}
- if (!opts.allowClosed() && change.isClosed()) {
+ if ((!opts.allowClosed() || OnlineReindexMode.isActive()) && change.isClosed()) {
SubmitRecord rec = new SubmitRecord();
rec.status = SubmitRecord.Status.CLOSED;
return Collections.singletonList(rec);
diff --git a/java/com/google/gerrit/server/query/change/ChangeData.java b/java/com/google/gerrit/server/query/change/ChangeData.java
index 0352b83..59cbf32 100644
--- a/java/com/google/gerrit/server/query/change/ChangeData.java
+++ b/java/com/google/gerrit/server/query/change/ChangeData.java
@@ -19,6 +19,7 @@
import static java.util.stream.Collectors.toMap;
import com.google.auto.value.AutoValue;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
@@ -364,6 +365,7 @@
return allUsersName;
}
+ @VisibleForTesting
public void setCurrentFilePaths(List<String> filePaths) {
PatchSet ps = currentPatchSet();
if (ps != null) {
diff --git a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index 3c43cb8..db91bb2 100644
--- a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -24,8 +24,6 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Enums;
import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.primitives.Ints;
import com.google.gerrit.common.data.GroupDescription;
@@ -1332,7 +1330,7 @@
int maxTerms = args.indexConfig.maxTerms();
if (allMembers.size() > maxTerms) {
// limit the number of query terms otherwise Gerrit will barf
- accounts = ImmutableSet.copyOf(Iterables.limit(allMembers, maxTerms));
+ accounts = allMembers.stream().limit(maxTerms).collect(toSet());
} else {
accounts = allMembers;
}
diff --git a/java/com/google/gerrit/server/restapi/account/GetCapabilities.java b/java/com/google/gerrit/server/restapi/account/GetCapabilities.java
index 77f1668..9e2f1cf 100644
--- a/java/com/google/gerrit/server/restapi/account/GetCapabilities.java
+++ b/java/com/google/gerrit/server/restapi/account/GetCapabilities.java
@@ -30,7 +30,6 @@
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestReadView;
-import com.google.gerrit.json.OutputFormat;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.OptionUtil;
import com.google.gerrit.server.account.AccountLimits;
@@ -40,7 +39,6 @@
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gson.reflect.TypeToken;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@@ -79,7 +77,7 @@
}
@Override
- public Object apply(AccountResource resource)
+ public Map<String, Object> apply(AccountResource resource)
throws RestApiException, PermissionBackendException {
permissionBackend.checkUsesDefaultCapabilities();
PermissionBackend.WithUser perm = permissionBackend.currentUser();
@@ -97,9 +95,7 @@
addRanges(have, limits);
addPriority(have, limits);
- return OutputFormat.JSON
- .newGson()
- .toJsonTree(have, new TypeToken<Map<String, Object>>() {}.getType());
+ return have;
}
private Set<GlobalOrPluginPermission> permissionsToTest() {
diff --git a/java/com/google/gerrit/server/restapi/account/PutUsername.java b/java/com/google/gerrit/server/restapi/account/PutUsername.java
index bc1ffc8..76a641d 100644
--- a/java/com/google/gerrit/server/restapi/account/PutUsername.java
+++ b/java/com/google/gerrit/server/restapi/account/PutUsername.java
@@ -20,9 +20,10 @@
import com.google.gerrit.exceptions.DuplicateKeyException;
import com.google.gerrit.extensions.api.accounts.UsernameInput;
import com.google.gerrit.extensions.client.AccountFieldName;
-import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.reviewdb.client.Account;
@@ -71,9 +72,7 @@
@Override
public String apply(AccountResource rsrc, UsernameInput input)
- throws AuthException, MethodNotAllowedException, UnprocessableEntityException,
- ResourceConflictException, IOException, ConfigInvalidException,
- PermissionBackendException {
+ throws RestApiException, IOException, ConfigInvalidException, PermissionBackendException {
if (!self.get().hasSameAccountId(rsrc.getUser())) {
permissionBackend.currentUser().check(GlobalPermission.ADMINISTRATE_SERVER);
}
@@ -82,17 +81,13 @@
throw new MethodNotAllowedException("realm does not allow editing username");
}
- if (input == null) {
- input = new UsernameInput();
- }
-
Account.Id accountId = rsrc.getUser().getAccountId();
if (!externalIds.byAccount(accountId, SCHEME_USERNAME).isEmpty()) {
throw new MethodNotAllowedException("Username cannot be changed.");
}
- if (Strings.isNullOrEmpty(input.username)) {
- return input.username;
+ if (input == null || Strings.isNullOrEmpty(input.username)) {
+ throw new BadRequestException("input required");
}
if (!ExternalId.isValidUsername(input.username)) {
diff --git a/java/com/google/gerrit/server/restapi/change/PostReview.java b/java/com/google/gerrit/server/restapi/change/PostReview.java
index b8ea310..86d8ed6 100644
--- a/java/com/google/gerrit/server/restapi/change/PostReview.java
+++ b/java/com/google/gerrit/server/restapi/change/PostReview.java
@@ -65,7 +65,6 @@
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.extensions.validators.CommentForValidation;
-import com.google.gerrit.extensions.validators.CommentForValidation.CommentType;
import com.google.gerrit.extensions.validators.CommentValidationFailure;
import com.google.gerrit.extensions.validators.CommentValidator;
import com.google.gerrit.json.OutputFormat;
@@ -992,7 +991,7 @@
CommentForValidation.create(
comment.lineNbr > 0
? CommentForValidation.CommentType.INLINE_COMMENT
- : CommentType.FILE_COMMENT,
+ : CommentForValidation.CommentType.FILE_COMMENT,
comment.message))
.collect(toImmutableList());
ImmutableList<CommentValidationFailure> draftValidationFailures =
diff --git a/java/com/google/gerrit/server/restapi/change/PutMessage.java b/java/com/google/gerrit/server/restapi/change/PutMessage.java
index db02418..5c36e60 100644
--- a/java/com/google/gerrit/server/restapi/change/PutMessage.java
+++ b/java/com/google/gerrit/server/restapi/change/PutMessage.java
@@ -22,7 +22,6 @@
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.reviewdb.client.BooleanProjectConfig;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.CurrentUser;
@@ -111,10 +110,7 @@
String sanitizedCommitMessage = CommitMessageUtil.checkAndSanitizeCommitMessage(input.message);
ensureCanEditCommitMessage(resource.getNotes());
- ensureChangeIdIsCorrect(
- projectCache.checkedGet(resource.getProject()).is(BooleanProjectConfig.REQUIRE_CHANGE_ID),
- resource.getChange().getKey().get(),
- sanitizedCommitMessage);
+ ensureChangeIdIsCorrect(resource.getChange().getKey().get(), sanitizedCommitMessage);
try (Repository repository = repositoryManager.openRepository(resource.getProject());
RevWalk revWalk = new RevWalk(repository);
@@ -193,8 +189,7 @@
}
}
- private static void ensureChangeIdIsCorrect(
- boolean requireChangeId, String currentChangeId, String newCommitMessage)
+ private static void ensureChangeIdIsCorrect(String currentChangeId, String newCommitMessage)
throws ResourceConflictException, BadRequestException {
RevCommit revCommit =
RevCommit.parse(
@@ -204,7 +199,7 @@
CommitMessageUtil.checkAndSanitizeCommitMessage(revCommit.getShortMessage());
List<String> changeIdFooters = revCommit.getFooterLines(FooterConstants.CHANGE_ID);
- if (requireChangeId && changeIdFooters.isEmpty()) {
+ if (changeIdFooters.isEmpty()) {
throw new ResourceConflictException("missing Change-Id footer");
}
if (!changeIdFooters.isEmpty() && !changeIdFooters.get(0).equals(currentChangeId)) {
diff --git a/java/com/google/gerrit/server/restapi/change/ReviewersUtil.java b/java/com/google/gerrit/server/restapi/change/ReviewersUtil.java
index 248dc6e..d8a6fe8 100644
--- a/java/com/google/gerrit/server/restapi/change/ReviewersUtil.java
+++ b/java/com/google/gerrit/server/restapi/change/ReviewersUtil.java
@@ -20,8 +20,6 @@
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
@@ -357,10 +355,9 @@
private List<GroupReference> suggestAccountGroups(
SuggestReviewers suggestReviewers, ProjectState projectState) {
- return Lists.newArrayList(
- Iterables.limit(
- groupBackend.suggest(suggestReviewers.getQuery(), projectState),
- suggestReviewers.getLimit()));
+ return groupBackend.suggest(suggestReviewers.getQuery(), projectState).stream()
+ .limit(suggestReviewers.getLimit())
+ .collect(toList());
}
private static class GroupAsReviewer {
diff --git a/java/com/google/gerrit/server/restapi/config/GetServerInfo.java b/java/com/google/gerrit/server/restapi/config/GetServerInfo.java
index 43bfa81..2493cd9 100644
--- a/java/com/google/gerrit/server/restapi/config/GetServerInfo.java
+++ b/java/com/google/gerrit/server/restapi/config/GetServerInfo.java
@@ -293,7 +293,6 @@
info.allProjects = allProjectsName.get();
info.allUsers = allUsersName.get();
info.reportBugUrl = config.getString("gerrit", null, "reportBugUrl");
- info.reportBugText = config.getString("gerrit", null, "reportBugText");
info.docUrl = getDocUrl();
info.docSearch = docSearcher.isAvailable();
info.editGpgKeys =
diff --git a/java/com/google/gerrit/server/restapi/group/ListGroups.java b/java/com/google/gerrit/server/restapi/group/ListGroups.java
index 9f2a7b7..38b525b 100644
--- a/java/com/google/gerrit/server/restapi/group/ListGroups.java
+++ b/java/com/google/gerrit/server/restapi/group/ListGroups.java
@@ -15,10 +15,10 @@
package com.google.gerrit.server.restapi.group;
import static com.google.common.collect.ImmutableList.toImmutableList;
+import static java.util.stream.Collectors.toList;
import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Streams;
import com.google.gerrit.common.data.GroupDescription;
@@ -320,10 +320,9 @@
"You should only have no more than one --project and -n with --suggest");
}
List<GroupReference> groupRefs =
- Lists.newArrayList(
- Iterables.limit(
- groupBackend.suggest(suggest, projects.stream().findFirst().orElse(null)),
- limit <= 0 ? 10 : Math.min(limit, 10)));
+ groupBackend.suggest(suggest, projects.stream().findFirst().orElse(null)).stream()
+ .limit(limit <= 0 ? 10 : Math.min(limit, 10))
+ .collect(toList());
List<GroupInfo> groupInfos = Lists.newArrayListWithCapacity(groupRefs.size());
for (GroupReference ref : groupRefs) {
diff --git a/java/com/google/gerrit/server/restapi/project/CreateProject.java b/java/com/google/gerrit/server/restapi/project/CreateProject.java
index 6844cac..6428435 100644
--- a/java/com/google/gerrit/server/restapi/project/CreateProject.java
+++ b/java/com/google/gerrit/server/restapi/project/CreateProject.java
@@ -147,8 +147,6 @@
args.newChangeForAllNotInTarget =
MoreObjects.firstNonNull(
input.createNewChangeForAllNotInTarget, InheritableBoolean.INHERIT);
- args.changeIdRequired =
- MoreObjects.firstNonNull(input.requireChangeId, InheritableBoolean.INHERIT);
args.rejectEmptyCommit =
MoreObjects.firstNonNull(input.rejectEmptyCommit, InheritableBoolean.INHERIT);
args.enableSignedPush =
diff --git a/java/com/google/gerrit/server/restapi/project/IndexChanges.java b/java/com/google/gerrit/server/restapi/project/IndexChanges.java
index b84f86c..b6b3d6b 100644
--- a/java/com/google/gerrit/server/restapi/project/IndexChanges.java
+++ b/java/com/google/gerrit/server/restapi/project/IndexChanges.java
@@ -20,7 +20,7 @@
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
-import com.google.gerrit.extensions.api.projects.ProjectInput;
+import com.google.gerrit.extensions.common.Input;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.reviewdb.client.Project;
@@ -38,7 +38,7 @@
@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
@Singleton
-public class IndexChanges implements RestModifyView<ProjectResource, ProjectInput> {
+public class IndexChanges implements RestModifyView<ProjectResource, Input> {
private final Provider<AllChangesIndexer> allChangesIndexerProvider;
private final ChangeIndexer indexer;
@@ -55,7 +55,7 @@
}
@Override
- public Response.Accepted apply(ProjectResource resource, ProjectInput input) {
+ public Response.Accepted apply(ProjectResource resource, Input input) {
Project.NameKey project = resource.getNameKey();
Task mpt =
new MultiProgressMonitor(ByteStreams.nullOutputStream(), "Reindexing project")
diff --git a/java/com/google/gerrit/server/schema/AllProjectsInput.java b/java/com/google/gerrit/server/schema/AllProjectsInput.java
index 7231b18..f72bf4d 100644
--- a/java/com/google/gerrit/server/schema/AllProjectsInput.java
+++ b/java/com/google/gerrit/server/schema/AllProjectsInput.java
@@ -33,8 +33,6 @@
public static final ImmutableMap<BooleanProjectConfig, InheritableBoolean>
DEFAULT_BOOLEAN_PROJECT_CONFIGS =
ImmutableMap.of(
- BooleanProjectConfig.REQUIRE_CHANGE_ID,
- InheritableBoolean.TRUE,
BooleanProjectConfig.USE_CONTENT_MERGE,
InheritableBoolean.TRUE,
BooleanProjectConfig.USE_CONTRIBUTOR_AGREEMENTS,
diff --git a/java/com/google/gerrit/server/schema/BUILD b/java/com/google/gerrit/server/schema/BUILD
index a8020b1..aa552ed 100644
--- a/java/com/google/gerrit/server/schema/BUILD
+++ b/java/com/google/gerrit/server/schema/BUILD
@@ -15,6 +15,7 @@
"//java/com/google/gerrit/metrics",
"//java/com/google/gerrit/reviewdb:server",
"//java/com/google/gerrit/server",
+ "//java/com/google/gerrit/server/logging",
"//java/com/google/gerrit/server/util/time",
"//lib:guava",
"//lib/auto:auto-value",
diff --git a/java/com/google/gerrit/server/schema/JdbcAccountPatchReviewStore.java b/java/com/google/gerrit/server/schema/JdbcAccountPatchReviewStore.java
index d7dbf58..cb91dea 100644
--- a/java/com/google/gerrit/server/schema/JdbcAccountPatchReviewStore.java
+++ b/java/com/google/gerrit/server/schema/JdbcAccountPatchReviewStore.java
@@ -34,6 +34,9 @@
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.config.ThreadSettingsConfig;
+import com.google.gerrit.server.logging.Metadata;
+import com.google.gerrit.server.logging.TraceContext;
+import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import java.nio.file.Path;
import java.sql.Connection;
import java.sql.PreparedStatement;
@@ -212,7 +215,15 @@
@Override
public boolean markReviewed(PatchSet.Id psId, Account.Id accountId, String path) {
- try (Connection con = ds.getConnection();
+ try (TraceTimer ignored =
+ TraceContext.newTimer(
+ "Mark file as reviewed",
+ Metadata.builder()
+ .patchSetId(psId.get())
+ .accountId(accountId.get())
+ .filePath(path)
+ .build());
+ Connection con = ds.getConnection();
PreparedStatement stmt =
con.prepareStatement(
"INSERT INTO account_patch_reviews "
@@ -239,7 +250,15 @@
return;
}
- try (Connection con = ds.getConnection();
+ try (TraceTimer ignored =
+ TraceContext.newTimer(
+ "Mark files as reviewed",
+ Metadata.builder()
+ .patchSetId(psId.get())
+ .accountId(accountId.get())
+ .resourceCount(paths.size())
+ .build());
+ Connection con = ds.getConnection();
PreparedStatement stmt =
con.prepareStatement(
"INSERT INTO account_patch_reviews "
@@ -264,7 +283,15 @@
@Override
public void clearReviewed(PatchSet.Id psId, Account.Id accountId, String path) {
- try (Connection con = ds.getConnection();
+ try (TraceTimer ignored =
+ TraceContext.newTimer(
+ "Clear reviewed flag",
+ Metadata.builder()
+ .patchSetId(psId.get())
+ .accountId(accountId.get())
+ .filePath(path)
+ .build());
+ Connection con = ds.getConnection();
PreparedStatement stmt =
con.prepareStatement(
"DELETE FROM account_patch_reviews "
@@ -282,7 +309,11 @@
@Override
public void clearReviewed(PatchSet.Id psId) {
- try (Connection con = ds.getConnection();
+ try (TraceTimer ignored =
+ TraceContext.newTimer(
+ "Clear all reviewed flags of patch set",
+ Metadata.builder().patchSetId(psId.get()).build());
+ Connection con = ds.getConnection();
PreparedStatement stmt =
con.prepareStatement(
"DELETE FROM account_patch_reviews "
@@ -297,7 +328,11 @@
@Override
public void clearReviewed(Change.Id changeId) {
- try (Connection con = ds.getConnection();
+ try (TraceTimer ignored =
+ TraceContext.newTimer(
+ "Clear all reviewed flags of change",
+ Metadata.builder().changeId(changeId.get()).build());
+ Connection con = ds.getConnection();
PreparedStatement stmt =
con.prepareStatement("DELETE FROM account_patch_reviews WHERE change_id = ?")) {
stmt.setInt(1, changeId.get());
@@ -309,7 +344,11 @@
@Override
public Optional<PatchSetWithReviewedFiles> findReviewed(PatchSet.Id psId, Account.Id accountId) {
- try (Connection con = ds.getConnection();
+ try (TraceTimer ignored =
+ TraceContext.newTimer(
+ "Find reviewed flags",
+ Metadata.builder().patchSetId(psId.get()).accountId(accountId.get()).build());
+ Connection con = ds.getConnection();
PreparedStatement stmt =
con.prepareStatement(
"SELECT patch_set_id, file_name FROM account_patch_reviews APR1 "
diff --git a/java/com/google/gerrit/server/schema/testing/AllProjectsCreatorTestUtil.java b/java/com/google/gerrit/server/schema/testing/AllProjectsCreatorTestUtil.java
index be56782..6c49b22 100644
--- a/java/com/google/gerrit/server/schema/testing/AllProjectsCreatorTestUtil.java
+++ b/java/com/google/gerrit/server/schema/testing/AllProjectsCreatorTestUtil.java
@@ -40,7 +40,6 @@
"[receive]",
" requireContributorAgreement = false",
" requireSignedOffBy = false",
- " requireChangeId = true",
" enableSignedPush = false");
private static final ImmutableList<String> DEFAULT_ALL_PROJECTS_SUBMIT_SECTION =
ImmutableList.of("[submit]", " mergeContent = true");
diff --git a/java/com/google/gerrit/server/submit/MergeOp.java b/java/com/google/gerrit/server/submit/MergeOp.java
index 06c52c7..6c3d48b 100644
--- a/java/com/google/gerrit/server/submit/MergeOp.java
+++ b/java/com/google/gerrit/server/submit/MergeOp.java
@@ -511,6 +511,8 @@
retryHelper
.getDefaultTimeout(ActionType.CHANGE_UPDATE)
.multipliedBy(cs.projects().size()))
+ .caller(getClass())
+ .retryWithTrace(t -> !(t instanceof RestApiException))
.build());
if (projects > 1) {
diff --git a/java/com/google/gerrit/server/update/RetryHelper.java b/java/com/google/gerrit/server/update/RetryHelper.java
index 7a4f462..695feba 100644
--- a/java/com/google/gerrit/server/update/RetryHelper.java
+++ b/java/com/google/gerrit/server/update/RetryHelper.java
@@ -39,11 +39,15 @@
import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.gerrit.server.logging.Metadata;
+import com.google.gerrit.server.logging.RequestId;
+import com.google.gerrit.server.logging.TraceContext;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.time.Duration;
import java.util.Arrays;
import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -93,12 +97,20 @@
@Nullable
abstract Duration timeout();
+ abstract Optional<Class<?>> caller();
+
+ abstract Optional<Predicate<Throwable>> retryWithTrace();
+
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder listener(RetryListener listener);
public abstract Builder timeout(Duration timeout);
+ public abstract Builder caller(Class<?> caller);
+
+ public abstract Builder retryWithTrace(Predicate<Throwable> exceptionPredicate);
+
public abstract Options build();
}
}
@@ -111,7 +123,8 @@
@Inject
Metrics(MetricMaker metricMaker) {
- Field<ActionType> actionTypeField = Field.ofEnum(ActionType.class, "action_type").build();
+ Field<ActionType> actionTypeField =
+ Field.ofEnum(ActionType.class, "action_type", Metadata.Builder::actionType).build();
attemptCounts =
metricMaker.newCounter(
"action/retry_attempt_count",
@@ -145,6 +158,7 @@
private final Map<ActionType, Duration> defaultTimeouts;
private final WaitStrategy waitStrategy;
@Nullable private final Consumer<RetryerBuilder<?>> overwriteDefaultRetryerStrategySetup;
+ private final boolean retryWithTraceOnFailure;
@Inject
RetryHelper(@GerritServerConfig Config cfg, Metrics metrics, BatchUpdate.Factory updateFactory) {
@@ -184,6 +198,7 @@
MILLISECONDS),
WaitStrategies.randomWait(50, MILLISECONDS));
this.overwriteDefaultRetryerStrategySetup = overwriteDefaultRetryerStrategySetup;
+ this.retryWithTraceOnFailure = cfg.getBoolean("retry", "retryWithTraceOnFailure", false);
}
public Duration getDefaultTimeout(ActionType actionType) {
@@ -254,8 +269,35 @@
Predicate<Throwable> exceptionPredicate)
throws Throwable {
MetricListener listener = new MetricListener();
- try {
- RetryerBuilder<T> retryerBuilder = createRetryerBuilder(actionType, opts, exceptionPredicate);
+ try (TraceContext traceContext = TraceContext.open()) {
+ RetryerBuilder<T> retryerBuilder =
+ createRetryerBuilder(
+ actionType,
+ opts,
+ t -> {
+ // exceptionPredicate checks for temporary errors for which the operation should be
+ // retried (e.g. LockFailure). The retry has good chances to succeed.
+ if (exceptionPredicate.test(t)) {
+ return true;
+ }
+
+ // A non-recoverable failure occurred. Check if we should retry to capture a trace
+ // of the failure. If a trace was already done there is no need to retry.
+ if (retryWithTraceOnFailure
+ && opts.retryWithTrace().isPresent()
+ && opts.retryWithTrace().get().test(t)
+ && !traceContext.isTracing()) {
+ traceContext
+ .addTag(RequestId.Type.TRACE_ID, "retry-on-failure-" + new RequestId())
+ .forceLogging();
+ logger.atFine().withCause(t).log(
+ "%s failed, retry with tracing eanbled",
+ opts.caller().map(Class::getSimpleName).orElse("N/A"));
+ return true;
+ }
+
+ return false;
+ });
retryerBuilder.withRetryListener(listener);
return executeWithTimeoutCount(actionType, action, retryerBuilder.build());
} finally {
diff --git a/java/com/google/gerrit/server/update/RetryingRestCollectionModifyView.java b/java/com/google/gerrit/server/update/RetryingRestCollectionModifyView.java
index 7620386..9204565 100644
--- a/java/com/google/gerrit/server/update/RetryingRestCollectionModifyView.java
+++ b/java/com/google/gerrit/server/update/RetryingRestCollectionModifyView.java
@@ -17,6 +17,7 @@
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestCollectionModifyView;
import com.google.gerrit.extensions.restapi.RestResource;
@@ -32,7 +33,13 @@
@Override
public final O apply(P parentResource, I input)
throws AuthException, BadRequestException, ResourceConflictException, Exception {
- return retryHelper.execute((updateFactory) -> applyImpl(updateFactory, parentResource, input));
+ RetryHelper.Options retryOptions =
+ RetryHelper.options()
+ .caller(getClass())
+ .retryWithTrace(t -> !(t instanceof RestApiException))
+ .build();
+ return retryHelper.execute(
+ (updateFactory) -> applyImpl(updateFactory, parentResource, input), retryOptions);
}
protected abstract O applyImpl(BatchUpdate.Factory updateFactory, P parentResource, I input)
diff --git a/java/com/google/gerrit/server/update/RetryingRestModifyView.java b/java/com/google/gerrit/server/update/RetryingRestModifyView.java
index e2f4a02..b471d70 100644
--- a/java/com/google/gerrit/server/update/RetryingRestModifyView.java
+++ b/java/com/google/gerrit/server/update/RetryingRestModifyView.java
@@ -14,6 +14,7 @@
package com.google.gerrit.server.update;
+import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.extensions.restapi.RestResource;
@@ -27,7 +28,13 @@
@Override
public final O apply(R resource, I input) throws Exception {
- return retryHelper.execute((updateFactory) -> applyImpl(updateFactory, resource, input));
+ RetryHelper.Options retryOptions =
+ RetryHelper.options()
+ .caller(getClass())
+ .retryWithTrace(t -> !(t instanceof RestApiException))
+ .build();
+ return retryHelper.execute(
+ (updateFactory) -> applyImpl(updateFactory, resource, input), retryOptions);
}
protected abstract O applyImpl(BatchUpdate.Factory updateFactory, R resource, I input)
diff --git a/java/com/google/gerrit/sshd/SshCommand.java b/java/com/google/gerrit/sshd/SshCommand.java
index 2bbdc49..2590188 100644
--- a/java/com/google/gerrit/sshd/SshCommand.java
+++ b/java/com/google/gerrit/sshd/SshCommand.java
@@ -16,10 +16,13 @@
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.server.AccessPath;
+import com.google.gerrit.server.RequestInfo;
+import com.google.gerrit.server.RequestListener;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.logging.PerformanceLogContext;
import com.google.gerrit.server.logging.PerformanceLogger;
import com.google.gerrit.server.logging.TraceContext;
+import com.google.gerrit.server.plugincontext.PluginSetContext;
import com.google.inject.Inject;
import java.io.IOException;
import java.io.PrintWriter;
@@ -29,6 +32,7 @@
public abstract class SshCommand extends BaseCommand {
@Inject private DynamicSet<PerformanceLogger> performanceLoggers;
+ @Inject private PluginSetContext<RequestListener> requestListeners;
@Inject @GerritServerConfig private Config config;
@Option(name = "--trace", usage = "enable request tracing")
@@ -50,6 +54,9 @@
try (TraceContext traceContext = enableTracing();
PerformanceLogContext performanceLogContext =
new PerformanceLogContext(config, performanceLoggers)) {
+ RequestInfo requestInfo =
+ RequestInfo.builder(RequestInfo.RequestType.SSH, user, traceContext).build();
+ requestListeners.runEach(l -> l.onRequest(requestInfo));
SshCommand.this.run();
} finally {
stdout.flush();
diff --git a/java/com/google/gerrit/sshd/SshKeyCacheImpl.java b/java/com/google/gerrit/sshd/SshKeyCacheImpl.java
index 94e7f1b..773c25b 100644
--- a/java/com/google/gerrit/sshd/SshKeyCacheImpl.java
+++ b/java/com/google/gerrit/sshd/SshKeyCacheImpl.java
@@ -24,6 +24,7 @@
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIds;
import com.google.gerrit.server.cache.CacheModule;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.gerrit.server.ssh.SshKeyCache;
@@ -107,7 +108,8 @@
public Iterable<SshKeyCacheEntry> load(String username) throws Exception {
try (TraceTimer timer =
TraceContext.newTimer(
- "Loading SSH keys for account with username", "username", username)) {
+ "Loading SSH keys for account with username",
+ Metadata.builder().username(username).build())) {
Optional<ExternalId> user =
externalIds.get(ExternalId.Key.create(SCHEME_USERNAME, username));
if (!user.isPresent()) {
diff --git a/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java b/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java
index df86d63..56e72e6 100644
--- a/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java
+++ b/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java
@@ -91,9 +91,6 @@
@Option(name = "--content-merge", usage = "allow automatic conflict resolving within files")
private InheritableBoolean contentMerge = InheritableBoolean.INHERIT;
- @Option(name = "--change-id", usage = "if change-id is required")
- private InheritableBoolean requireChangeID = InheritableBoolean.INHERIT;
-
@Option(name = "--reject-empty-commit", usage = "if empty commits should be rejected on submit")
private InheritableBoolean rejectEmptyCommit = InheritableBoolean.INHERIT;
@@ -124,14 +121,6 @@
}
@Option(
- name = "--require-change-id",
- aliases = {"--id"},
- usage = "if change-id is required")
- void setRequireChangeId(@SuppressWarnings("unused") boolean on) {
- requireChangeID = InheritableBoolean.TRUE;
- }
-
- @Option(
name = "--create-new-change-for-all-not-in-target",
aliases = {"--ncfa"},
usage = "if a new change will be created for every commit not in target branch")
@@ -186,7 +175,6 @@
input.useContributorAgreements = contributorAgreements;
input.useSignedOffBy = signedOffBy;
input.useContentMerge = contentMerge;
- input.requireChangeId = requireChangeID;
input.createNewChangeForAllNotInTarget = createNewChangeForAllNotInTarget;
input.branches = branch;
input.createEmptyCommit = createEmptyCommit;
diff --git a/java/com/google/gerrit/sshd/commands/SetProjectCommand.java b/java/com/google/gerrit/sshd/commands/SetProjectCommand.java
index 8c9fc9f..f145b9e 100644
--- a/java/com/google/gerrit/sshd/commands/SetProjectCommand.java
+++ b/java/com/google/gerrit/sshd/commands/SetProjectCommand.java
@@ -56,9 +56,6 @@
@Option(name = "--content-merge", usage = "allow automatic conflict resolving within files")
private InheritableBoolean contentMerge;
- @Option(name = "--change-id", usage = "if change-id is required")
- private InheritableBoolean requireChangeID;
-
@Option(
name = "--use-contributor-agreements",
aliases = {"--ca"},
@@ -104,22 +101,6 @@
}
@Option(
- name = "--require-change-id",
- aliases = {"--id"},
- usage = "if change-id is required")
- void setRequireChangeId(@SuppressWarnings("unused") boolean on) {
- requireChangeID = InheritableBoolean.TRUE;
- }
-
- @Option(
- name = "--no-change-id",
- aliases = {"--nid"},
- usage = "if change-id is not required")
- void setNoChangeId(@SuppressWarnings("unused") boolean on) {
- requireChangeID = InheritableBoolean.FALSE;
- }
-
- @Option(
name = "--project-state",
aliases = {"--ps"},
usage = "project's visibility state")
@@ -133,7 +114,6 @@
@Override
protected void run() throws Failure {
ConfigInput configInput = new ConfigInput();
- configInput.requireChangeId = requireChangeID;
configInput.submitType = submitType;
configInput.useContentMerge = contentMerge;
configInput.useContributorAgreements = contributorAgreements;
diff --git a/java/com/google/gerrit/sshd/commands/Upload.java b/java/com/google/gerrit/sshd/commands/Upload.java
index 24a6975..a22cdaf 100644
--- a/java/com/google/gerrit/sshd/commands/Upload.java
+++ b/java/com/google/gerrit/sshd/commands/Upload.java
@@ -17,15 +17,19 @@
import com.google.common.collect.Lists;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.server.RequestInfo;
+import com.google.gerrit.server.RequestListener;
import com.google.gerrit.server.git.DefaultAdvertiseRefsHook;
import com.google.gerrit.server.git.TransferConfig;
import com.google.gerrit.server.git.UploadPackInitializer;
import com.google.gerrit.server.git.validators.UploadValidationException;
import com.google.gerrit.server.git.validators.UploadValidators;
+import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackend.RefFilterOptions;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.ProjectPermission;
+import com.google.gerrit.server.plugincontext.PluginSetContext;
import com.google.gerrit.sshd.AbstractGitCommand;
import com.google.gerrit.sshd.SshSession;
import com.google.inject.Inject;
@@ -43,6 +47,7 @@
@Inject private DynamicSet<PreUploadHook> preUploadHooks;
@Inject private DynamicSet<PostUploadHook> postUploadHooks;
@Inject private DynamicSet<UploadPackInitializer> uploadPackInitializers;
+ @Inject private PluginSetContext<RequestListener> requestListeners;
@Inject private UploadValidators.Factory uploadValidatorsFactory;
@Inject private SshSession session;
@Inject private PermissionBackend permissionBackend;
@@ -73,7 +78,13 @@
for (UploadPackInitializer initializer : uploadPackInitializers) {
initializer.init(projectState.getNameKey(), up);
}
- try {
+ try (TraceContext traceContext = TraceContext.open()) {
+ RequestInfo requestInfo =
+ RequestInfo.builder(RequestInfo.RequestType.GIT_UPLOAD, user, traceContext)
+ .project(projectState.getNameKey())
+ .build();
+ requestListeners.runEach(l -> l.onRequest(requestInfo));
+
up.upload(in, out, err);
session.setPeerAgent(up.getPeerUserAgent());
} catch (UploadValidationException e) {
diff --git a/java/com/google/gerrit/testing/FakeAccountCache.java b/java/com/google/gerrit/testing/FakeAccountCache.java
index b99a32d..c86bcf4 100644
--- a/java/com/google/gerrit/testing/FakeAccountCache.java
+++ b/java/com/google/gerrit/testing/FakeAccountCache.java
@@ -20,8 +20,6 @@
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountState;
-import com.google.gerrit.server.config.AllUsersName;
-import com.google.gerrit.server.config.AllUsersNameProvider;
import com.google.gerrit.server.util.time.TimeUtil;
import java.util.HashMap;
import java.util.Map;
@@ -78,6 +76,6 @@
}
private static AccountState newState(Account account) {
- return AccountState.forAccount(new AllUsersName(AllUsersNameProvider.DEFAULT), account);
+ return AccountState.forAccount(account);
}
}
diff --git a/java/com/google/gerrit/util/cli/CmdLineParser.java b/java/com/google/gerrit/util/cli/CmdLineParser.java
index 1c16133..1c430fc 100644
--- a/java/com/google/gerrit/util/cli/CmdLineParser.java
+++ b/java/com/google/gerrit/util/cli/CmdLineParser.java
@@ -41,7 +41,6 @@
import com.google.common.base.Strings;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
-import com.google.common.collect.MultimapBuilder;
import com.google.common.flogger.FluentLogger;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@@ -313,23 +312,13 @@
parser.parseArgument(tmp.toArray(new String[tmp.size()]));
}
- public void parseOptionMap(Map<String, String[]> parameters) throws CmdLineException {
- ListMultimap<String, String> map = MultimapBuilder.hashKeys().arrayListValues().build();
- for (Map.Entry<String, String[]> ent : parameters.entrySet()) {
- for (String val : ent.getValue()) {
- map.put(ent.getKey(), val);
- }
- }
- parseOptionMap(map);
- }
-
public void parseOptionMap(ListMultimap<String, String> params) throws CmdLineException {
logger.atFinest().log("Command-line parameters: %s", params.keySet());
List<String> tmp = Lists.newArrayListWithCapacity(2 * params.size());
for (String key : params.keySet()) {
String name = makeOption(key);
- if (isBoolean(name)) {
+ if (isBooleanOption(name)) {
boolean on = false;
for (String value : params.get(key)) {
on = toBoolean(key, value);
@@ -347,10 +336,6 @@
parser.parseArgument(tmp.toArray(new String[tmp.size()]));
}
- public boolean isBoolean(String name) {
- return findHandler(makeOption(name)) instanceof BooleanOptionHandler;
- }
-
public void parseWithPrefix(String prefix, Object bean) {
parser.parseWithPrefix(prefix, bean);
}
@@ -359,6 +344,10 @@
parser.addOptionsWithMetRequirements();
}
+ private boolean isBooleanOption(String name) {
+ return findHandler(makeOption(name)) instanceof BooleanOptionHandler;
+ }
+
private String makeOption(String name) {
if (!name.startsWith("-")) {
if (name.length() == 1) {
diff --git a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
index 228f233..5b6acfe 100644
--- a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
@@ -131,6 +131,8 @@
import com.google.gerrit.server.index.account.AccountIndexer;
import com.google.gerrit.server.index.account.StalenessChecker;
import com.google.gerrit.server.notedb.Sequences;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackend.RefFilterOptions;
import com.google.gerrit.server.project.ProjectConfig;
import com.google.gerrit.server.project.RefPattern;
import com.google.gerrit.server.query.account.InternalAccountQuery;
@@ -217,6 +219,7 @@
@Inject private Sequences seq;
@Inject private StalenessChecker stalenessChecker;
@Inject private VersionedAuthorizedKeys.Accessor authorizedKeys;
+ @Inject private PermissionBackend permissionBackend;
@Inject protected Emails emails;
@@ -1371,6 +1374,19 @@
}
@Test
+ public void refsUsersSelfIsAdvertised() throws Exception {
+ try (Repository allUsersRepo = repoManager.openRepository(allUsers)) {
+ assertThat(
+ permissionBackend
+ .currentUser()
+ .project(allUsers)
+ .filter(ImmutableList.of(), allUsersRepo, RefFilterOptions.defaults())
+ .keySet())
+ .containsExactly(RefNames.REFS_USERS_SELF);
+ }
+ }
+
+ @Test
public void pushToUserBranch() throws Exception {
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
fetch(allUsersRepo, RefNames.refsUsers(admin.id()) + ":userRef");
diff --git a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
index 627fc09..1c1ef22 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
@@ -3468,6 +3468,42 @@
}
@Test
+ public void notifyConfigForDirectoryTriggersEmail() throws Exception {
+ // Configure notifications on project level.
+ RevCommit oldHead = projectOperations.project(project).getHead("master");
+ GitUtil.fetch(testRepo, RefNames.REFS_CONFIG + ":config");
+ testRepo.reset("config");
+ PushOneCommit push =
+ pushFactory.create(
+ admin.newIdent(),
+ testRepo,
+ "Configure Notifications",
+ "project.config",
+ "[notify \"my=notify-config\"]\n"
+ + " email = foo@test.com\n"
+ + " filter = dir:\\\"foo/bar/baz\\\"");
+ push.to(RefNames.REFS_CONFIG);
+ testRepo.reset(oldHead);
+
+ // Push a change that matches the filter.
+ sender.clear();
+ push =
+ pushFactory.create(
+ admin.newIdent(), testRepo, "Test change", "foo/bar/baz/test.txt", "some content");
+ PushOneCommit.Result r = push.to("refs/for/master");
+ assertThat(sender.getMessages()).hasSize(1);
+ assertThat(sender.getMessages().get(0).rcpt()).containsExactly(Address.parse("foo@test.com"));
+
+ // Comment on the change.
+ sender.clear();
+ ReviewInput reviewInput = new ReviewInput();
+ reviewInput.message = "some message";
+ gApi.changes().id(r.getChangeId()).current().review(reviewInput);
+ assertThat(sender.getMessages()).hasSize(1);
+ assertThat(sender.getMessages().get(0).rcpt()).containsExactly(Address.parse("foo@test.com"));
+ }
+
+ @Test
public void checkLabelsForMergedChangeWithNonAuthorCodeReview() throws Exception {
// Configure Non-Author-Code-Review
RevCommit oldHead = projectOperations.project(project).getHead("master");
@@ -3777,24 +3813,6 @@
}
@Test
- public void changeCommitMessageWithNoChangeIdSucceedsIfChangeIdNotRequired() throws Exception {
- ConfigInput configInput = new ConfigInput();
- configInput.requireChangeId = InheritableBoolean.FALSE;
- gApi.projects().name(project.get()).config(configInput);
-
- PushOneCommit.Result r = createChange();
- r.assertOkStatus();
- assertThat(getCommitMessage(r.getChangeId()))
- .isEqualTo("test commit\n\nChange-Id: " + r.getChangeId() + "\n");
-
- String newMessage = "modified commit\n";
- gApi.changes().id(r.getChangeId()).setMessage(newMessage);
- RevisionApi rApi = gApi.changes().id(r.getChangeId()).current();
- assertThat(rApi.files().keySet()).containsExactly("/COMMIT_MSG", "a.txt");
- assertThat(getCommitMessage(r.getChangeId())).isEqualTo(newMessage);
- }
-
- @Test
public void changeCommitMessageWithNoChangeIdFails() throws Exception {
PushOneCommit.Result r = createChange();
assertThat(getCommitMessage(r.getChangeId()))
diff --git a/javatests/com/google/gerrit/acceptance/api/change/StickyApprovalsIT.java b/javatests/com/google/gerrit/acceptance/api/change/StickyApprovalsIT.java
index 99935b5..20be0a7 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/StickyApprovalsIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/StickyApprovalsIT.java
@@ -16,7 +16,6 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
-import static com.google.common.truth.Truth.assert_;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
import static com.google.gerrit.extensions.client.ChangeKind.MERGE_FIRST_PARENT_UPDATE;
import static com.google.gerrit.extensions.client.ChangeKind.NO_CHANGE;
@@ -414,7 +413,7 @@
noChange(changeId);
return;
default:
- assert_().fail("unexpected change kind: " + changeKind);
+ assertWithMessage("unexpected change kind: " + changeKind).fail();
}
}
@@ -523,7 +522,7 @@
case NO_CHANGE:
case MERGE_FIRST_PARENT_UPDATE:
default:
- assert_().fail("unexpected change kind: " + changeKind);
+ assertWithMessage("unexpected change kind: " + changeKind).fail();
}
testRepo.reset(projectOperations.project(project).getHead("master"));
diff --git a/javatests/com/google/gerrit/acceptance/api/group/GroupsConsistencyIT.java b/javatests/com/google/gerrit/acceptance/api/group/GroupsConsistencyIT.java
index ab1dbd3..966c056 100644
--- a/javatests/com/google/gerrit/acceptance/api/group/GroupsConsistencyIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/group/GroupsConsistencyIT.java
@@ -15,7 +15,7 @@
package com.google.gerrit.acceptance.api.group;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
+import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
@@ -252,7 +252,8 @@
}
}
- assert_().fail(String.format("could not find %s substring '%s' in %s", want, msg, problems));
+ assertWithMessage(String.format("could not find %s substring '%s' in %s", want, msg, problems))
+ .fail();
}
private void updateGroupFile(String refName, String fileName, String content) throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/api/plugin/PluginIT.java b/javatests/com/google/gerrit/acceptance/api/plugin/PluginIT.java
index dd12382..a120eac 100644
--- a/javatests/com/google/gerrit/acceptance/api/plugin/PluginIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/plugin/PluginIT.java
@@ -15,7 +15,6 @@
package com.google.gerrit.acceptance.api.plugin;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.stream.Collectors.toList;
@@ -104,13 +103,7 @@
// Disable mandatory
mandatoryPluginsCollection.add("plugin_e");
- api = gApi.plugins().name("plugin_e");
- try {
- api.disable();
- assert_().fail("Disabling mandatory plugin should have failed");
- } catch (MethodNotAllowedException e) {
- // expected
- }
+ assertThrows(MethodNotAllowedException.class, () -> gApi.plugins().name("plugin_e").disable());
api = gApi.plugins().name("plugin_e");
assertThat(api.get().disabled).isNull();
diff --git a/javatests/com/google/gerrit/acceptance/api/project/CheckAccessIT.java b/javatests/com/google/gerrit/acceptance/api/project/CheckAccessIT.java
index 3fcc595..b7d6627 100644
--- a/javatests/com/google/gerrit/acceptance/api/project/CheckAccessIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/project/CheckAccessIT.java
@@ -15,7 +15,7 @@
package com.google.gerrit.acceptance.api.project;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
+import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.deny;
@@ -247,15 +247,16 @@
try {
info = gApi.projects().name(tc.project).checkAccess(tc.input);
} catch (RestApiException e) {
- assert_().fail(String.format("check.access(%s, %s): exception %s", tc.project, in, e));
+ assertWithMessage(String.format("check.access(%s, %s): exception %s", tc.project, in, e))
+ .fail();
}
int want = tc.want;
if (want != info.status) {
- assert_()
- .fail(
+ assertWithMessage(
String.format(
- "check.access(%s, %s) = %d, want %d", tc.project, in, info.status, want));
+ "check.access(%s, %s) = %d, want %d", tc.project, in, info.status, want))
+ .fail();
}
switch (want) {
@@ -271,7 +272,7 @@
assertThat(info.message).isNull();
break;
default:
- assert_().fail(String.format("unknown code %d", want));
+ assertWithMessage(String.format("unknown code %d", want)).fail();
}
}
}
diff --git a/javatests/com/google/gerrit/acceptance/api/project/CheckProjectIT.java b/javatests/com/google/gerrit/acceptance/api/project/CheckProjectIT.java
index 96ba722..05295ae 100644
--- a/javatests/com/google/gerrit/acceptance/api/project/CheckProjectIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/project/CheckProjectIT.java
@@ -27,7 +27,6 @@
import com.google.gerrit.extensions.api.projects.CheckProjectInput.AutoCloseableChangesCheckInput;
import com.google.gerrit.extensions.api.projects.CheckProjectResultInfo;
import com.google.gerrit.extensions.client.ChangeStatus;
-import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
@@ -66,7 +65,7 @@
@Test
public void detectAutoCloseableChangeByCommit() throws Exception {
- RevCommit commit = pushCommitWithoutChangeIdForReview();
+ RevCommit commit = pushCommitForReview();
ChangeInfo change =
Iterables.getOnlyElement(gApi.changes().query("commit:" + commit.name()).get());
@@ -90,7 +89,7 @@
@Test
public void fixAutoCloseableChangeByCommit() throws Exception {
- RevCommit commit = pushCommitWithoutChangeIdForReview();
+ RevCommit commit = pushCommitForReview();
ChangeInfo change =
Iterables.getOnlyElement(gApi.changes().query("commit:" + commit.name()).get());
@@ -280,17 +279,18 @@
+ ProjectsConsistencyChecker.AUTO_CLOSE_MAX_COMMITS_LIMIT);
}
- private RevCommit pushCommitWithoutChangeIdForReview() throws Exception {
- setRequireChangeId(InheritableBoolean.FALSE);
+ private RevCommit pushCommitForReview() throws Exception {
RevCommit commit =
testRepo
.branch("HEAD")
.commit()
.message("A change")
+ .insertChangeId()
.author(admin.newIdent())
.committer(new PersonIdent(admin.newIdent(), testRepo.getDate()))
.create();
pushHead(testRepo, "refs/for/master");
+
return commit;
}
diff --git a/javatests/com/google/gerrit/acceptance/api/project/ProjectIT.java b/javatests/com/google/gerrit/acceptance/api/project/ProjectIT.java
index 91c8d22..da0cd43 100644
--- a/javatests/com/google/gerrit/acceptance/api/project/ProjectIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/project/ProjectIT.java
@@ -316,7 +316,6 @@
assertThat(info.useSignedOffBy.configuredValue).isEqualTo(input.useSignedOffBy);
assertThat(info.createNewChangeForAllNotInTarget.configuredValue)
.isEqualTo(input.createNewChangeForAllNotInTarget);
- assertThat(info.requireChangeId.configuredValue).isEqualTo(input.requireChangeId);
assertThat(info.rejectImplicitMerges.configuredValue).isEqualTo(input.rejectImplicitMerges);
assertThat(info.enableReviewerByEmail.configuredValue).isEqualTo(input.enableReviewerByEmail);
assertThat(info.createNewChangeForAllNotInTarget.configuredValue)
@@ -346,7 +345,6 @@
assertThat(info.useSignedOffBy.configuredValue).isEqualTo(input.useSignedOffBy);
assertThat(info.createNewChangeForAllNotInTarget.configuredValue)
.isEqualTo(input.createNewChangeForAllNotInTarget);
- assertThat(info.requireChangeId.configuredValue).isEqualTo(input.requireChangeId);
assertThat(info.rejectImplicitMerges.configuredValue).isEqualTo(input.rejectImplicitMerges);
assertThat(info.enableReviewerByEmail.configuredValue).isEqualTo(input.enableReviewerByEmail);
assertThat(info.createNewChangeForAllNotInTarget.configuredValue)
@@ -683,7 +681,6 @@
input.useContentMerge = InheritableBoolean.TRUE;
input.useSignedOffBy = InheritableBoolean.TRUE;
input.createNewChangeForAllNotInTarget = InheritableBoolean.TRUE;
- input.requireChangeId = InheritableBoolean.TRUE;
input.rejectImplicitMerges = InheritableBoolean.TRUE;
input.enableReviewerByEmail = InheritableBoolean.TRUE;
input.createNewChangeForAllNotInTarget = InheritableBoolean.TRUE;
@@ -715,10 +712,6 @@
countsByProject.clear();
}
- long getCount(String projectName) {
- return countsByProject.get(projectName);
- }
-
void assertReindexOf(String projectName) {
assertReindexOf(projectName, 1);
}
diff --git a/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java b/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
index 553f225..3d9b88d 100644
--- a/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
+++ b/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
@@ -89,7 +89,6 @@
import com.google.gerrit.git.ObjectIds;
import com.google.gerrit.mail.Address;
import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.client.BooleanProjectConfig;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.ChangeMessage;
import com.google.gerrit.reviewdb.client.PatchSet;
@@ -101,7 +100,6 @@
import com.google.gerrit.server.git.receive.ReceiveConstants;
import com.google.gerrit.server.git.validators.CommitValidationListener;
import com.google.gerrit.server.git.validators.CommitValidationMessage;
-import com.google.gerrit.server.git.validators.CommitValidators.ChangeIdValidator;
import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.project.testing.TestLabels;
import com.google.gerrit.server.query.change.ChangeData;
@@ -125,7 +123,6 @@
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository;
@@ -460,20 +457,6 @@
}
@Test
- public void pushWithoutChangeIdDeprecated() throws Exception {
- setRequireChangeId(InheritableBoolean.FALSE);
- testRepo
- .branch("HEAD")
- .commit()
- .message("A change")
- .author(admin.newIdent())
- .committer(new PersonIdent(admin.newIdent(), testRepo.getDate()))
- .create();
- PushResult result = pushHead(testRepo, "refs/for/master");
- assertThat(result.getMessages()).contains("warning: pushing without Change-Id is deprecated");
- }
-
- @Test
public void autocloseByChangeId() throws Exception {
// Create a change
PushOneCommit.Result r = pushTo("refs/for/master");
@@ -1256,40 +1239,6 @@
}
@Test
- @GerritConfig(name = "receive.allowPushToRefsChanges", value = "true")
- public void pushToRefsChangesAllowed() throws Exception {
- PushOneCommit.Result r = pushOneCommitToRefsChanges();
- r.assertOkStatus();
- }
-
- @Test
- public void pushNewPatchsetToRefsChanges() throws Exception {
- PushOneCommit.Result r = pushOneCommitToRefsChanges();
- r.assertErrorStatus("upload to refs/changes not allowed");
- }
-
- @Test
- @GerritConfig(name = "receive.allowPushToRefsChanges", value = "false")
- public void pushToRefsChangesNotAllowed() throws Exception {
- PushOneCommit.Result r = pushOneCommitToRefsChanges();
- r.assertErrorStatus("upload to refs/changes not allowed");
- }
-
- private PushOneCommit.Result pushOneCommitToRefsChanges() throws Exception {
- PushOneCommit.Result r = pushTo("refs/for/master");
- r.assertOkStatus();
- PushOneCommit push =
- pushFactory.create(
- admin.newIdent(),
- testRepo,
- PushOneCommit.SUBJECT,
- "b.txt",
- "anotherContent",
- r.getChangeId());
- return push.to("refs/changes/" + r.getChange().change().getId().get());
- }
-
- @Test
public void pushNewPatchsetToPatchSetLockedChange() throws Exception {
PushOneCommit.Result r = pushTo("refs/for/master");
r.assertOkStatus();
@@ -1607,9 +1556,6 @@
RevCommit c = createCommit(testRepo, "Message without Change-Id");
assertThat(GitUtil.getChangeId(testRepo, c)).isEmpty();
pushForReviewRejected(testRepo, "missing Change-Id in message footer");
-
- setRequireChangeId(InheritableBoolean.FALSE);
- pushForReviewOk(testRepo);
}
@Test
@@ -1633,9 +1579,6 @@
+ "More text, uh oh.\n");
assertThat(GitUtil.getChangeId(testRepo, c)).isEmpty();
pushForReviewRejected(testRepo, "Change-Id must be in message footer");
-
- setRequireChangeId(InheritableBoolean.FALSE);
- pushForReviewRejected(testRepo, "Change-Id must be in message footer");
}
@Test
@@ -1654,28 +1597,6 @@
}
@Test
- @GerritConfig(name = "receive.allowPushToRefsChanges", value = "true")
- public void testPushWithChangedChangeId() throws Exception {
- PushOneCommit.Result r = pushTo("refs/for/master");
- r.assertOkStatus();
- PushOneCommit push =
- pushFactory.create(
- admin.newIdent(),
- testRepo,
- PushOneCommit.SUBJECT
- + "\n\n"
- + "Change-Id: I55eab7c7a76e95005fa9cc469aa8f9fc16da9eba\n",
- "b.txt",
- "anotherContent",
- r.getChangeId());
- r = push.to("refs/changes/" + r.getChange().change().getId().get());
- r.assertErrorStatus(
- String.format(
- "commit %s: %s",
- abbreviateName(r.getCommit()), ChangeIdValidator.CHANGE_ID_MISMATCH_MSG));
- }
-
- @Test
public void pushWithMultipleChangeIds() throws Exception {
testPushWithMultipleChangeIds();
}
@@ -1694,9 +1615,6 @@
+ "Change-Id: I10f98c2ef76e52e23aa23be5afeb71e40b350e86\n"
+ "Change-Id: Ie9a132e107def33bdd513b7854b50de911edba0a\n");
pushForReviewRejected(testRepo, "multiple Change-Id lines in message footer");
-
- setRequireChangeId(InheritableBoolean.FALSE);
- pushForReviewRejected(testRepo, "multiple Change-Id lines in message footer");
}
@Test
@@ -1713,9 +1631,6 @@
private void testpushWithInvalidChangeId() throws Exception {
createCommit(testRepo, "Message with invalid Change-Id\n\nChange-Id: X\n");
pushForReviewRejected(testRepo, "invalid Change-Id line format in message footer");
-
- setRequireChangeId(InheritableBoolean.FALSE);
- pushForReviewRejected(testRepo, "invalid Change-Id line format in message footer");
}
@Test
@@ -1737,18 +1652,12 @@
+ "\n"
+ "Change-Id: I0000000000000000000000000000000000000000\n");
pushForReviewRejected(testRepo, "invalid Change-Id line format in message footer");
-
- setRequireChangeId(InheritableBoolean.FALSE);
- pushForReviewRejected(testRepo, "invalid Change-Id line format in message footer");
}
@Test
public void pushWithChangeIdInSubjectLine() throws Exception {
createCommit(testRepo, "Change-Id: I1234000000000000000000000000000000000000");
pushForReviewRejected(testRepo, "missing subject; Change-Id must be in message footer");
-
- setRequireChangeId(InheritableBoolean.FALSE);
- pushForReviewRejected(testRepo, "missing subject; Change-Id must be in message footer");
}
@Test
@@ -1766,19 +1675,6 @@
"same Change-Id in multiple changes.\n"
+ "Squash the commits with the same Change-Id or ensure Change-Ids are unique for each"
+ " commit");
-
- try (ProjectConfigUpdate u = updateProject(project)) {
- u.getConfig()
- .getProject()
- .setBooleanConfig(BooleanProjectConfig.REQUIRE_CHANGE_ID, InheritableBoolean.FALSE);
- u.save();
- }
-
- pushForReviewRejected(
- testRepo,
- "same Change-Id in multiple changes.\n"
- + "Squash the commits with the same Change-Id or ensure Change-Ids are unique for each"
- + " commit");
}
@Test
@@ -1792,19 +1688,6 @@
"same Change-Id in multiple changes.\n"
+ "Squash the commits with the same Change-Id or ensure Change-Ids are unique for each"
+ " commit");
-
- try (ProjectConfigUpdate u = updateProject(project)) {
- u.getConfig()
- .getProject()
- .setBooleanConfig(BooleanProjectConfig.REQUIRE_CHANGE_ID, InheritableBoolean.FALSE);
- u.save();
- }
-
- pushForReviewRejected(
- testRepo,
- "same Change-Id in multiple changes.\n"
- + "Squash the commits with the same Change-Id or ensure Change-Ids are unique for each"
- + " commit");
}
private static RevCommit createCommit(TestRepository<?> testRepo, String message)
@@ -1851,25 +1734,6 @@
}
@Test
- @GerritConfig(name = "receive.allowPushToRefsChanges", value = "true")
- public void accidentallyPushNewPatchSetDirectlyToBranchAndRecoverByPushingToRefsChanges()
- throws Exception {
- Change.Id id = accidentallyPushNewPatchSetDirectlyToBranch();
- ChangeData cd = byChangeId(id);
- String ps1Rev = Iterables.getOnlyElement(cd.patchSets()).commitId().name();
-
- String r = "refs/changes/" + id;
- assertPushOk(pushHead(testRepo, r, false), r);
-
- // Added a new patch set and auto-closed the change.
- cd = byChangeId(id);
- assertThat(cd.change().isMerged()).isTrue();
- assertThat(getPatchSetRevisions(cd))
- .containsExactlyEntriesIn(
- ImmutableMap.of(1, ps1Rev, 2, testRepo.getRepository().resolve("HEAD").name()));
- }
-
- @Test
public void accidentallyPushNewPatchSetDirectlyToBranchAndCantRecoverByPushingToRefsFor()
throws Exception {
Change.Id id = accidentallyPushNewPatchSetDirectlyToBranch();
@@ -2799,10 +2663,6 @@
return cds.get(0);
}
- private static void pushForReviewOk(TestRepository<?> testRepo) throws GitAPIException {
- pushForReview(testRepo, RemoteRefUpdate.Status.OK, null);
- }
-
private static void pushForReviewRejected(TestRepository<?> testRepo, String expectedMessage)
throws GitAPIException {
pushForReview(testRepo, RemoteRefUpdate.Status.REJECTED_OTHER_REASON, expectedMessage);
diff --git a/javatests/com/google/gerrit/acceptance/git/PushPermissionsIT.java b/javatests/com/google/gerrit/acceptance/git/PushPermissionsIT.java
index 46012f4..66af8a4 100644
--- a/javatests/com/google/gerrit/acceptance/git/PushPermissionsIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/PushPermissionsIT.java
@@ -16,7 +16,6 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
-import static com.google.common.truth.Truth.assert_;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.git.testing.PushResultSubject.assertThat;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
@@ -31,10 +30,8 @@
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.changes.ReviewInput;
-import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.client.ProjectState;
import com.google.gerrit.extensions.common.ChangeInput;
-import com.google.gerrit.reviewdb.client.BooleanProjectConfig;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.project.ProjectConfig;
@@ -62,8 +59,6 @@
public void setUp() throws Exception {
try (ProjectConfigUpdate u = updateProject(allProjects)) {
ProjectConfig cfg = u.getConfig();
- cfg.getProject()
- .setBooleanConfig(BooleanProjectConfig.REQUIRE_CHANGE_ID, InheritableBoolean.FALSE);
// Remove push-related permissions, so they can be added back individually by test methods.
removeAllBranchPermissions(
@@ -98,17 +93,6 @@
}
@Test
- public void mixingDirectChangesAndRegularPush() throws Exception {
- testRepo.branch("HEAD").commit().create();
- PushResult r = push("HEAD:refs/heads/master", "HEAD:refs/changes/01/101");
-
- String msg = "cannot combine normal pushes and magic pushes";
- assertThat(r.getRemoteUpdate("refs/heads/master")).isNotEqualTo(Status.OK);
- assertThat(r.getRemoteUpdate("refs/changes/01/101")).isNotEqualTo(Status.OK);
- assertThat(r.getRemoteUpdate("refs/heads/master").getMessage()).isEqualTo(msg);
- }
-
- @Test
public void fastForwardUpdateDenied() throws Exception {
testRepo.branch("HEAD").commit().create();
PushResult r = push("HEAD:refs/heads/master");
@@ -267,7 +251,8 @@
.add(allow(Permission.PUSH).ref("refs/for/refs/heads/*").group(REGISTERED_USERS))
.update();
- ObjectId commit = testRepo.branch("HEAD").commit().create();
+ ObjectId commit =
+ testRepo.branch("HEAD").commit().message("test commit").insertChangeId().create();
assertThat(push("HEAD:refs/for/master")).onlyRef("refs/for/master").isOk();
gApi.changes().id(commit.name()).current().review(ReviewInput.approve());
@@ -430,7 +415,7 @@
case REJECTED_OTHER_REASON:
case RENAMED:
default:
- assert_().fail("fetch failed to update local %s: %s", ref, u.getResult());
+ assertWithMessage("fetch failed to update local %s: %s", ref, u.getResult()).fail();
break;
}
return u.getNewObjectId();
diff --git a/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java b/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
index ed8c081..88fc557 100644
--- a/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
@@ -630,11 +630,10 @@
try (Repository repo = repoManager.openRepository(project)) {
// c2 <- newcommit1 (branch)
PushOneCommit.Result r =
- r =
- pushFactory
- .create(admin.newIdent(), testRepo)
- .setParent(rcBranch)
- .to("refs/heads/branch");
+ pushFactory
+ .create(admin.newIdent(), testRepo)
+ .setParent(rcBranch)
+ .to("refs/heads/branch");
r.assertOkStatus();
RevCommit tagRc = r.getCommit();
@@ -687,11 +686,10 @@
try (Repository repo = repoManager.openRepository(project)) {
// rcBranch (c2) <- newcommit1 (branch)
PushOneCommit.Result r =
- r =
- pushFactory
- .create(admin.newIdent(), testRepo)
- .setParent(rcBranch)
- .to("refs/heads/branch");
+ pushFactory
+ .create(admin.newIdent(), testRepo)
+ .setParent(rcBranch)
+ .to("refs/heads/branch");
r.assertOkStatus();
RevCommit tagRc = r.getCommit();
@@ -743,11 +741,10 @@
try (Repository repo = repoManager.openRepository(project)) {
// rcBranch (c2) <- newcommit1 (branch)
PushOneCommit.Result r =
- r =
- pushFactory
- .create(admin.newIdent(), testRepo)
- .setParent(rcBranch)
- .to("refs/heads/branch");
+ pushFactory
+ .create(admin.newIdent(), testRepo)
+ .setParent(rcBranch)
+ .to("refs/heads/branch");
r.assertOkStatus();
RevCommit tagRc = r.getCommit();
@@ -921,7 +918,6 @@
.setParent(rcBranch)
.to("refs/tags/updated-tag");
r.assertOkStatus();
- RevCommit tagRc = r.getCommit();
}
assertUploadPackRefs(
diff --git a/javatests/com/google/gerrit/acceptance/git/RefOperationValidationIT.java b/javatests/com/google/gerrit/acceptance/git/RefOperationValidationIT.java
index b41c5bb..640f65e 100644
--- a/javatests/com/google/gerrit/acceptance/git/RefOperationValidationIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/RefOperationValidationIT.java
@@ -15,10 +15,10 @@
package com.google.gerrit.acceptance.git;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
import static com.google.gerrit.acceptance.GitUtil.deleteRef;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.eclipse.jgit.lib.Constants.HEAD;
import static org.eclipse.jgit.transport.ReceiveCommand.Type.CREATE;
import static org.eclipse.jgit.transport.ReceiveCommand.Type.DELETE;
@@ -83,9 +83,10 @@
@Test
public void rejectRefCreation() throws Exception {
try (TestRefValidator validator = new TestRefValidator(CREATE)) {
- gApi.projects().name(project.get()).branch(TEST_REF).create(new BranchInput());
- assert_().fail("expected exception");
- } catch (RestApiException expected) {
+ RestApiException expected =
+ assertThrows(
+ RestApiException.class,
+ () -> gApi.projects().name(project.get()).branch(TEST_REF).create(new BranchInput()));
assertThat(expected).hasMessageThat().contains(CREATE.name());
}
}
@@ -115,9 +116,10 @@
public void rejectRefDeletion() throws Exception {
gApi.projects().name(project.get()).branch(TEST_REF).create(new BranchInput());
try (TestRefValidator validator = new TestRefValidator(DELETE)) {
- gApi.projects().name(project.get()).branch(TEST_REF).delete();
- assert_().fail("expected exception");
- } catch (RestApiException expected) {
+ RestApiException expected =
+ assertThrows(
+ RestApiException.class,
+ () -> gApi.projects().name(project.get()).branch(TEST_REF).delete());
assertThat(expected).hasMessageThat().contains(DELETE.name());
}
}
diff --git a/javatests/com/google/gerrit/acceptance/git/SubmitOnPushIT.java b/javatests/com/google/gerrit/acceptance/git/SubmitOnPushIT.java
index 02f7b0a..3924992 100644
--- a/javatests/com/google/gerrit/acceptance/git/SubmitOnPushIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/SubmitOnPushIT.java
@@ -24,8 +24,14 @@
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
+import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.Permission;
+import com.google.gerrit.extensions.api.changes.NotifyHandling;
+import com.google.gerrit.extensions.api.changes.RecipientType;
+import com.google.gerrit.mail.Address;
+import com.google.gerrit.mail.EmailHeader;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
@@ -34,6 +40,7 @@
import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.testing.FakeEmailSender.Message;
import com.google.inject.Inject;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
@@ -358,6 +365,75 @@
assertThat(cd1.patchSet(psId1_2).commitId()).isEqualTo(c1_2);
}
+ @Test
+ public void pushForSubmitWithNotifyOption() throws Exception {
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.SUBMIT).ref("refs/for/refs/heads/master").group(adminGroupUuid()))
+ .update();
+
+ TestAccount user = accountCreator.user();
+ String pushSpec = "refs/for/master%reviewer=" + user.email();
+ sender.clear();
+
+ PushOneCommit.Result result = pushTo(pushSpec + ",submit,notify=" + NotifyHandling.NONE);
+ result.assertOkStatus();
+ assertThat(sender.getMessages()).isEmpty();
+
+ sender.clear();
+ result = pushTo(pushSpec + ",submit,notify=" + NotifyHandling.OWNER);
+ result.assertOkStatus();
+ assertThat(sender.getMessages()).isEmpty();
+
+ sender.clear();
+ result = pushTo(pushSpec + ",submit,notify=" + NotifyHandling.OWNER_REVIEWERS);
+ result.assertOkStatus();
+ assertThatEmailsForChangeCreationAndSubmitWereSent(user, null);
+
+ sender.clear();
+ result = pushTo(pushSpec + ",submit,notify=" + NotifyHandling.ALL);
+ result.assertOkStatus();
+ assertThatEmailsForChangeCreationAndSubmitWereSent(user, null);
+
+ sender.clear();
+ result = pushTo(pushSpec + ",submit"); // default is notify = ALL
+ result.assertOkStatus();
+ assertThatEmailsForChangeCreationAndSubmitWereSent(user, null);
+ }
+
+ @Test
+ public void pushForSubmitWithNotifyingUsersExplicitly() throws Exception {
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.SUBMIT).ref("refs/for/refs/heads/master").group(adminGroupUuid()))
+ .update();
+
+ TestAccount user = accountCreator.user();
+ String pushSpec = "refs/for/master%reviewer=" + user.email() + ",cc=" + user.email();
+
+ TestAccount user2 = accountCreator.user2();
+
+ sender.clear();
+ PushOneCommit.Result result =
+ pushTo(pushSpec + ",submit,notify=" + NotifyHandling.NONE + ",notify-to=" + user2.email());
+ result.assertOkStatus();
+ assertThatEmailsForChangeCreationAndSubmitWereSent(user2, RecipientType.TO);
+
+ sender.clear();
+ result =
+ pushTo(pushSpec + ",submit,notify=" + NotifyHandling.NONE + ",notify-cc=" + user2.email());
+ result.assertOkStatus();
+ assertThatEmailsForChangeCreationAndSubmitWereSent(user2, RecipientType.CC);
+
+ sender.clear();
+ result =
+ pushTo(pushSpec + ",submit,notify=" + NotifyHandling.NONE + ",notify-bcc=" + user2.email());
+ result.assertOkStatus();
+ assertThatEmailsForChangeCreationAndSubmitWereSent(user2, RecipientType.BCC);
+ }
+
private PatchSetApproval getSubmitter(PatchSet.Id patchSetId) throws Exception {
ChangeNotes notes = notesFactory.createChecked(project, patchSetId.changeId()).load();
return approvalsUtil.getSubmitter(notes, patchSetId);
@@ -405,4 +481,45 @@
pushFactory.create(admin.newIdent(), testRepo, subject, fileName, content, changeId);
return push.to(ref);
}
+
+ /**
+ * Makes sure that two emails are sent: one for the change creation, and one for the submit.
+ *
+ * @param expected The account expected to receive message.
+ * @param expectedRecipientType The notification's type: To/Cc/Bcc. if {@code null} then it is not
+ * needed to check the recipientType. It is meant for -notify without other flags like
+ * notify-cc, notify-to, and notify-bcc. With the -notify flag, the message can sometimes be
+ * sent as "To" and sometimes can be sent as "Cc".
+ */
+ private void assertThatEmailsForChangeCreationAndSubmitWereSent(
+ TestAccount expected, @Nullable RecipientType expectedRecipientType) {
+ String expectedEmail = expected.email();
+ String expectedFullName = expected.fullName();
+ Address expectedAddress = new Address(expectedFullName, expectedEmail);
+ assertThat(sender.getMessages()).hasSize(2);
+ Message message = sender.getMessages().get(0);
+ assertThat(message.body().contains("review")).isTrue();
+ assertAddress(message, expectedAddress, expectedRecipientType);
+ message = sender.getMessages().get(1);
+ assertThat(message.rcpt()).containsExactly(expectedAddress);
+ assertAddress(message, expectedAddress, expectedRecipientType);
+ assertThat(message.body().contains("submitted")).isTrue();
+ }
+
+ private void assertAddress(
+ Message message, Address expectedAddress, @Nullable RecipientType expectedRecipientType) {
+ assertThat(message.rcpt()).containsExactly(expectedAddress);
+ if (expectedRecipientType != null
+ && expectedRecipientType
+ != RecipientType.BCC) { // When Bcc, it does not appear in the header.
+ String expectedRecipientTypeString = "To";
+ if (expectedRecipientType == RecipientType.CC) {
+ expectedRecipientTypeString = "Cc";
+ }
+ assertThat(
+ ((EmailHeader.AddressList) message.headers().get(expectedRecipientTypeString))
+ .getAddressList())
+ .containsExactly(expectedAddress);
+ }
+ }
}
diff --git a/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java b/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java
index 6991a250..3fca298 100644
--- a/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java
+++ b/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java
@@ -37,7 +37,7 @@
@ConfigSuite.Config
public static Config elasticsearchV7() {
- return getConfig(ElasticVersion.V7_1);
+ return getConfig(ElasticVersion.V7_2);
}
@Override
diff --git a/javatests/com/google/gerrit/acceptance/rest/TraceIT.java b/javatests/com/google/gerrit/acceptance/rest/TraceIT.java
index d40bcdf..56a9b69 100644
--- a/javatests/com/google/gerrit/acceptance/rest/TraceIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/TraceIT.java
@@ -16,17 +16,22 @@
import static com.google.common.truth.Truth.assertThat;
import static org.apache.http.HttpStatus.SC_CREATED;
+import static org.apache.http.HttpStatus.SC_INTERNAL_SERVER_ERROR;
+import static org.apache.http.HttpStatus.SC_OK;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Iterables;
import com.google.common.truth.Expect;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GerritConfig;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.RestResponse;
+import com.google.gerrit.common.data.SubmitRecord;
+import com.google.gerrit.extensions.api.changes.ReviewInput;
+import com.google.gerrit.extensions.events.ChangeIndexedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.registration.RegistrationHandle;
import com.google.gerrit.httpd.restapi.ParameterParser;
@@ -37,16 +42,19 @@
import com.google.gerrit.server.git.validators.CommitValidationListener;
import com.google.gerrit.server.git.validators.CommitValidationMessage;
import com.google.gerrit.server.logging.LoggingContext;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.PerformanceLogger;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.project.CreateProjectArgs;
+import com.google.gerrit.server.project.SubmitRuleOptions;
+import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.server.rules.SubmitRule;
import com.google.gerrit.server.validators.ProjectCreationValidationListener;
import com.google.gerrit.server.validators.ValidationException;
import com.google.inject.Inject;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
-import java.util.Map;
-import java.util.Optional;
import java.util.SortedMap;
import java.util.SortedSet;
import org.apache.http.message.BasicHeader;
@@ -55,12 +63,29 @@
import org.junit.Rule;
import org.junit.Test;
+/**
+ * This test tests the tracing of requests.
+ *
+ * <p>To verify that tracing is working we do:
+ *
+ * <ul>
+ * <li>Register a plugin extension that we know is invoked when the request is done. Within the
+ * implementation of this plugin extension we access the status of the thread local state in
+ * the {@link LoggingContext} and store it locally in the plugin extension class.
+ * <li>Do a request (e.g. REST) that triggers the plugin extension.
+ * <li>When the plugin extension is invoked it records the current logging context.
+ * <li>After the request is done the test verifies that logging context that was recorded by the
+ * plugin extension has the expected state.
+ * </ul>
+ */
public class TraceIT extends AbstractDaemonTest {
@Rule public final Expect expect = Expect.create();
@Inject private DynamicSet<ProjectCreationValidationListener> projectCreationValidationListeners;
@Inject private DynamicSet<CommitValidationListener> commitValidationListeners;
+ @Inject private DynamicSet<ChangeIndexedListener> changeIndexedListeners;
@Inject private DynamicSet<PerformanceLogger> performanceLoggers;
+ @Inject private DynamicSet<SubmitRule> submitRules;
@Inject private WorkQueue workQueue;
private TraceValidatingProjectCreationValidationListener projectCreationListener;
@@ -96,6 +121,29 @@
assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
assertThat(projectCreationListener.traceId).isNull();
assertThat(projectCreationListener.isLoggingForced).isFalse();
+
+ // The logging tag with the project name is also set if tracing is off.
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new1");
+ }
+
+ @Test
+ public void restCallForChangeSetsProjectTag() throws Exception {
+ String changeId = createChange().getChangeId();
+
+ TraceChangeIndexedListener changeIndexedListener = new TraceChangeIndexedListener();
+ RegistrationHandle registrationHandle =
+ changeIndexedListeners.add("gerrit", changeIndexedListener);
+ try {
+ RestResponse response =
+ adminRestSession.post(
+ "/changes/" + changeId + "/revisions/current/review", ReviewInput.approve());
+ assertThat(response.getStatusCode()).isEqualTo(SC_OK);
+
+ // The logging tag with the project name is also set if tracing is off.
+ assertThat(changeIndexedListener.tags.get("project")).containsExactly(project.get());
+ } finally {
+ registrationHandle.remove();
+ }
}
@Test
@@ -106,6 +154,7 @@
assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNotNull();
assertThat(projectCreationListener.traceId).isNotNull();
assertThat(projectCreationListener.isLoggingForced).isTrue();
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new2");
}
@Test
@@ -116,6 +165,7 @@
assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isEqualTo("issue/123");
assertThat(projectCreationListener.traceId).isEqualTo("issue/123");
assertThat(projectCreationListener.isLoggingForced).isTrue();
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new3");
}
@Test
@@ -127,6 +177,7 @@
assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNotNull();
assertThat(projectCreationListener.traceId).isNotNull();
assertThat(projectCreationListener.isLoggingForced).isTrue();
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new4");
}
@Test
@@ -138,6 +189,7 @@
assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isEqualTo("issue/123");
assertThat(projectCreationListener.traceId).isEqualTo("issue/123");
assertThat(projectCreationListener.isLoggingForced).isTrue();
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new5");
}
@Test
@@ -150,6 +202,7 @@
assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isEqualTo("issue/123");
assertThat(projectCreationListener.traceId).isEqualTo("issue/123");
assertThat(projectCreationListener.isLoggingForced).isTrue();
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new6");
// trace ID only specified by trace request parameter
response =
@@ -159,6 +212,7 @@
assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isEqualTo("issue/123");
assertThat(projectCreationListener.traceId).isEqualTo("issue/123");
assertThat(projectCreationListener.isLoggingForced).isTrue();
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new7");
// same trace ID specified by trace header and trace request parameter
response =
@@ -169,6 +223,7 @@
assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isEqualTo("issue/123");
assertThat(projectCreationListener.traceId).isEqualTo("issue/123");
assertThat(projectCreationListener.isLoggingForced).isTrue();
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new8");
// different trace IDs specified by trace header and trace request parameter
response =
@@ -180,6 +235,7 @@
.containsExactly("issue/123", "issue/456");
assertThat(projectCreationListener.traceIds).containsExactly("issue/123", "issue/456");
assertThat(projectCreationListener.isLoggingForced).isTrue();
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new9");
}
@Test
@@ -189,6 +245,9 @@
r.assertOkStatus();
assertThat(commitValidationListener.traceId).isNull();
assertThat(commitValidationListener.isLoggingForced).isFalse();
+
+ // The logging tag with the project name is also set if tracing is off.
+ assertThat(commitValidationListener.tags.get("project")).containsExactly(project.get());
}
@Test
@@ -199,6 +258,7 @@
r.assertOkStatus();
assertThat(commitValidationListener.traceId).isNotNull();
assertThat(commitValidationListener.isLoggingForced).isTrue();
+ assertThat(commitValidationListener.tags.get("project")).containsExactly(project.get());
}
@Test
@@ -209,6 +269,7 @@
r.assertOkStatus();
assertThat(commitValidationListener.traceId).isEqualTo("issue/123");
assertThat(commitValidationListener.isLoggingForced).isTrue();
+ assertThat(commitValidationListener.tags.get("project")).containsExactly(project.get());
}
@Test
@@ -218,6 +279,9 @@
r.assertOkStatus();
assertThat(commitValidationListener.traceId).isNull();
assertThat(commitValidationListener.isLoggingForced).isFalse();
+
+ // The logging tag with the project name is also set if tracing is off.
+ assertThat(commitValidationListener.tags.get("project")).containsExactly(project.get());
}
@Test
@@ -228,6 +292,7 @@
r.assertOkStatus();
assertThat(commitValidationListener.traceId).isNotNull();
assertThat(commitValidationListener.isLoggingForced).isTrue();
+ assertThat(commitValidationListener.tags.get("project")).containsExactly(project.get());
}
@Test
@@ -238,6 +303,7 @@
r.assertOkStatus();
assertThat(commitValidationListener.traceId).isEqualTo("issue/123");
assertThat(commitValidationListener.isLoggingForced).isTrue();
+ assertThat(commitValidationListener.tags.get("project")).containsExactly(project.get());
}
@Test
@@ -308,6 +374,256 @@
assertThat(testPerformanceLogger.logEntries()).isEmpty();
}
+ @Test
+ @GerritConfig(name = "tracing.issue123.projectPattern", value = "new12")
+ public void traceProject() throws Exception {
+ RestResponse response = adminRestSession.put("/projects/new12");
+ assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(projectCreationListener.traceId).isEqualTo("issue123");
+ assertThat(projectCreationListener.isLoggingForced).isTrue();
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new12");
+ }
+
+ @Test
+ @GerritConfig(name = "tracing.issue123.projectPattern", value = "new.*")
+ public void traceProjectMatchRegEx() throws Exception {
+ RestResponse response = adminRestSession.put("/projects/new13");
+ assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(projectCreationListener.traceId).isEqualTo("issue123");
+ assertThat(projectCreationListener.isLoggingForced).isTrue();
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new13");
+ }
+
+ @Test
+ @GerritConfig(name = "tracing.issue123.projectPattern", value = "foo.*")
+ public void traceProjectNoMatch() throws Exception {
+ RestResponse response = adminRestSession.put("/projects/new13");
+ assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(projectCreationListener.traceId).isNull();
+ assertThat(projectCreationListener.isLoggingForced).isFalse();
+
+ // The logging tag with the project name is also set if tracing is off.
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new13");
+ }
+
+ @Test
+ @GerritConfig(name = "tracing.issue123.projectPattern", value = "][")
+ public void traceProjectInvalidRegEx() throws Exception {
+ RestResponse response = adminRestSession.put("/projects/new14");
+ assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(projectCreationListener.traceId).isNull();
+ assertThat(projectCreationListener.isLoggingForced).isFalse();
+
+ // The logging tag with the project name is also set if tracing is off.
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new14");
+ }
+
+ @Test
+ @GerritConfig(name = "tracing.issue123.account", value = "1000000")
+ public void traceAccount() throws Exception {
+ RestResponse response = adminRestSession.put("/projects/new15");
+ assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(projectCreationListener.traceId).isEqualTo("issue123");
+ assertThat(projectCreationListener.isLoggingForced).isTrue();
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new15");
+ }
+
+ @Test
+ @GerritConfig(name = "tracing.issue123.account", value = "1000001")
+ public void traceAccountNoMatch() throws Exception {
+ RestResponse response = adminRestSession.put("/projects/new16");
+ assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(projectCreationListener.traceId).isNull();
+ assertThat(projectCreationListener.isLoggingForced).isFalse();
+
+ // The logging tag with the project name is also set if tracing is off.
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new16");
+ }
+
+ @Test
+ @GerritConfig(name = "tracing.issue123.account", value = "999")
+ public void traceAccountNotFound() throws Exception {
+ RestResponse response = adminRestSession.put("/projects/new17");
+ assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(projectCreationListener.traceId).isNull();
+ assertThat(projectCreationListener.isLoggingForced).isFalse();
+
+ // The logging tag with the project name is also set if tracing is off.
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new17");
+ }
+
+ @Test
+ @GerritConfig(name = "tracing.issue123.account", value = "invalid")
+ public void traceAccountInvalidId() throws Exception {
+ RestResponse response = adminRestSession.put("/projects/new18");
+ assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(projectCreationListener.traceId).isNull();
+ assertThat(projectCreationListener.isLoggingForced).isFalse();
+
+ // The logging tag with the project name is also set if tracing is off.
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new18");
+ }
+
+ @Test
+ @GerritConfig(name = "tracing.issue123.requestType", value = "REST")
+ public void traceRequestType() throws Exception {
+ RestResponse response = adminRestSession.put("/projects/new19");
+ assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(projectCreationListener.traceId).isEqualTo("issue123");
+ assertThat(projectCreationListener.isLoggingForced).isTrue();
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new19");
+ }
+
+ @Test
+ @GerritConfig(name = "tracing.issue123.requestType", value = "SSH")
+ public void traceRequestTypeNoMatch() throws Exception {
+ RestResponse response = adminRestSession.put("/projects/new20");
+ assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(projectCreationListener.traceId).isNull();
+ assertThat(projectCreationListener.isLoggingForced).isFalse();
+
+ // The logging tag with the project name is also set if tracing is off.
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new20");
+ }
+
+ @Test
+ @GerritConfig(name = "tracing.issue123.requestType", value = "FOO")
+ public void traceProjectInvalidRequestType() throws Exception {
+ RestResponse response = adminRestSession.put("/projects/new21");
+ assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(projectCreationListener.traceId).isNull();
+ assertThat(projectCreationListener.isLoggingForced).isFalse();
+
+ // The logging tag with the project name is also set if tracing is off.
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new21");
+ }
+
+ @Test
+ @GerritConfig(name = "tracing.issue123.account", value = "1000000")
+ @GerritConfig(name = "tracing.issue123.projectPattern", value = "new.*")
+ public void traceProjectForAccount() throws Exception {
+ RestResponse response = adminRestSession.put("/projects/new22");
+ assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(projectCreationListener.traceId).isEqualTo("issue123");
+ assertThat(projectCreationListener.isLoggingForced).isTrue();
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new22");
+ }
+
+ @Test
+ @GerritConfig(name = "tracing.issue123.account", value = "1000000")
+ @GerritConfig(name = "tracing.issue123.projectPattern", value = "foo.*")
+ public void traceProjectForAccountNoProjectMatch() throws Exception {
+ RestResponse response = adminRestSession.put("/projects/new23");
+ assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(projectCreationListener.traceId).isNull();
+ assertThat(projectCreationListener.isLoggingForced).isFalse();
+
+ // The logging tag with the project name is also set if tracing is off.
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new23");
+ }
+
+ @Test
+ @GerritConfig(name = "tracing.issue123.account", value = "1000001")
+ @GerritConfig(name = "tracing.issue123.projectPattern", value = "new.*")
+ public void traceProjectForAccountNoAccountMatch() throws Exception {
+ RestResponse response = adminRestSession.put("/projects/new24");
+ assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(projectCreationListener.traceId).isNull();
+ assertThat(projectCreationListener.isLoggingForced).isFalse();
+
+ // The logging tag with the project name is also set if tracing is off.
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new24");
+ }
+
+ @Test
+ @GerritConfig(name = "tracing.issue123.requestUriPattern", value = "/projects/.*")
+ public void traceRequestUri() throws Exception {
+ RestResponse response = adminRestSession.put("/projects/new23");
+ assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(projectCreationListener.traceId).isEqualTo("issue123");
+ assertThat(projectCreationListener.isLoggingForced).isTrue();
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new23");
+ }
+
+ @Test
+ @GerritConfig(name = "tracing.issue123.requestUriPattern", value = "/projects/.*/foo")
+ public void traceRequestUriNoMatch() throws Exception {
+ RestResponse response = adminRestSession.put("/projects/new23");
+ assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(projectCreationListener.traceId).isNull();
+ assertThat(projectCreationListener.isLoggingForced).isFalse();
+
+ // The logging tag with the project name is also set if tracing is off.
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new23");
+ }
+
+ @Test
+ @GerritConfig(name = "tracing.issue123.requestUriPattern", value = "][")
+ public void traceRequestUriInvalidRegEx() throws Exception {
+ RestResponse response = adminRestSession.put("/projects/new24");
+ assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(projectCreationListener.traceId).isNull();
+ assertThat(projectCreationListener.isLoggingForced).isFalse();
+
+ // The logging tag with the project name is also set if tracing is off.
+ assertThat(projectCreationListener.tags.get("project")).containsExactly("new24");
+ }
+
+ @GerritConfig(name = "retry.retryWithTraceOnFailure", value = "true")
+ public void autoRetryWithTrace() throws Exception {
+ String changeId = createChange().getChangeId();
+ approve(changeId);
+
+ TraceSubmitRule traceSubmitRule = new TraceSubmitRule();
+ traceSubmitRule.failOnce = true;
+ RegistrationHandle submitRuleRegistrationHandle = submitRules.add("gerrit", traceSubmitRule);
+ try {
+ RestResponse response = adminRestSession.post("/changes/" + changeId + "/submit");
+ assertThat(response.getStatusCode()).isEqualTo(SC_OK);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(traceSubmitRule.traceId).startsWith("retry-on-failure-");
+ assertThat(traceSubmitRule.isLoggingForced).isTrue();
+ } finally {
+ submitRuleRegistrationHandle.remove();
+ }
+ }
+
+ @Test
+ public void noAutoRetryWithTraceIfDisabled() throws Exception {
+ String changeId = createChange().getChangeId();
+ approve(changeId);
+
+ TraceSubmitRule traceSubmitRule = new TraceSubmitRule();
+ traceSubmitRule.failOnce = true;
+ RegistrationHandle submitRuleRegistrationHandle = submitRules.add("gerrit", traceSubmitRule);
+ try {
+ RestResponse response = adminRestSession.post("/changes/" + changeId + "/submit");
+ assertThat(response.getStatusCode()).isEqualTo(SC_INTERNAL_SERVER_ERROR);
+ assertThat(response.getHeader(RestApiServlet.X_GERRIT_TRACE)).isNull();
+ assertThat(traceSubmitRule.traceId).isNull();
+ assertThat(traceSubmitRule.isLoggingForced).isNull();
+ } finally {
+ submitRuleRegistrationHandle.remove();
+ }
+ }
+
private void assertForceLogging(boolean expected) {
assertThat(LoggingContext.getInstance().shouldForceLogging(null, null, false))
.isEqualTo(expected);
@@ -318,6 +634,7 @@
String traceId;
ImmutableSet<String> traceIds;
Boolean isLoggingForced;
+ ImmutableSetMultimap<String, String> tags;
@Override
public void validateNewProject(CreateProjectArgs args) throws ValidationException {
@@ -325,12 +642,14 @@
Iterables.getFirst(LoggingContext.getInstance().getTagsAsMap().get("TRACE_ID"), null);
this.traceIds = LoggingContext.getInstance().getTagsAsMap().get("TRACE_ID");
this.isLoggingForced = LoggingContext.getInstance().shouldForceLogging(null, null, false);
+ this.tags = LoggingContext.getInstance().getTagsAsMap();
}
}
private static class TraceValidatingCommitValidationListener implements CommitValidationListener {
String traceId;
Boolean isLoggingForced;
+ ImmutableSetMultimap<String, String> tags;
@Override
public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent receiveEvent)
@@ -338,16 +657,51 @@
this.traceId =
Iterables.getFirst(LoggingContext.getInstance().getTagsAsMap().get("TRACE_ID"), null);
this.isLoggingForced = LoggingContext.getInstance().shouldForceLogging(null, null, false);
+ this.tags = LoggingContext.getInstance().getTagsAsMap();
return ImmutableList.of();
}
}
+ private static class TraceChangeIndexedListener implements ChangeIndexedListener {
+ ImmutableSetMultimap<String, String> tags;
+
+ @Override
+ public void onChangeIndexed(String projectName, int id) {
+ this.tags = LoggingContext.getInstance().getTagsAsMap();
+ }
+
+ @Override
+ public void onChangeDeleted(int id) {}
+ }
+
+ private static class TraceSubmitRule implements SubmitRule {
+ String traceId;
+ Boolean isLoggingForced;
+ boolean failOnce;
+
+ @Override
+ public Collection<SubmitRecord> evaluate(ChangeData changeData, SubmitRuleOptions options) {
+ if (failOnce) {
+ failOnce = false;
+ throw new IllegalStateException("forced failure from test");
+ }
+
+ this.traceId =
+ Iterables.getFirst(LoggingContext.getInstance().getTagsAsMap().get("TRACE_ID"), null);
+ this.isLoggingForced = LoggingContext.getInstance().shouldForceLogging(null, null, false);
+
+ SubmitRecord submitRecord = new SubmitRecord();
+ submitRecord.status = SubmitRecord.Status.OK;
+ return ImmutableList.of(submitRecord);
+ }
+ }
+
private static class TestPerformanceLogger implements PerformanceLogger {
private List<PerformanceLogEntry> logEntries = new ArrayList<>();
@Override
- public void log(String operation, long durationMs, Map<String, Optional<Object>> metaData) {
- logEntries.add(PerformanceLogEntry.create(operation, metaData));
+ public void log(String operation, long durationMs, Metadata metadata) {
+ logEntries.add(PerformanceLogEntry.create(operation, metadata));
}
ImmutableList<PerformanceLogEntry> logEntries() {
@@ -357,12 +711,12 @@
@AutoValue
abstract static class PerformanceLogEntry {
- static PerformanceLogEntry create(String operation, Map<String, Optional<Object>> metaData) {
- return new AutoValue_TraceIT_PerformanceLogEntry(operation, ImmutableMap.copyOf(metaData));
+ static PerformanceLogEntry create(String operation, Metadata metadata) {
+ return new AutoValue_TraceIT_PerformanceLogEntry(operation, metadata);
}
abstract String operation();
- abstract ImmutableMap<String, Object> metaData();
+ abstract Metadata metadata();
}
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
index be3f2a0..c2df9ca 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
@@ -502,6 +502,81 @@
}
@Test
+ public void submitWholeTopicWithMultipleTopics() throws Throwable {
+ assume().that(isSubmitWholeTopicEnabled()).isTrue();
+ String topic1 = "test-topic-1";
+ String topic2 = "test-topic-2";
+ PushOneCommit.Result change1 = createChange("Change 1", "a.txt", "content", topic1);
+ PushOneCommit.Result change2 = createChange("Change 2", "b.txt", "content", topic1);
+ PushOneCommit.Result change3 = createChange("Change 3", "c.txt", "content", topic2);
+ PushOneCommit.Result change4 = createChange("Change 4", "d.txt", "content", topic2);
+ approve(change1.getChangeId());
+ approve(change2.getChangeId());
+ approve(change3.getChangeId());
+ approve(change4.getChangeId());
+ submit(change4.getChangeId());
+ String expectedTopic1 = name(topic1);
+ String expectedTopic2 = name(topic2);
+ if (getSubmitType() == SubmitType.CHERRY_PICK) {
+ change1.assertChange(Change.Status.NEW, expectedTopic1, admin);
+ change2.assertChange(Change.Status.NEW, expectedTopic1, admin);
+
+ } else {
+ change1.assertChange(Change.Status.MERGED, expectedTopic1, admin);
+ change2.assertChange(Change.Status.MERGED, expectedTopic1, admin);
+ }
+
+ // Check for the exact change to have the correct submitter.
+ assertSubmitter(change4);
+ // Also check submitters for changes submitted via the topic relationship.
+ assertSubmitter(change3);
+ if (getSubmitType() != SubmitType.CHERRY_PICK) {
+ assertSubmitter(change1);
+ assertSubmitter(change2);
+ }
+
+ // Check that the repo has the expected commits
+ List<RevCommit> log = getRemoteLog();
+ List<String> commitsInRepo = log.stream().map(RevCommit::getShortMessage).collect(toList());
+ int expectedCommitCount;
+ switch (getSubmitType()) {
+ case MERGE_ALWAYS:
+ // initial commit + 4 commits + merge commit
+ expectedCommitCount = 6;
+ break;
+ case CHERRY_PICK:
+ // initial commit + 2 commits
+ expectedCommitCount = 3;
+ break;
+ case FAST_FORWARD_ONLY:
+ case INHERIT:
+ case MERGE_IF_NECESSARY:
+ case REBASE_ALWAYS:
+ case REBASE_IF_NECESSARY:
+ default:
+ // initial commit + 4 commits
+ expectedCommitCount = 5;
+ break;
+ }
+ assertThat(log).hasSize(expectedCommitCount);
+
+ if (getSubmitType() == SubmitType.CHERRY_PICK) {
+ assertThat(commitsInRepo).containsAtLeast("Initial empty repository", "Change 3", "Change 4");
+ assertThat(commitsInRepo).doesNotContain("Change 1");
+ assertThat(commitsInRepo).doesNotContain("Change 2");
+ } else if (getSubmitType() == SubmitType.MERGE_ALWAYS) {
+ assertThat(commitsInRepo)
+ .contains(
+ String.format(
+ "Merge changes from topics \"%s\", \"%s\"", expectedTopic1, expectedTopic2));
+ } else {
+ assertThat(commitsInRepo)
+ .containsAtLeast(
+ "Initial empty repository", "Change 1", "Change 2", "Change 3", "Change 4");
+ }
+ }
+
+ @Test
public void submitReusingOldTopic() throws Throwable {
assume().that(isSubmitWholeTopicEnabled()).isTrue();
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/WorkInProgressByDefaultIT.java b/javatests/com/google/gerrit/acceptance/rest/change/WorkInProgressByDefaultIT.java
index 49692dd..ccf1c0d 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/WorkInProgressByDefaultIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/WorkInProgressByDefaultIT.java
@@ -15,11 +15,13 @@
package com.google.gerrit.acceptance.rest.change;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.GitUtil.assertPushOk;
+import static com.google.gerrit.acceptance.GitUtil.pushHead;
import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.GitUtil;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
-import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.extensions.api.projects.ConfigInput;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
import com.google.gerrit.extensions.client.InheritableBoolean;
@@ -29,113 +31,165 @@
import com.google.inject.Inject;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
-import org.junit.After;
-import org.junit.Before;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.transport.PushResult;
import org.junit.Test;
public class WorkInProgressByDefaultIT extends AbstractDaemonTest {
@Inject private ProjectOperations projectOperations;
- @Inject private RequestScopeOperations requestScopeOperations;
-
- private Project.NameKey project1;
- private Project.NameKey project2;
-
- @Before
- public void setUp() throws Exception {
- project1 = projectOperations.newProject().create();
- project2 = projectOperations.newProject().parent(project1).create();
- }
-
- @After
- public void tearDown() throws Exception {
- requestScopeOperations.setApiUser(admin.id());
- GeneralPreferencesInfo prefs = gApi.accounts().id(admin.id().get()).getPreferences();
- prefs.workInProgressByDefault = false;
- gApi.accounts().id(admin.id().get()).setPreferences(prefs);
- }
@Test
public void createChangeWithWorkInProgressByDefaultForProjectDisabled() throws Exception {
+ Project.NameKey project = projectOperations.newProject().create();
ChangeInfo info =
- gApi.changes().create(new ChangeInput(project2.get(), "master", "empty change")).get();
+ gApi.changes().create(new ChangeInput(project.get(), "master", "empty change")).get();
assertThat(info.workInProgress).isNull();
}
@Test
public void createChangeWithWorkInProgressByDefaultForProjectEnabled() throws Exception {
- setWorkInProgressByDefaultForProject(project2);
- ChangeInput input = new ChangeInput(project2.get(), "master", "empty change");
+ Project.NameKey project = projectOperations.newProject().create();
+ setWorkInProgressByDefaultForProject(project);
+ ChangeInput input = new ChangeInput(project.get(), "master", "empty change");
assertThat(gApi.changes().create(input).get().workInProgress).isTrue();
}
@Test
public void createChangeWithWorkInProgressByDefaultForUserEnabled() throws Exception {
+ Project.NameKey project = projectOperations.newProject().create();
setWorkInProgressByDefaultForUser();
- ChangeInput input = new ChangeInput(project2.get(), "master", "empty change");
+ ChangeInput input = new ChangeInput(project.get(), "master", "empty change");
assertThat(gApi.changes().create(input).get().workInProgress).isTrue();
}
@Test
public void createChangeBypassWorkInProgressByDefaultForProjectEnabled() throws Exception {
- setWorkInProgressByDefaultForProject(project2);
- ChangeInput input = new ChangeInput(project2.get(), "master", "empty change");
+ Project.NameKey project = projectOperations.newProject().create();
+ setWorkInProgressByDefaultForProject(project);
+ ChangeInput input = new ChangeInput(project.get(), "master", "empty change");
input.workInProgress = false;
assertThat(gApi.changes().create(input).get().workInProgress).isNull();
}
@Test
public void createChangeBypassWorkInProgressByDefaultForUserEnabled() throws Exception {
+ Project.NameKey project = projectOperations.newProject().create();
setWorkInProgressByDefaultForUser();
- ChangeInput input = new ChangeInput(project2.get(), "master", "empty change");
+ ChangeInput input = new ChangeInput(project.get(), "master", "empty change");
input.workInProgress = false;
assertThat(gApi.changes().create(input).get().workInProgress).isNull();
}
@Test
public void createChangeWithWorkInProgressByDefaultForProjectInherited() throws Exception {
- setWorkInProgressByDefaultForProject(project1);
+ Project.NameKey parentProject = projectOperations.newProject().create();
+ Project.NameKey childProject = projectOperations.newProject().parent(parentProject).create();
+ setWorkInProgressByDefaultForProject(parentProject);
ChangeInfo info =
- gApi.changes().create(new ChangeInput(project2.get(), "master", "empty change")).get();
+ gApi.changes().create(new ChangeInput(childProject.get(), "master", "empty change")).get();
assertThat(info.workInProgress).isTrue();
}
@Test
public void pushWithWorkInProgressByDefaultForProjectEnabled() throws Exception {
- setWorkInProgressByDefaultForProject(project2);
- assertThat(createChange(project2).getChange().change().isWorkInProgress()).isTrue();
+ Project.NameKey project = projectOperations.newProject().create();
+ setWorkInProgressByDefaultForProject(project);
+ assertThat(createChange(project).getChange().change().isWorkInProgress()).isTrue();
}
@Test
public void pushWithWorkInProgressByDefaultForUserEnabled() throws Exception {
+ Project.NameKey project = projectOperations.newProject().create();
setWorkInProgressByDefaultForUser();
- assertThat(createChange(project2).getChange().change().isWorkInProgress()).isTrue();
+ assertThat(createChange(project).getChange().change().isWorkInProgress()).isTrue();
}
@Test
public void pushBypassWorkInProgressByDefaultForProjectEnabled() throws Exception {
- setWorkInProgressByDefaultForProject(project2);
+ Project.NameKey project = projectOperations.newProject().create();
+ setWorkInProgressByDefaultForProject(project);
assertThat(
- createChange(project2, "refs/for/master%ready").getChange().change().isWorkInProgress())
+ createChange(project, "refs/for/master%ready").getChange().change().isWorkInProgress())
.isFalse();
}
@Test
public void pushBypassWorkInProgressByDefaultForUserEnabled() throws Exception {
+ Project.NameKey project = projectOperations.newProject().create();
setWorkInProgressByDefaultForUser();
assertThat(
- createChange(project2, "refs/for/master%ready").getChange().change().isWorkInProgress())
+ createChange(project, "refs/for/master%ready").getChange().change().isWorkInProgress())
.isFalse();
}
@Test
public void pushWithWorkInProgressByDefaultForProjectDisabled() throws Exception {
- assertThat(createChange(project2).getChange().change().isWorkInProgress()).isFalse();
+ Project.NameKey project = projectOperations.newProject().create();
+ assertThat(createChange(project).getChange().change().isWorkInProgress()).isFalse();
}
@Test
public void pushWorkInProgressByDefaultForProjectInherited() throws Exception {
- setWorkInProgressByDefaultForProject(project1);
- assertThat(createChange(project2).getChange().change().isWorkInProgress()).isTrue();
+ Project.NameKey parentProject = projectOperations.newProject().create();
+ Project.NameKey childProject = projectOperations.newProject().parent(parentProject).create();
+ setWorkInProgressByDefaultForProject(parentProject);
+ assertThat(createChange(childProject).getChange().change().isWorkInProgress()).isTrue();
+ }
+
+ @Test
+ public void pushNewPatchSetWithWorkInProgressByDefaultForUserEnabled() throws Exception {
+ Project.NameKey project = projectOperations.newProject().create();
+
+ // Create change.
+ TestRepository<InMemoryRepository> testRepo = cloneProject(project);
+ PushOneCommit.Result result =
+ pushFactory.create(admin.newIdent(), testRepo).to("refs/for/master");
+ result.assertOkStatus();
+
+ String changeId = result.getChangeId();
+ assertThat(gApi.changes().id(changeId).get().workInProgress).isNull();
+
+ setWorkInProgressByDefaultForUser();
+
+ // Create new patch set on existing change, this shouldn't mark the change as WIP.
+ result = pushFactory.create(admin.newIdent(), testRepo, changeId).to("refs/for/master");
+ result.assertOkStatus();
+ assertThat(gApi.changes().id(changeId).get().workInProgress).isNull();
+ }
+
+ @Test
+ public void pushNewPatchSetAndNewChangeAtOnceWithWorkInProgressByDefaultForUserEnabled()
+ throws Exception {
+ Project.NameKey project = projectOperations.newProject().create();
+
+ // Create change.
+ TestRepository<InMemoryRepository> testRepo = cloneProject(project);
+ RevCommit initialHead = getHead(testRepo.getRepository(), "HEAD");
+ RevCommit commit1a =
+ testRepo.commit().parent(initialHead).message("Change 1").insertChangeId().create();
+ String changeId1 = GitUtil.getChangeId(testRepo, commit1a).get();
+ testRepo.reset(commit1a);
+ PushResult result = pushHead(testRepo, "refs/for/master", false);
+ assertPushOk(result, "refs/for/master");
+ assertThat(gApi.changes().id(changeId1).get().workInProgress).isNull();
+
+ setWorkInProgressByDefaultForUser();
+
+ // Create a new patch set on the existing change and in the same push create a new successor
+ // change.
+ RevCommit commit1b = testRepo.amend(commit1a).create();
+ testRepo.reset(commit1b);
+ RevCommit commit2 =
+ testRepo.commit().parent(commit1b).message("Change 2").insertChangeId().create();
+ String changeId2 = GitUtil.getChangeId(testRepo, commit2).get();
+ testRepo.reset(commit2);
+ result = pushHead(testRepo, "refs/for/master", false);
+ assertPushOk(result, "refs/for/master");
+
+ // Check that the existing change (changeId1) is not marked as WIP, but only the newly created
+ // change (changeId2).
+ assertThat(gApi.changes().id(changeId1).get().workInProgress).isNull();
+ assertThat(gApi.changes().id(changeId2).get().workInProgress).isTrue();
}
private void setWorkInProgressByDefaultForProject(Project.NameKey p) throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/rest/config/ServerInfoIT.java b/javatests/com/google/gerrit/acceptance/rest/config/ServerInfoIT.java
index 14521cc..4a74018 100644
--- a/javatests/com/google/gerrit/acceptance/rest/config/ServerInfoIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/config/ServerInfoIT.java
@@ -70,7 +70,6 @@
// gerrit
@GerritConfig(name = "gerrit.allProjects", value = "Root")
@GerritConfig(name = "gerrit.allUsers", value = "Users")
- @GerritConfig(name = "gerrit.reportBugText", value = "REPORT BUG")
@GerritConfig(name = "gerrit.reportBugUrl", value = "https://example.com/report")
// suggest
@@ -112,7 +111,6 @@
assertThat(i.gerrit.allProjects).isEqualTo("Root");
assertThat(i.gerrit.allUsers).isEqualTo("Users");
assertThat(i.gerrit.reportBugUrl).isEqualTo("https://example.com/report");
- assertThat(i.gerrit.reportBugText).isEqualTo("REPORT BUG");
// plugin
assertThat(i.plugin.jsResourcePaths).isEmpty();
@@ -179,7 +177,6 @@
assertThat(i.gerrit.allProjects).isEqualTo(AllProjectsNameProvider.DEFAULT);
assertThat(i.gerrit.allUsers).isEqualTo(AllUsersNameProvider.DEFAULT);
assertThat(i.gerrit.reportBugUrl).isNull();
- assertThat(i.gerrit.reportBugText).isNull();
// plugin
assertThat(i.plugin.jsResourcePaths).isEmpty();
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java b/javatests/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
index 043bde7..b102619 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
@@ -218,7 +218,6 @@
in.useContributorAgreements = InheritableBoolean.TRUE;
in.useSignedOffBy = InheritableBoolean.TRUE;
in.useContentMerge = InheritableBoolean.TRUE;
- in.requireChangeId = InheritableBoolean.TRUE;
ProjectInfo p = gApi.projects().create(in).get();
assertThat(p.name).isEqualTo(newProjectName);
Project project = projectCache.get(Project.nameKey(newProjectName)).getProject();
@@ -231,8 +230,6 @@
.isEqualTo(in.useSignedOffBy);
assertThat(project.getBooleanConfig(BooleanProjectConfig.USE_CONTENT_MERGE))
.isEqualTo(in.useContentMerge);
- assertThat(project.getBooleanConfig(BooleanProjectConfig.REQUIRE_CHANGE_ID))
- .isEqualTo(in.requireChangeId);
}
@Test
diff --git a/javatests/com/google/gerrit/acceptance/rest/util/RestApiCallHelper.java b/javatests/com/google/gerrit/acceptance/rest/util/RestApiCallHelper.java
index 52e72fe..f98fb45 100644
--- a/javatests/com/google/gerrit/acceptance/rest/util/RestApiCallHelper.java
+++ b/javatests/com/google/gerrit/acceptance/rest/util/RestApiCallHelper.java
@@ -15,7 +15,6 @@
package com.google.gerrit.acceptance.rest.util;
import static com.google.common.truth.Truth.assertWithMessage;
-import static com.google.common.truth.Truth.assert_;
import static org.apache.http.HttpStatus.SC_FORBIDDEN;
import static org.apache.http.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.apache.http.HttpStatus.SC_METHOD_NOT_ALLOWED;
@@ -76,7 +75,8 @@
response = restSession.delete(uri);
break;
default:
- assert_().fail(String.format("unsupported method: %s", restCall.httpMethod().name()));
+ assertWithMessage(String.format("unsupported method: %s", restCall.httpMethod().name()))
+ .fail();
throw new IllegalStateException();
}
diff --git a/javatests/com/google/gerrit/acceptance/server/change/CommentsIT.java b/javatests/com/google/gerrit/acceptance/server/change/CommentsIT.java
index 085cfea..6842926 100644
--- a/javatests/com/google/gerrit/acceptance/server/change/CommentsIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/change/CommentsIT.java
@@ -557,6 +557,13 @@
@Test
public void publishCommentsAllRevisions() throws Exception {
+ PushOneCommit.Result result = createChange();
+ String changeId = result.getChangeId();
+
+ pushFactory
+ .create(admin.newIdent(), testRepo, SUBJECT, FILE_NAME, "initial content\n", changeId)
+ .to("refs/heads/master");
+
PushOneCommit.Result r1 =
pushFactory
.create(admin.newIdent(), testRepo, SUBJECT, FILE_NAME, "old boring content\n")
@@ -580,7 +587,7 @@
addDraft(
r1.getChangeId(),
r1.getCommit().getName(),
- newDraft(FILE_NAME, Side.PARENT, 2, "what happened to this?"));
+ newDraft(FILE_NAME, Side.PARENT, createLineRange(1, 0, 7), "what happened to this?"));
addDraft(
r2.getChangeId(),
r2.getCommit().getName(),
@@ -665,8 +672,8 @@
+ project.get()
+ "/+/"
+ c
- + "/1/a.txt@a2 \n"
- + "PS1, Line 2: \n"
+ + "/1/a.txt@a1 \n"
+ + "PS1, Line 1: initial\n"
+ "what happened to this?\n"
+ "\n"
+ "\n"
@@ -694,7 +701,7 @@
+ "/+/"
+ c
+ "/2/a.txt@a1 \n"
- + "PS2, Line 1: \n"
+ + "PS2, Line 1: initial content\n"
+ "comment 1 on base\n"
+ "\n"
+ "\n"
@@ -724,7 +731,7 @@
+ "/+/"
+ c
+ "/2/a.txt@2 \n"
- + "PS2, Line 2: nten\n"
+ + "PS2, Line 2: cntent\n"
+ "typo: content\n"
+ "\n"
+ "\n");
@@ -1150,7 +1157,7 @@
private DraftInput newDraft(String path, Side side, Comment.Range range, String message) {
DraftInput d = new DraftInput();
- return populate(d, path, side, null, range, message, false);
+ return populate(d, path, side, null, range.startLine, range, message, false);
}
private DraftInput newDraftOnParent(String path, int parent, int line, String message) {
@@ -1163,23 +1170,25 @@
String path,
Side side,
Integer parent,
+ int line,
Comment.Range range,
String message,
Boolean unresolved) {
- int line = range.startLine;
c.path = path;
c.side = side;
c.parent = parent;
c.line = line != 0 ? line : null;
c.message = message;
c.unresolved = unresolved;
- if (line != 0) c.range = range;
+ if (range != null) {
+ c.range = range;
+ }
return c;
}
private static <C extends Comment> C populate(
C c, String path, Side side, Integer parent, int line, String message, Boolean unresolved) {
- return populate(c, path, side, parent, createLineRange(line, 1, 5), message, unresolved);
+ return populate(c, path, side, parent, line, null, message, unresolved);
}
private static Comment.Range createLineRange(int line, int startChar, int endChar) {
diff --git a/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java b/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java
index eaf65ae..f81ca4c 100644
--- a/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java
+++ b/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java
@@ -36,7 +36,7 @@
@ConfigSuite.Config
public static Config elasticsearchV7() {
- return getConfig(ElasticVersion.V7_1);
+ return getConfig(ElasticVersion.V7_2);
}
@Override
diff --git a/javatests/com/google/gerrit/acceptance/ssh/SshTraceIT.java b/javatests/com/google/gerrit/acceptance/ssh/SshTraceIT.java
index 5dd07c0..09e97b2 100644
--- a/javatests/com/google/gerrit/acceptance/ssh/SshTraceIT.java
+++ b/javatests/com/google/gerrit/acceptance/ssh/SshTraceIT.java
@@ -18,13 +18,13 @@
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.UseSsh;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.registration.RegistrationHandle;
import com.google.gerrit.server.logging.LoggingContext;
+import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.PerformanceLogger;
import com.google.gerrit.server.logging.RequestId;
import com.google.gerrit.server.project.CreateProjectArgs;
@@ -33,8 +33,6 @@
import com.google.inject.Inject;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
-import java.util.Optional;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -129,8 +127,8 @@
private List<PerformanceLogEntry> logEntries = new ArrayList<>();
@Override
- public void log(String operation, long durationMs, Map<String, Optional<Object>> metaData) {
- logEntries.add(PerformanceLogEntry.create(operation, metaData));
+ public void log(String operation, long durationMs, Metadata metadata) {
+ logEntries.add(PerformanceLogEntry.create(operation, metadata));
}
ImmutableList<PerformanceLogEntry> logEntries() {
@@ -140,12 +138,12 @@
@AutoValue
abstract static class PerformanceLogEntry {
- static PerformanceLogEntry create(String operation, Map<String, Optional<Object>> metaData) {
- return new AutoValue_SshTraceIT_PerformanceLogEntry(operation, ImmutableMap.copyOf(metaData));
+ static PerformanceLogEntry create(String operation, Metadata metadata) {
+ return new AutoValue_SshTraceIT_PerformanceLogEntry(operation, metadata);
}
abstract String operation();
- abstract ImmutableMap<String, Object> metaData();
+ abstract Metadata metadata();
}
}
diff --git a/javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java b/javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java
index de13552..34406e0 100644
--- a/javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java
+++ b/javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java
@@ -15,7 +15,7 @@
package com.google.gerrit.acceptance.ssh;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
+import static com.google.common.truth.Truth.assertWithMessage;
import com.google.common.base.Splitter;
import com.google.gerrit.acceptance.AbstractDaemonTest;
@@ -118,7 +118,7 @@
// that is currently not public.
char channel = packet.charAt(0);
if (channel != 1) {
- assert_().fail("got packet on channel " + (int) channel, packet);
+ assertWithMessage("got packet on channel " + (int) channel, packet).fail();
}
}
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java b/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
index ba64b2e..a0c40c7 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
@@ -54,6 +54,8 @@
return "blacktop/elasticsearch:7.0.1";
case V7_1:
return "blacktop/elasticsearch:7.1.1";
+ case V7_2:
+ return "blacktop/elasticsearch:7.2.0";
}
throw new IllegalStateException("No tests for version: " + version.name());
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
index 78c3684..c6faa7b 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
@@ -41,7 +41,7 @@
return;
}
- container = ElasticContainer.createAndStart(ElasticVersion.V7_1);
+ container = ElasticContainer.createAndStart(ElasticVersion.V7_2);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
index ae00e0d..780c8ab 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
@@ -51,7 +51,7 @@
return;
}
- container = ElasticContainer.createAndStart(ElasticVersion.V7_1);
+ container = ElasticContainer.createAndStart(ElasticVersion.V7_2);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
client = HttpAsyncClients.createDefault();
client.start();
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
index 301b5dd..188ed26 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
@@ -41,7 +41,7 @@
return;
}
- container = ElasticContainer.createAndStart(ElasticVersion.V7_1);
+ container = ElasticContainer.createAndStart(ElasticVersion.V7_2);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
index e1b7e3f..88617ee 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
@@ -41,7 +41,7 @@
return;
}
- container = ElasticContainer.createAndStart(ElasticVersion.V7_1);
+ container = ElasticContainer.createAndStart(ElasticVersion.V7_2);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java
index d28cbb4..0ad80de 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java
@@ -48,6 +48,9 @@
assertThat(ElasticVersion.forVersion("7.1.0")).isEqualTo(ElasticVersion.V7_1);
assertThat(ElasticVersion.forVersion("7.1.1")).isEqualTo(ElasticVersion.V7_1);
+
+ assertThat(ElasticVersion.forVersion("7.2.0")).isEqualTo(ElasticVersion.V7_2);
+ assertThat(ElasticVersion.forVersion("7.2.1")).isEqualTo(ElasticVersion.V7_2);
}
@Test
@@ -73,6 +76,7 @@
assertThat(ElasticVersion.V6_7.isAtLeastMinorVersion(ElasticVersion.V6_7)).isTrue();
assertThat(ElasticVersion.V7_0.isAtLeastMinorVersion(ElasticVersion.V6_7)).isFalse();
assertThat(ElasticVersion.V7_1.isAtLeastMinorVersion(ElasticVersion.V6_7)).isFalse();
+ assertThat(ElasticVersion.V7_2.isAtLeastMinorVersion(ElasticVersion.V6_7)).isFalse();
}
@Test
@@ -86,6 +90,7 @@
assertThat(ElasticVersion.V6_7.isV6OrLater()).isTrue();
assertThat(ElasticVersion.V7_0.isV6OrLater()).isTrue();
assertThat(ElasticVersion.V7_1.isV6OrLater()).isTrue();
+ assertThat(ElasticVersion.V7_2.isV6OrLater()).isTrue();
}
@Test
@@ -99,5 +104,6 @@
assertThat(ElasticVersion.V6_7.isV7OrLater()).isFalse();
assertThat(ElasticVersion.V7_0.isV7OrLater()).isTrue();
assertThat(ElasticVersion.V7_1.isV7OrLater()).isTrue();
+ assertThat(ElasticVersion.V7_2.isV7OrLater()).isTrue();
}
}
diff --git a/javatests/com/google/gerrit/httpd/BUILD b/javatests/com/google/gerrit/httpd/BUILD
index 0fbd922..6849d66 100644
--- a/javatests/com/google/gerrit/httpd/BUILD
+++ b/javatests/com/google/gerrit/httpd/BUILD
@@ -25,5 +25,6 @@
"//lib/jgit/org.eclipse.jgit:jgit",
"//lib/jgit/org.eclipse.jgit.junit:junit",
"//lib/truth",
+ "//lib/truth:truth-java8-extension",
],
)
diff --git a/javatests/com/google/gerrit/metrics/proc/ProcMetricModuleTest.java b/javatests/com/google/gerrit/metrics/proc/ProcMetricModuleTest.java
index 13d04ab..33919e7 100644
--- a/javatests/com/google/gerrit/metrics/proc/ProcMetricModuleTest.java
+++ b/javatests/com/google/gerrit/metrics/proc/ProcMetricModuleTest.java
@@ -82,7 +82,7 @@
metrics.newCounter(
"test/count",
new Description("simple test").setCumulative(),
- Field.ofString("action").build());
+ Field.ofString("action", Field.ignoreMetadata()).build());
Counter total = get("test/count_total", Counter.class);
assertThat(total.getCount()).isEqualTo(0);
@@ -107,7 +107,7 @@
new Description("simple test")
.setCumulative()
.setFieldOrdering(FieldOrdering.PREFIX_FIELDS_BASENAME),
- Field.ofString("action").build());
+ Field.ofString("action", Field.ignoreMetadata()).build());
Counter total = get("test/count_total", Counter.class);
assertThat(total.getCount()).isEqualTo(0);
diff --git a/javatests/com/google/gerrit/server/account/AccountResolverTest.java b/javatests/com/google/gerrit/server/account/AccountResolverTest.java
index d4ad7d7..5470e3c 100644
--- a/javatests/com/google/gerrit/server/account/AccountResolverTest.java
+++ b/javatests/com/google/gerrit/server/account/AccountResolverTest.java
@@ -27,7 +27,6 @@
import com.google.gerrit.server.account.AccountResolver.Searcher;
import com.google.gerrit.server.account.AccountResolver.StringSearcher;
import com.google.gerrit.server.account.AccountResolver.UnresolvableAccountException;
-import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.util.time.TimeUtil;
import java.util.Arrays;
import java.util.function.Predicate;
@@ -329,14 +328,13 @@
}
private AccountState newAccount(int id) {
- return AccountState.forAccount(
- new AllUsersName("All-Users"), new Account(Account.id(id), TimeUtil.nowTs()));
+ return AccountState.forAccount(new Account(Account.id(id), TimeUtil.nowTs()));
}
private AccountState newInactiveAccount(int id) {
Account a = new Account(Account.id(id), TimeUtil.nowTs());
a.setActive(false);
- return AccountState.forAccount(new AllUsersName("All-Users"), a);
+ return AccountState.forAccount(a);
}
private static ImmutableSet<Account.Id> ids(int... ids) {
diff --git a/javatests/com/google/gerrit/server/index/account/AccountFieldTest.java b/javatests/com/google/gerrit/server/index/account/AccountFieldTest.java
index 5573be7..0f73cc5 100644
--- a/javatests/com/google/gerrit/server/index/account/AccountFieldTest.java
+++ b/javatests/com/google/gerrit/server/index/account/AccountFieldTest.java
@@ -39,8 +39,7 @@
Account account = new Account(Account.id(1), TimeUtil.nowTs());
String metaId = "0e39795bb25dc914118224995c53c5c36923a461";
account.setMetaId(metaId);
- List<String> values =
- toStrings(AccountField.REF_STATE.get(AccountState.forAccount(allUsersName, account)));
+ List<String> values = toStrings(AccountField.REF_STATE.get(AccountState.forAccount(account)));
assertThat(values).hasSize(1);
String expectedValue =
allUsersName.get() + ":" + RefNames.refsUsers(account.getId()) + ":" + metaId;
@@ -68,7 +67,7 @@
List<String> values =
toStrings(
AccountField.EXTERNAL_ID_STATE.get(
- AccountState.forAccount(null, account, ImmutableSet.of(extId1, extId2))));
+ AccountState.forAccount(account, ImmutableSet.of(extId1, extId2))));
String expectedValue1 = extId1.key().sha1().name() + ":" + extId1.blobId().name();
String expectedValue2 = extId2.key().sha1().name() + ":" + extId2.blobId().name();
assertThat(values).containsExactly(expectedValue1, expectedValue2);
diff --git a/javatests/com/google/gerrit/server/logging/LoggingContextAwareExecutorServiceTest.java b/javatests/com/google/gerrit/server/logging/LoggingContextAwareExecutorServiceTest.java
index 8e2ca09c..733d784 100644
--- a/javatests/com/google/gerrit/server/logging/LoggingContextAwareExecutorServiceTest.java
+++ b/javatests/com/google/gerrit/server/logging/LoggingContextAwareExecutorServiceTest.java
@@ -24,8 +24,6 @@
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
-import java.util.Map;
-import java.util.Optional;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.concurrent.ExecutorService;
@@ -53,8 +51,7 @@
testPerformanceLogger =
new PerformanceLogger() {
@Override
- public void log(
- String operation, long durationMs, Map<String, Optional<Object>> metaData) {
+ public void log(String operation, long durationMs, Metadata metadata) {
// do nothing
}
};
diff --git a/javatests/com/google/gerrit/server/logging/PerformanceLogContextTest.java b/javatests/com/google/gerrit/server/logging/PerformanceLogContextTest.java
index 6b7df5e..ed4325d 100644
--- a/javatests/com/google/gerrit/server/logging/PerformanceLogContextTest.java
+++ b/javatests/com/google/gerrit/server/logging/PerformanceLogContextTest.java
@@ -18,7 +18,6 @@
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.registration.RegistrationHandle;
import com.google.gerrit.metrics.Description;
@@ -35,8 +34,6 @@
import com.google.inject.Injector;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
-import java.util.Optional;
import org.eclipse.jgit.lib.Config;
import org.junit.After;
import org.junit.Before;
@@ -80,87 +77,17 @@
assertThat(LoggingContext.getInstance().isPerformanceLogging()).isTrue();
TraceContext.newTimer("test1").close();
- TraceContext.newTimer("test2", "foo", "bar").close();
- TraceContext.newTimer("test3", "foo1", "bar1", "foo2", "bar2").close();
- TraceContext.newTimer("test4", "foo1", "bar1", "foo2", "bar2", "foo3", "bar3").close();
- TraceContext.newTimer("test5", "foo1", "bar1", "foo2", "bar2", "foo3", "bar3", "foo4", "bar4")
+ TraceContext.newTimer("test2", Metadata.builder().accountId(1000000).changeId(123).build())
.close();
- assertThat(LoggingContext.getInstance().getPerformanceLogRecords()).hasSize(5);
+ assertThat(LoggingContext.getInstance().getPerformanceLogRecords()).hasSize(2);
}
assertThat(testPerformanceLogger.logEntries())
.containsExactly(
- PerformanceLogEntry.create("test1", ImmutableMap.of()),
- PerformanceLogEntry.create("test2", ImmutableMap.of("foo", Optional.of("bar"))),
+ PerformanceLogEntry.create("test1", Metadata.empty()),
PerformanceLogEntry.create(
- "test3", ImmutableMap.of("foo1", Optional.of("bar1"), "foo2", Optional.of("bar2"))),
- PerformanceLogEntry.create(
- "test4",
- ImmutableMap.of(
- "foo1",
- Optional.of("bar1"),
- "foo2",
- Optional.of("bar2"),
- "foo3",
- Optional.of("bar3"))),
- PerformanceLogEntry.create(
- "test5",
- ImmutableMap.of(
- "foo1",
- Optional.of("bar1"),
- "foo2",
- Optional.of("bar2"),
- "foo3",
- Optional.of("bar3"),
- "foo4",
- Optional.of("bar4"))))
- .inOrder();
-
- assertThat(LoggingContext.getInstance().isPerformanceLogging()).isFalse();
- assertThat(LoggingContext.getInstance().getPerformanceLogRecords()).isEmpty();
- }
-
- @Test
- public void traceTimersInsidePerformanceLogContextCreatePerformanceLogNullValuesAllowed() {
- assertThat(LoggingContext.getInstance().isPerformanceLogging()).isFalse();
- assertThat(LoggingContext.getInstance().getPerformanceLogRecords()).isEmpty();
-
- try (PerformanceLogContext traceContext =
- new PerformanceLogContext(config, performanceLoggers)) {
- assertThat(LoggingContext.getInstance().isPerformanceLogging()).isTrue();
-
- TraceContext.newTimer("test1").close();
- TraceContext.newTimer("test2", "foo", null).close();
- TraceContext.newTimer("test3", "foo1", null, "foo2", null).close();
- TraceContext.newTimer("test4", "foo1", null, "foo2", null, "foo3", null).close();
- TraceContext.newTimer("test5", "foo1", null, "foo2", null, "foo3", null, "foo4", null)
- .close();
-
- assertThat(LoggingContext.getInstance().getPerformanceLogRecords()).hasSize(5);
- }
-
- assertThat(testPerformanceLogger.logEntries())
- .containsExactly(
- PerformanceLogEntry.create("test1", ImmutableMap.of()),
- PerformanceLogEntry.create("test2", ImmutableMap.of("foo", Optional.empty())),
- PerformanceLogEntry.create(
- "test3", ImmutableMap.of("foo1", Optional.empty(), "foo2", Optional.empty())),
- PerformanceLogEntry.create(
- "test4",
- ImmutableMap.of(
- "foo1", Optional.empty(), "foo2", Optional.empty(), "foo3", Optional.empty())),
- PerformanceLogEntry.create(
- "test5",
- ImmutableMap.of(
- "foo1",
- Optional.empty(),
- "foo2",
- Optional.empty(),
- "foo3",
- Optional.empty(),
- "foo4",
- Optional.empty())))
+ "test2", Metadata.builder().accountId(1000000).changeId(123).build()))
.inOrder();
assertThat(LoggingContext.getInstance().isPerformanceLogging()).isFalse();
@@ -173,10 +100,7 @@
assertThat(LoggingContext.getInstance().getPerformanceLogRecords()).isEmpty();
TraceContext.newTimer("test1").close();
- TraceContext.newTimer("test2", "foo", "bar").close();
- TraceContext.newTimer("test3", "foo1", "bar1", "foo2", "bar2").close();
- TraceContext.newTimer("test4", "foo1", "bar1", "foo2", "bar2", "foo3", "bar3").close();
- TraceContext.newTimer("test5", "foo1", "bar1", "foo2", "bar2", "foo3", "bar3", "foo4", "bar4")
+ TraceContext.newTimer("test2", Metadata.builder().accountId(1000000).changeId(123).build())
.close();
assertThat(LoggingContext.getInstance().isPerformanceLogging()).isFalse();
@@ -198,10 +122,7 @@
assertThat(LoggingContext.getInstance().isPerformanceLogging()).isFalse();
TraceContext.newTimer("test1").close();
- TraceContext.newTimer("test2", "foo", "bar").close();
- TraceContext.newTimer("test3", "foo1", "bar1", "foo2", "bar2").close();
- TraceContext.newTimer("test4", "foo1", "bar1", "foo2", "bar2", "foo3", "bar3").close();
- TraceContext.newTimer("test5", "foo1", "bar1", "foo2", "bar2", "foo3", "bar3", "foo4", "bar4")
+ TraceContext.newTimer("test2", Metadata.builder().accountId(1000000).changeId(123).build())
.close();
assertThat(LoggingContext.getInstance().getPerformanceLogRecords()).isEmpty();
@@ -226,50 +147,43 @@
metricMaker.newTimer("test1/latency", new Description("Latency metric for testing"));
timer0.start().close();
- Timer1<String> timer1 =
+ Timer1<Integer> timer1 =
metricMaker.newTimer(
"test2/latency",
new Description("Latency metric for testing"),
- Field.ofString("foo").build());
- timer1.start("value1").close();
+ Field.ofInteger("account", Metadata.Builder::accountId).build());
+ timer1.start(1000000).close();
- Timer2<String, String> timer2 =
+ Timer2<Integer, Integer> timer2 =
metricMaker.newTimer(
"test3/latency",
new Description("Latency metric for testing"),
- Field.ofString("foo").build(),
- Field.ofString("bar").build());
- timer2.start("value1", "value2").close();
+ Field.ofInteger("account", Metadata.Builder::accountId).build(),
+ Field.ofInteger("change", Metadata.Builder::changeId).build());
+ timer2.start(1000000, 123).close();
- Timer3<String, String, String> timer3 =
+ Timer3<Integer, Integer, String> timer3 =
metricMaker.newTimer(
"test4/latency",
new Description("Latency metric for testing"),
- Field.ofString("foo").build(),
- Field.ofString("bar").build(),
- Field.ofString("baz").build());
- timer3.start("value1", "value2", "value3").close();
+ Field.ofInteger("account", Metadata.Builder::accountId).build(),
+ Field.ofInteger("change", Metadata.Builder::changeId).build(),
+ Field.ofString("project", Metadata.Builder::projectName).build());
+ timer3.start(1000000, 123, "foo/bar").close();
assertThat(LoggingContext.getInstance().getPerformanceLogRecords()).hasSize(4);
}
assertThat(testPerformanceLogger.logEntries())
.containsExactly(
- PerformanceLogEntry.create("test1/latency", ImmutableMap.of()),
+ PerformanceLogEntry.create("test1/latency", Metadata.empty()),
PerformanceLogEntry.create(
- "test2/latency", ImmutableMap.of("foo", Optional.of("value1"))),
+ "test2/latency", Metadata.builder().accountId(1000000).build()),
PerformanceLogEntry.create(
- "test3/latency",
- ImmutableMap.of("foo", Optional.of("value1"), "bar", Optional.of("value2"))),
+ "test3/latency", Metadata.builder().accountId(1000000).changeId(123).build()),
PerformanceLogEntry.create(
"test4/latency",
- ImmutableMap.of(
- "foo",
- Optional.of("value1"),
- "bar",
- Optional.of("value2"),
- "baz",
- Optional.of("value3"))))
+ Metadata.builder().accountId(1000000).changeId(123).projectName("foo/bar").build()))
.inOrder();
assertThat(LoggingContext.getInstance().isPerformanceLogging()).isFalse();
@@ -289,24 +203,24 @@
metricMaker.newTimer(
"test1/latency",
new Description("Latency metric for testing"),
- Field.ofString("foo").build());
+ Field.ofString("project", Metadata.Builder::projectName).build());
timer1.start(null).close();
Timer2<String, String> timer2 =
metricMaker.newTimer(
"test2/latency",
new Description("Latency metric for testing"),
- Field.ofString("foo").build(),
- Field.ofString("bar").build());
+ Field.ofString("project", Metadata.Builder::projectName).build(),
+ Field.ofString("branch", Metadata.Builder::branchName).build());
timer2.start(null, null).close();
Timer3<String, String, String> timer3 =
metricMaker.newTimer(
"test3/latency",
new Description("Latency metric for testing"),
- Field.ofString("foo").build(),
- Field.ofString("bar").build(),
- Field.ofString("baz").build());
+ Field.ofString("project", Metadata.Builder::projectName).build(),
+ Field.ofString("branch", Metadata.Builder::branchName).build(),
+ Field.ofString("revision", Metadata.Builder::revision).build());
timer3.start(null, null, null).close();
assertThat(LoggingContext.getInstance().getPerformanceLogRecords()).hasSize(3);
@@ -314,13 +228,9 @@
assertThat(testPerformanceLogger.logEntries())
.containsExactly(
- PerformanceLogEntry.create("test1/latency", ImmutableMap.of("foo", Optional.empty())),
- PerformanceLogEntry.create(
- "test2/latency", ImmutableMap.of("foo", Optional.empty(), "bar", Optional.empty())),
- PerformanceLogEntry.create(
- "test3/latency",
- ImmutableMap.of(
- "foo", Optional.empty(), "bar", Optional.empty(), "baz", Optional.empty())))
+ PerformanceLogEntry.create("test1/latency", Metadata.empty()),
+ PerformanceLogEntry.create("test2/latency", Metadata.empty()),
+ PerformanceLogEntry.create("test3/latency", Metadata.empty()))
.inOrder();
assertThat(LoggingContext.getInstance().isPerformanceLogging()).isFalse();
@@ -336,29 +246,29 @@
metricMaker.newTimer("test1/latency", new Description("Latency metric for testing"));
timer0.start().close();
- Timer1<String> timer1 =
+ Timer1<Integer> timer1 =
metricMaker.newTimer(
"test2/latency",
new Description("Latency metric for testing"),
- Field.ofString("foo").build());
- timer1.start("value1").close();
+ Field.ofInteger("account", Metadata.Builder::accountId).build());
+ timer1.start(1000000).close();
- Timer2<String, String> timer2 =
+ Timer2<Integer, Integer> timer2 =
metricMaker.newTimer(
"test3/latency",
new Description("Latency metric for testing"),
- Field.ofString("foo").build(),
- Field.ofString("bar").build());
- timer2.start("value1", "value2").close();
+ Field.ofInteger("account", Metadata.Builder::accountId).build(),
+ Field.ofInteger("change", Metadata.Builder::changeId).build());
+ timer2.start(1000000, 123).close();
- Timer3<String, String, String> timer3 =
+ Timer3<Integer, Integer, String> timer3 =
metricMaker.newTimer(
"test4/latency",
new Description("Latency metric for testing"),
- Field.ofString("foo").build(),
- Field.ofString("bar").build(),
- Field.ofString("baz").build());
- timer3.start("value1", "value2", "value3").close();
+ Field.ofInteger("account", Metadata.Builder::accountId).build(),
+ Field.ofInteger("change", Metadata.Builder::changeId).build(),
+ Field.ofString("project", Metadata.Builder::projectName).build());
+ timer3.start(1000000, 123, "value3").close();
assertThat(LoggingContext.getInstance().isPerformanceLogging()).isFalse();
assertThat(LoggingContext.getInstance().getPerformanceLogRecords()).isEmpty();
@@ -382,29 +292,29 @@
metricMaker.newTimer("test1/latency", new Description("Latency metric for testing"));
timer0.start().close();
- Timer1<String> timer1 =
+ Timer1<Integer> timer1 =
metricMaker.newTimer(
"test2/latency",
new Description("Latency metric for testing"),
- Field.ofString("foo").build());
- timer1.start("value1").close();
+ Field.ofInteger("accoutn", Metadata.Builder::accountId).build());
+ timer1.start(1000000).close();
- Timer2<String, String> timer2 =
+ Timer2<Integer, Integer> timer2 =
metricMaker.newTimer(
"test3/latency",
new Description("Latency metric for testing"),
- Field.ofString("foo").build(),
- Field.ofString("bar").build());
- timer2.start("value1", "value2").close();
+ Field.ofInteger("account", Metadata.Builder::accountId).build(),
+ Field.ofInteger("change", Metadata.Builder::changeId).build());
+ timer2.start(1000000, 123).close();
- Timer3<String, String, String> timer3 =
+ Timer3<Integer, Integer, String> timer3 =
metricMaker.newTimer(
"test4/latency",
new Description("Latency metric for testing"),
- Field.ofString("foo").build(),
- Field.ofString("bar").build(),
- Field.ofString("baz").build());
- timer3.start("value1", "value2", "value3").close();
+ Field.ofInteger("account", Metadata.Builder::accountId).build(),
+ Field.ofInteger("change", Metadata.Builder::changeId).build(),
+ Field.ofString("project", Metadata.Builder::projectName).build());
+ timer3.start(1000000, 123, "foo/bar").close();
assertThat(LoggingContext.getInstance().getPerformanceLogRecords()).isEmpty();
}
@@ -450,8 +360,8 @@
private List<PerformanceLogEntry> logEntries = new ArrayList<>();
@Override
- public void log(String operation, long durationMs, Map<String, Optional<Object>> metaData) {
- logEntries.add(PerformanceLogEntry.create(operation, metaData));
+ public void log(String operation, long durationMs, Metadata metadata) {
+ logEntries.add(PerformanceLogEntry.create(operation, metadata));
}
ImmutableList<PerformanceLogEntry> logEntries() {
@@ -461,13 +371,12 @@
@AutoValue
abstract static class PerformanceLogEntry {
- static PerformanceLogEntry create(String operation, Map<String, Optional<Object>> metaData) {
- return new AutoValue_PerformanceLogContextTest_PerformanceLogEntry(
- operation, ImmutableMap.copyOf(metaData));
+ static PerformanceLogEntry create(String operation, Metadata metadata) {
+ return new AutoValue_PerformanceLogContextTest_PerformanceLogEntry(operation, metadata);
}
abstract String operation();
- abstract ImmutableMap<String, Object> metaData();
+ abstract Metadata metadata();
}
}
diff --git a/javatests/com/google/gerrit/server/logging/TraceContextTest.java b/javatests/com/google/gerrit/server/logging/TraceContextTest.java
index fedbe8b..13f2035 100644
--- a/javatests/com/google/gerrit/server/logging/TraceContextTest.java
+++ b/javatests/com/google/gerrit/server/logging/TraceContextTest.java
@@ -240,58 +240,17 @@
@Test
public void operationForTraceTimerCannotBeNull() throws Exception {
assertThrows(NullPointerException.class, () -> TraceContext.newTimer(null));
- assertThrows(NullPointerException.class, () -> TraceContext.newTimer(null, "foo", "bar"));
- assertThrows(
- NullPointerException.class,
- () -> TraceContext.newTimer(null, "foo1", "bar1", "foo2", "bar2"));
- assertThrows(
- NullPointerException.class,
- () -> TraceContext.newTimer(null, "foo1", "bar1", "foo2", "bar2", "foo3", "bar3"));
+ assertThrows(NullPointerException.class, () -> TraceContext.newTimer(null, Metadata.empty()));
assertThrows(
NullPointerException.class,
() ->
TraceContext.newTimer(
- null, "foo1", "bar1", "foo2", "bar2", "foo3", "bar3", "foo4", "bar4"));
+ null, Metadata.builder().accountId(1000000).changeId(123).build()));
}
@Test
- public void keysForTraceTimerCannotBeNull() throws Exception {
- assertThrows(NullPointerException.class, () -> TraceContext.newTimer("test", null, "bar"));
- assertThrows(
- NullPointerException.class,
- () -> TraceContext.newTimer("test", null, "bar1", "foo2", "bar2"));
- assertThrows(
- NullPointerException.class,
- () -> TraceContext.newTimer("test", "foo1", "bar1", null, "bar2"));
- assertThrows(
- NullPointerException.class,
- () -> TraceContext.newTimer("test", null, "bar1", "foo2", "bar2", "foo3", "bar3"));
- assertThrows(
- NullPointerException.class,
- () -> TraceContext.newTimer("test", "foo1", "bar1", null, "bar2", "foo3", "bar3"));
- assertThrows(
- NullPointerException.class,
- () -> TraceContext.newTimer("test", "foo1", "bar1", "foo2", "bar2", null, "bar3"));
- assertThrows(
- NullPointerException.class,
- () ->
- TraceContext.newTimer(
- "test", null, "bar1", "foo2", "bar2", "foo3", "bar3", "foo4", "bar4"));
- assertThrows(
- NullPointerException.class,
- () ->
- TraceContext.newTimer(
- "test", "foo1", "bar1", null, "bar2", "foo3", "bar3", "foo4", "bar4"));
- assertThrows(
- NullPointerException.class,
- () ->
- TraceContext.newTimer(
- "test", "foo1", "bar1", "foo2", "bar2", null, "bar3", "foo4", "bar4"));
- assertThrows(
- NullPointerException.class,
- () ->
- TraceContext.newTimer(
- "test", "foo1", "bar1", "foo2", "bar2", "foo3", "bar3", null, "bar4"));
+ public void metadataForTraceTimerCannotBeNull() throws Exception {
+ assertThrows(NullPointerException.class, () -> TraceContext.newTimer("test", null));
}
private void assertTags(ImmutableMap<String, ImmutableSet<String>> expectedTagMap) {
diff --git a/javatests/com/google/gerrit/server/mail/send/FromAddressGeneratorProviderTest.java b/javatests/com/google/gerrit/server/mail/send/FromAddressGeneratorProviderTest.java
index 128279f..0e04739 100644
--- a/javatests/com/google/gerrit/server/mail/send/FromAddressGeneratorProviderTest.java
+++ b/javatests/com/google/gerrit/server/mail/send/FromAddressGeneratorProviderTest.java
@@ -25,8 +25,6 @@
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountState;
-import com.google.gerrit.server.config.AllUsersName;
-import com.google.gerrit.server.config.AllUsersNameProvider;
import com.google.gerrit.server.util.time.TimeUtil;
import java.util.Arrays;
import java.util.List;
@@ -383,6 +381,6 @@
final Account account = new Account(userId, TimeUtil.nowTs());
account.setFullName(name);
account.setPreferredEmail(email);
- return AccountState.forAccount(new AllUsersName(AllUsersNameProvider.DEFAULT), account);
+ return AccountState.forAccount(account);
}
}
diff --git a/javatests/com/google/gerrit/server/project/ProjectConfigTest.java b/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
index 75e1cd7..aacd41b 100644
--- a/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
+++ b/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
@@ -16,7 +16,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
-import static com.google.gerrit.reviewdb.client.BooleanProjectConfig.REQUIRE_CHANGE_ID;
+import static com.google.gerrit.reviewdb.client.BooleanProjectConfig.USE_CONTRIBUTOR_AGREEMENTS;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
@@ -612,13 +612,13 @@
public void readAllProjectsBaseConfigFromSitePaths() throws Exception {
ProjectConfig cfg = factory.create(ALL_PROJECTS);
cfg.load(db);
- assertThat(cfg.getProject().getBooleanConfig(REQUIRE_CHANGE_ID))
+ assertThat(cfg.getProject().getBooleanConfig(USE_CONTRIBUTOR_AGREEMENTS))
.isEqualTo(InheritableBoolean.INHERIT);
- writeDefaultAllProjectsConfig("[receive]", "requireChangeId = false");
+ writeDefaultAllProjectsConfig("[receive]", "requireContributorAgreement = false");
cfg.load(db);
- assertThat(cfg.getProject().getBooleanConfig(REQUIRE_CHANGE_ID))
+ assertThat(cfg.getProject().getBooleanConfig(USE_CONTRIBUTOR_AGREEMENTS))
.isEqualTo(InheritableBoolean.FALSE);
}
@@ -626,17 +626,17 @@
public void readOtherProjectIgnoresAllProjectsBaseConfig() throws Exception {
ProjectConfig cfg = factory.create(Project.nameKey("test"));
cfg.load(db);
- assertThat(cfg.getProject().getBooleanConfig(REQUIRE_CHANGE_ID))
+ assertThat(cfg.getProject().getBooleanConfig(USE_CONTRIBUTOR_AGREEMENTS))
.isEqualTo(InheritableBoolean.INHERIT);
- writeDefaultAllProjectsConfig("[receive]", "requireChangeId = false");
+ writeDefaultAllProjectsConfig("[receive]", "requireContributorAgreement = false");
cfg.load(db);
// If we went through ProjectState, then this would return FALSE, since project.config for
// All-Projects would inherit from all_projects.config, and this project would inherit from
// All-Projects. But in ProjectConfig itself, there is no inheritance from All-Projects, so this
// continues to return the default.
- assertThat(cfg.getProject().getBooleanConfig(REQUIRE_CHANGE_ID))
+ assertThat(cfg.getProject().getBooleanConfig(USE_CONTRIBUTOR_AGREEMENTS))
.isEqualTo(InheritableBoolean.INHERIT);
}
diff --git a/javatests/com/google/gerrit/testing/GerritJUnitTest.java b/javatests/com/google/gerrit/testing/GerritJUnitTest.java
index 430f48f..56dda08 100644
--- a/javatests/com/google/gerrit/testing/GerritJUnitTest.java
+++ b/javatests/com/google/gerrit/testing/GerritJUnitTest.java
@@ -15,7 +15,7 @@
package com.google.gerrit.testing;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
+import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import org.junit.Test;
@@ -68,7 +68,7 @@
() -> {
throw new MyException("foo");
});
- assert_().fail("expected AssertionError");
+ assertWithMessage("expected AssertionError").fail();
} catch (AssertionError e) {
assertThat(e).hasMessageThat().contains(IllegalStateException.class.getSimpleName());
assertThat(e).hasMessageThat().contains(MyException.class.getSimpleName());
@@ -81,7 +81,7 @@
public void assertThrowsThrowsAssertionErrorWhenNothingThrown() {
try {
assertThrows(MyException.class, () -> {});
- assert_().fail("expected AssertionError");
+ assertWithMessage("expected AssertionError").fail();
} catch (AssertionError e) {
assertThat(e).hasMessageThat().contains(MyException.class.getSimpleName());
assertThat(e).hasCauseThat().isNull();
diff --git a/plugins/codemirror-editor b/plugins/codemirror-editor
index 2d3f265..56ebd4f 160000
--- a/plugins/codemirror-editor
+++ b/plugins/codemirror-editor
@@ -1 +1 @@
-Subproject commit 2d3f265ab1797d4179cbd6855c937989175d5ce5
+Subproject commit 56ebd4f7a2bf27f89aa11245ff77f7eefcf4a7d6
diff --git a/plugins/hooks b/plugins/hooks
index d285496..cfc7675 160000
--- a/plugins/hooks
+++ b/plugins/hooks
@@ -1 +1 @@
-Subproject commit d285496d44d8e49378910ea28fc8a77d4a86bf9f
+Subproject commit cfc7675ef9c4d0f2bd1da47957835306bb1fd36a
diff --git a/plugins/plugin-manager b/plugins/plugin-manager
index a51055a..f681e7e 160000
--- a/plugins/plugin-manager
+++ b/plugins/plugin-manager
@@ -1 +1 @@
-Subproject commit a51055a8f3b71f2ccf634016c42eb5b8086a373b
+Subproject commit f681e7ecb6ddbc52fe9e07cf3672ccdcad7d7d0b
diff --git a/plugins/replication b/plugins/replication
index c449ba1..a5a5e0c 160000
--- a/plugins/replication
+++ b/plugins/replication
@@ -1 +1 @@
-Subproject commit c449ba153358150927cb8d88e77f2b3d60d63ecc
+Subproject commit a5a5e0cd13f1ff2614d77e9bf1bacbbc1d61b696
diff --git a/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior.html b/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior.html
index 0e5be3f..4252e6e 100644
--- a/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior.html
+++ b/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior.html
@@ -129,8 +129,8 @@
return this.getBaseUrl() + '/c/' + changeNum;
},
- changeIsOpen(status) {
- return status === this.ChangeStatus.NEW;
+ changeIsOpen(change) {
+ return change && change.status === this.ChangeStatus.NEW;
},
/**
diff --git a/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log.html b/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log.html
index 071beda..08131ab 100644
--- a/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log.html
+++ b/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log.html
@@ -43,33 +43,34 @@
<tr id="loading" class$="loadingMsg [[computeLoadingClass(_loading)]]">
<td>Loading...</td>
</tr>
- <template is="dom-repeat" items="[[_auditLog]]"
- class$="[[computeLoadingClass(_loading)]]">
- <tr class="table">
- <td class="date">
- <gr-date-formatter
- has-tooltip
- date-str="[[item.date]]">
- </gr-date-formatter>
- </td>
- <td class="type">[[itemType(item.type)]]</td>
- <td class="member">
- <template is="dom-if" if="[[_isGroupEvent(item.type)]]">
- <a href$="[[_computeGroupUrl(item.member)]]">
- [[_getNameForGroup(item.member)]]
- </a>
- </template>
- <template is="dom-if" if="[[!_isGroupEvent(item.type)]]">
- <gr-account-link account="[[item.member]]"></gr-account-link>
- [[_getIdForUser(item.member)]]
- </template>
- </td>
- <td class="by-user">
- <gr-account-link account="[[item.user]]"></gr-account-link>
- [[_getIdForUser(item.user)]]
- </td>
- </tr>
- </template>
+ <tbody class$="[[computeLoadingClass(_loading)]]">
+ <template is="dom-repeat" items="[[_auditLog]]">
+ <tr class="table">
+ <td class="date">
+ <gr-date-formatter
+ has-tooltip
+ date-str="[[item.date]]">
+ </gr-date-formatter>
+ </td>
+ <td class="type">[[itemType(item.type)]]</td>
+ <td class="member">
+ <template is="dom-if" if="[[_isGroupEvent(item.type)]]">
+ <a href$="[[_computeGroupUrl(item.member)]]">
+ [[_getNameForGroup(item.member)]]
+ </a>
+ </template>
+ <template is="dom-if" if="[[!_isGroupEvent(item.type)]]">
+ <gr-account-link account="[[item.member]]"></gr-account-link>
+ [[_getIdForUser(item.member)]]
+ </template>
+ </td>
+ <td class="by-user">
+ <gr-account-link account="[[item.user]]"></gr-account-link>
+ [[_getIdForUser(item.user)]]
+ </td>
+ </tr>
+ </template>
+ </tbody>
</table>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
</template>
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list.html b/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list.html
index 1c02b3c..e284201 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list.html
@@ -128,9 +128,8 @@
bind-value="{{_revisedRef}}"
class="editItem">
<input
- is=iron-input
- bind-value="{{_revisedRef}}"
- class="editItem">
+ is="iron-input"
+ bind-value="{{_revisedRef}}">
</iron-input>
<gr-button
link
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config.html b/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config.html
index 872d282..e17409e 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config.html
@@ -88,7 +88,7 @@
</template>
<template is="dom-if" if="[[_isString(option.info.type)]]">
<iron-input
- value="[[option.info.value]]"
+ bind-value="[[option.info.value]]"
on-input="_handleStringChange"
data-option-key$="[[option._key]]"
disabled$="[[_computeDisabled(option.info.editable)]]">
diff --git a/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.html b/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.html
index 05fb221..044e1fe 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.html
@@ -154,21 +154,6 @@
</gr-select>
</span>
</section>
- <section>
- <span class="title">Require Change-Id in commit message</span>
- <span class="value">
- <gr-select
- id="requireChangeIdSelect"
- bind-value="{{_repoConfig.require_change_id.configured_value}}">
- <select disabled$="[[_readOnly]]">
- <template is="dom-repeat"
- items="[[_formatBooleanSelect(_repoConfig.require_change_id)]]">
- <option value="[[item.value]]">[[item.label]]</option>
- </template>
- </select>
- </gr-select>
- </span>
- </section>
<section
id="enableSignedPushSettings"
class$="repositorySettings [[_computeRepositoriesClass(_repoConfig.enable_signed_push)]]">
@@ -271,6 +256,7 @@
<span class="title">Maximum Git object size limit</span>
<span class="value">
<iron-input
+ id="maxGitObjSizeIronInput"
bind-value="{{_repoConfig.max_object_size_limit.configured_value}}"
type="text"
disabled$="[[_readOnly]]">
diff --git a/polygerrit-ui/app/elements/admin/gr-repo/gr-repo_test.html b/polygerrit-ui/app/elements/admin/gr-repo/gr-repo_test.html
index 0ac1834..744ef42 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo/gr-repo_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo/gr-repo_test.html
@@ -57,10 +57,6 @@
value: false,
configured_value: 'FALSE',
},
- require_change_id: {
- value: false,
- configured_value: 'FALSE',
- },
enable_signed_push: {
value: false,
configured_value: 'FALSE',
@@ -322,7 +318,6 @@
use_content_merge: 'TRUE',
use_signed_off_by: 'TRUE',
create_new_change_for_all_not_in_target: 'TRUE',
- require_change_id: 'TRUE',
enable_signed_push: 'TRUE',
require_signed_push: 'TRUE',
reject_implicit_merges: 'TRUE',
@@ -352,8 +347,6 @@
configInputObj.use_content_merge;
element.$.newChangeSelect.bindValue =
configInputObj.create_new_change_for_all_not_in_target;
- element.$.requireChangeIdSelect.bindValue =
- configInputObj.require_change_id;
element.$.enableSignedPush.bindValue =
configInputObj.enable_signed_push;
element.$.requireSignedPush.bindValue =
@@ -364,8 +357,9 @@
configInputObj.private_by_default;
element.$.matchAuthoredDateWithCommitterDateSelect.bindValue =
configInputObj.match_author_to_committer_date;
- element.$.maxGitObjSizeInput.bindValue =
- configInputObj.max_object_size_limit;
+ const inputElement = Polymer.Element ?
+ element.$.maxGitObjSizeIronInput : element.$.maxGitObjSizeInput;
+ inputElement.bindValue = configInputObj.max_object_size_limit;
element.$.contributorAgreementSelect.bindValue =
configInputObj.use_contributor_agreements;
element.$.useSignedOffBySelect.bindValue =
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
index 7d4dc5a..1f0da2b 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
@@ -40,11 +40,6 @@
type: String,
computed: '_computeChangeURL(change)',
},
- needsReview: {
- type: Boolean,
- reflectToAttribute: true,
- computed: '_computeItemNeedsReview(change.reviewed)',
- },
statuses: {
type: Array,
computed: 'changeStatuses(change)',
@@ -78,10 +73,6 @@
});
},
- _computeItemNeedsReview(reviewed) {
- return reviewed === false;
- },
-
_computeChangeURL(change) {
return Gerrit.Nav.getUrlForChange(change);
},
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html
index 1d76df2..df4a442 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html
@@ -274,11 +274,5 @@
assert.equal(element._computeRepoDisplay(change, true),
'…/test/repo');
});
-
- test('_computeItemNeedsReview', () => {
- assert.isFalse(element._computeItemNeedsReview(undefined));
- assert.isFalse(element._computeItemNeedsReview(true));
- assert.isTrue(element._computeItemNeedsReview(false));
- });
});
</script>
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js
index d2b17a3..57d6f8a 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js
@@ -236,9 +236,9 @@
},
_computeItemNeedsReview(account, change, showReviewedState) {
- return showReviewedState && change.reviewed === false &&
+ return showReviewedState && !change.reviewed &&
!change.work_in_progress &&
- this.changeIsOpen(change.status) &&
+ this.changeIsOpen(change) &&
(!account || account._account_id != change.owner._account_id);
},
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
index 650ebeb..dce2a55 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
@@ -221,38 +221,29 @@
{
_number: 1,
status: 'NEW',
- reviewed: false,
owner: {_account_id: 0},
},
{
_number: 2,
status: 'MERGED',
- reviewed: false,
owner: {_account_id: 0},
},
{
_number: 3,
status: 'ABANDONED',
- reviewed: false,
owner: {_account_id: 0},
},
{
_number: 4,
status: 'NEW',
- reviewed: false,
work_in_progress: true,
owner: {_account_id: 0},
},
- {
- _number: 5,
- status: 'NEW',
- owner: {_account_id: 0},
- },
];
flushAsynchronousOperations();
let elementItems = Polymer.dom(element.root).querySelectorAll(
'gr-change-list-item');
- assert.equal(elementItems.length, 6);
+ assert.equal(elementItems.length, 5);
for (let i = 0; i < elementItems.length; i++) {
assert.isFalse(elementItems[i].hasAttribute('needs-review'));
}
@@ -260,24 +251,22 @@
element.showReviewedState = true;
elementItems = Polymer.dom(element.root).querySelectorAll(
'gr-change-list-item');
- assert.equal(elementItems.length, 6);
+ assert.equal(elementItems.length, 5);
assert.isFalse(elementItems[0].hasAttribute('needs-review'));
assert.isTrue(elementItems[1].hasAttribute('needs-review'));
assert.isFalse(elementItems[2].hasAttribute('needs-review'));
assert.isFalse(elementItems[3].hasAttribute('needs-review'));
assert.isFalse(elementItems[4].hasAttribute('needs-review'));
- assert.isFalse(elementItems[5].hasAttribute('needs-review'));
element.account = {_account_id: 42};
elementItems = Polymer.dom(element.root).querySelectorAll(
'gr-change-list-item');
- assert.equal(elementItems.length, 6);
+ assert.equal(elementItems.length, 5);
assert.isFalse(elementItems[0].hasAttribute('needs-review'));
assert.isTrue(elementItems[1].hasAttribute('needs-review'));
assert.isFalse(elementItems[2].hasAttribute('needs-review'));
assert.isFalse(elementItems[3].hasAttribute('needs-review'));
assert.isFalse(elementItems[4].hasAttribute('needs-review'));
- assert.isFalse(elementItems[5].hasAttribute('needs-review'));
});
test('no changes', () => {
diff --git a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
index d7ad0f4..608aaf7 100644
--- a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
+++ b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
@@ -249,7 +249,7 @@
if (!draftSection || !draftSection.results.length) { return; }
const closedChanges = draftSection.results
- .filter(change => !this.changeIsOpen(change.status));
+ .filter(change => !this.changeIsOpen(change));
if (!closedChanges.length) { return; }
this._showDraftsBanner = true;
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
index ca0aa16..83a454b 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
@@ -592,7 +592,7 @@
if (editPatchsetLoaded) {
// Only show actions that mutate an edit if an actual edit patch set
// is loaded.
- if (this.changeIsOpen(this.change.status)) {
+ if (this.changeIsOpen(this.change)) {
if (editBasedOnCurrentPatchSet) {
if (!this.actions.publishEdit) {
this.set('actions.publishEdit', PUBLISH_EDIT);
@@ -614,7 +614,7 @@
this._deleteAndNotify('deleteEdit');
}
- if (this.changeIsOpen(this.change.status)) {
+ if (this.changeIsOpen(this.change)) {
// Only show edit button if there is no edit patchset loaded and the
// file list is not in edit mode.
if (editPatchsetLoaded || editMode) {
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
index 34e21b3..154fc36 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
@@ -177,7 +177,7 @@
},
_computeHideStrategy(change) {
- return !this.changeIsOpen(change.status);
+ return !this.changeIsOpen(change);
},
/**
@@ -222,12 +222,14 @@
},
_showAddTopic(changeRecord, settingTopic) {
- const hasTopic = !!changeRecord && !!changeRecord.base.topic;
+ const hasTopic = !!changeRecord &&
+ !!changeRecord.base && !!changeRecord.base.topic;
return !hasTopic && !settingTopic;
},
_showTopicChip(changeRecord, settingTopic) {
- const hasTopic = !!changeRecord && !!changeRecord.base.topic;
+ const hasTopic = !!changeRecord &&
+ !!changeRecord.base && !!changeRecord.base.topic;
return hasTopic && !settingTopic;
},
@@ -406,7 +408,7 @@
* @return {Object|null} either an accound or null.
*/
_getNonOwnerRole(change, role) {
- if (!change.current_revision ||
+ if (!change || !change.current_revision ||
!change.revisions[change.current_revision]) {
return null;
}
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
index 9d2710b2..db41da0 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
@@ -817,7 +817,7 @@
_computeFiles(filesByPath, changeComments, patchRange, reviewed, loading) {
// Await all promises resolving from reload. @See Issue 9057
- if (loading) { return; }
+ if (loading || !changeComments) { return; }
const commentedPaths = changeComments.getPaths(patchRange);
const files = Object.assign({}, filesByPath);
diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js
index 8a8b6b3..07bf139 100644
--- a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js
+++ b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js
@@ -121,7 +121,7 @@
];
// Get conflicts if change is open and is mergeable.
- if (this.changeIsOpen(this.change.status) && this.mergeable) {
+ if (this.changeIsOpen(this.change) && this.mergeable) {
promises.push(this._getConflicts().then(response => {
// Because the server doesn't always return a response and the
// template expects an array, always return an array.
@@ -315,6 +315,7 @@
_computeConnectedRevisions(change, patchNum, relatedChanges) {
const connected = [];
let changeRevision;
+ if (!change) { return []; }
for (const rev in change.revisions) {
if (this.patchNumEquals(change.revisions[rev]._number, patchNum)) {
changeRevision = rev;
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
index 264639d..cd93a2c 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
@@ -571,31 +571,31 @@
//
this.disabled = false;
- if (response.status !== 400) {
- // This is all restAPI does when there is no custom error handling.
- this.fire('server-error', {response});
- return response;
- }
-
- // Process the response body, format a better error message, and fire
- // an event for gr-event-manager to display.
- const jsonPromise = this.$.restAPI.getResponseObject(response);
+ // Using response.clone() here, because getResponseObject() and
+ // potentially the generic error handler will want to call text() on the
+ // response object, which can only be done once per object.
+ const jsonPromise = this.$.restAPI.getResponseObject(response.clone());
return jsonPromise.then(result => {
- const errors = [];
- for (const state of ['reviewers', 'ccs']) {
- if (!result.hasOwnProperty(state)) { continue; }
- for (const reviewer of Object.values(result[state])) {
- if (reviewer.error) {
- errors.push(reviewer.error);
+ // Only perform custom error handling for 400s and a parseable
+ // ReviewResult response.
+ if (response.status === 400 && result) {
+ const errors = [];
+ for (const state of ['reviewers', 'ccs']) {
+ if (!result.hasOwnProperty(state)) { continue; }
+ for (const reviewer of Object.values(result[state])) {
+ if (reviewer.error) {
+ errors.push(reviewer.error);
+ }
}
}
+ response = {
+ ok: false,
+ status: response.status,
+ text() { return Promise.resolve(errors.join(', ')); },
+ };
}
- response = {
- ok: false,
- status: response.status,
- text() { return Promise.resolve(errors.join(', ')); },
- };
this.fire('server-error', {response});
+ return null; // Means that the error has been handled.
});
},
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
index c36b572..e137eef 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
@@ -35,6 +35,25 @@
</test-fixture>
<script>
+ function cloneableResponse(status, text) {
+ return {
+ ok: false,
+ status,
+ text() {
+ return Promise.resolve(text);
+ },
+ clone() {
+ return {
+ ok: false,
+ status,
+ text() {
+ return Promise.resolve(text);
+ },
+ };
+ },
+ };
+ }
+
suite('gr-reply-dialog tests', () => {
let element;
let changeNum;
@@ -473,11 +492,7 @@
sandbox.stub(window, 'fetch', () => {
const text = '....{"reviewers":{"id1":{"error":"first error"}},' +
'"ccs":{"id2":{"error":"second error"}}}';
- return Promise.resolve({
- ok: false,
- status: 400,
- text() { return Promise.resolve(text); },
- });
+ return Promise.resolve(cloneableResponse(400, text));
});
element.addEventListener('server-error', event => {
@@ -495,6 +510,27 @@
flush(() => { element.send(); });
});
+ test('non-json 400 is treated as a normal server-error', done => {
+ sandbox.stub(window, 'fetch', () => {
+ const text = 'Comment validation error!';
+ return Promise.resolve(cloneableResponse(400, text));
+ });
+
+ element.addEventListener('server-error', event => {
+ if (event.target !== element) {
+ return;
+ }
+ event.detail.response.text().then(body => {
+ assert.equal(body, 'Comment validation error!');
+ done();
+ });
+ });
+
+ // Async tick is needed because iron-selector content is distributed and
+ // distributed content requires an observer to be set up.
+ flush(() => { element.send(); });
+ });
+
test('filterReviewerSuggestion', () => {
const owner = makeAccount();
const reviewer1 = makeAccount();
@@ -803,60 +839,50 @@
const error1 = 'error 1';
const error2 = 'error 2';
const error3 = 'error 3';
- const response = {
- status: 400,
- text() {
- return Promise.resolve(')]}\'' + JSON.stringify({
- reviewers: {
- username1: {
- input: 'user 1',
- error: error1,
- },
- username2: {
- input: 'user 2',
- error: error2,
- },
- },
- ccs: {
- username3: {
- input: 'user 3',
- error: error3,
- },
- },
- }));
+ const text = ')]}\'' + JSON.stringify({
+ reviewers: {
+ username1: {
+ input: 'user 1',
+ error: error1,
+ },
+ username2: {
+ input: 'user 2',
+ error: error2,
+ },
},
- };
+ ccs: {
+ username3: {
+ input: 'user 3',
+ error: error3,
+ },
+ },
+ });
element.addEventListener('server-error', e => {
e.detail.response.text().then(text => {
assert.equal(text, [error1, error2, error3].join(', '));
done();
});
});
- element._handle400Error(response);
+ element._handle400Error(cloneableResponse(400, text));
});
test('_handle400Error CCs only', done => {
const error1 = 'error 1';
- const response = {
- status: 400,
- text() {
- return Promise.resolve(')]}\'' + JSON.stringify({
- ccs: {
- username1: {
- input: 'user 1',
- error: error1,
- },
- },
- }));
+ const text = ')]}\'' + JSON.stringify({
+ ccs: {
+ username1: {
+ input: 'user 1',
+ error: error1,
+ },
},
- };
+ });
element.addEventListener('server-error', e => {
e.detail.response.text().then(text => {
assert.equal(text, error1);
done();
});
});
- element._handle400Error(response);
+ element._handle400Error(cloneableResponse(400, text));
});
test('fires height change when the drafts load', done => {
diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html
index babf886..37cb317 100644
--- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html
+++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html
@@ -195,6 +195,9 @@
</template>
</ul>
<div class="rightItems">
+ <gr-endpoint-decorator
+ class="hideOnMobile"
+ name="header-small-banner"></gr-endpoint-decorator>
<gr-smart-search
id="search"
search-query="{{searchQuery}}"></gr-smart-search>
diff --git a/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.js b/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.js
index 83f68a1..f247156 100644
--- a/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.js
+++ b/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.js
@@ -201,8 +201,11 @@
if (type === ERROR.TYPE && category === ERROR.CATEGORY) {
console.error(eventValue.error || eventName);
} else {
- console.log(eventName + (eventValue !== undefined ?
- (': ' + eventValue) : ''));
+ if (eventValue !== undefined) {
+ console.log(`Reporting: ${eventName}: ${eventValue}`);
+ } else {
+ console.log(`Reporting: ${eventName}`);
+ }
}
},
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.js b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
index b1c7fd8..4d70bdc 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router.js
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
@@ -197,7 +197,9 @@
const reporting = document.createElement('gr-reporting');
window.addEventListener('load', () => {
- reporting.pageLoaded();
+ setTimeout(() => {
+ reporting.pageLoaded();
+ }, 0);
});
window.addEventListener('WebComponentsReady', () => {
@@ -1116,11 +1118,16 @@
},
_handleProjectsOldRoute(data) {
+ let params = '';
if (data.params[1]) {
- this._redirect('/admin/repos/' + encodeURIComponent(data.params[1]));
- } else {
- this._redirect('/admin/repos');
+ params = encodeURIComponent(data.params[1]);
+ if (data.params[1].includes(',')) {
+ params =
+ encodeURIComponent(data.params[1]).replace('%2C', ',');
+ }
}
+
+ this._redirect(`/admin/repos/${params}`);
},
_handleRepoCommandsRoute(data) {
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
index 90d65137..27016e8 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
@@ -1108,6 +1108,28 @@
});
suite('repo routes', () => {
+ test('_handleProjectsOldRoute', () => {
+ const data = {params: {}};
+ element._handleProjectsOldRoute(data);
+ assert.isTrue(redirectStub.calledOnce);
+ assert.equal(redirectStub.lastCall.args[0], '/admin/repos/');
+ });
+
+ test('_handleProjectsOldRoute test', () => {
+ const data = {params: {1: 'test'}};
+ element._handleProjectsOldRoute(data);
+ assert.isTrue(redirectStub.calledOnce);
+ assert.equal(redirectStub.lastCall.args[0], '/admin/repos/test');
+ });
+
+ test('_handleProjectsOldRoute test,branches', () => {
+ const data = {params: {1: 'test,branches'}};
+ element._handleProjectsOldRoute(data);
+ assert.isTrue(redirectStub.calledOnce);
+ assert.equal(
+ redirectStub.lastCall.args[0], '/admin/repos/test,branches');
+ });
+
test('_handleRepoRoute', () => {
const data = {params: {0: 4321}};
assertDataToParams(data, '_handleRepoRoute', {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html
index 4ec460f..6ac6714 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html
@@ -35,7 +35,12 @@
:host(.no-left) .sideBySide ::content .right:not([data-value]) + td {
display: none;
}
- .thread-group, ::slotted(*) .thread-group {
+ ::slotted(*) .thread-group {
+ display: block;
+ max-width: var(--content-width, 80ch);
+ white-space: normal;
+ }
+ .thread-group {
display: block;
max-width: var(--content-width, 80ch);
white-space: normal;
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js
index d2f9214..633e081 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js
@@ -86,6 +86,9 @@
* implements the same behavior as the template parsing for imperative slots.
*/
Gerrit.slotToContent = function(slot) {
+ if (Polymer.Element) {
+ return slot;
+ }
const content = document.createElement('content');
content.name = slot.name;
content.setAttribute('select', `[slot='${slot.name}']`);
diff --git a/polygerrit-ui/app/elements/gr-app-element.html b/polygerrit-ui/app/elements/gr-app-element.html
index af4d799..aff71f7 100644
--- a/polygerrit-ui/app/elements/gr-app-element.html
+++ b/polygerrit-ui/app/elements/gr-app-element.html
@@ -72,10 +72,6 @@
padding: 0 var(--default-horizontal-margin);
border-bottom: 1px solid var(--border-color);
}
- gr-main-header.shadow {
- /* Make it obvious for shadow dom testing */
- border-bottom: 1px solid pink;
- }
footer {
background-color: var(--footer-background-color);
border-top: 1px solid var(--border-color);
@@ -125,7 +121,6 @@
<gr-main-header
id="mainHeader"
search-query="{{params.query}}"
- class$="[[_computeShadowClass(_isShadowDom)]]"
on-mobile-search="_mobileSearchToggle">
</gr-main-header>
</gr-fixed-panel>
@@ -191,7 +186,7 @@
<div class="errorMoreInfo">[[_lastError.moreInfo]]</div>
</div>
</main>
- <footer r="contentinfo" class$="[[_computeShadowClass(_isShadowDom)]]">
+ <footer r="contentinfo">
<div>
Powered by <a href="https://www.gerritcodereview.com/" rel="noopener"
target="_blank">Gerrit Code Review</a>
@@ -201,7 +196,7 @@
<div>
<a class="feedback"
href$="[[_feedbackUrl]]"
- rel="noopener" target="_blank">Send feedback</a>
+ rel="noopener" target="_blank">Report bug</a>
| Press “?” for keyboard shortcuts
<gr-endpoint-decorator name="footer-right"></gr-endpoint-decorator>
</div>
diff --git a/polygerrit-ui/app/elements/gr-app-element.js b/polygerrit-ui/app/elements/gr-app-element.js
index 75abc3a..4d556ae 100644
--- a/polygerrit-ui/app/elements/gr-app-element.js
+++ b/polygerrit-ui/app/elements/gr-app-element.js
@@ -73,7 +73,6 @@
_lastError: Object,
_lastSearchPage: String,
_path: String,
- _isShadowDom: Boolean,
_pluginScreenName: {
type: String,
computed: '_computePluginScreenName(params)',
@@ -122,7 +121,7 @@
},
ready() {
- this._isShadowDom = Polymer.Settings.useShadow;
+ this.$.reporting.appStarted(document.visibilityState === 'hidden');
this.$.router.start();
this.$.restAPI.getAccount().then(account => {
@@ -150,8 +149,6 @@
// router has been initialized. @see Issue 7837
this._settingsUrl = Gerrit.Nav.getUrlForSettings();
- this.$.reporting.appStarted(document.visibilityState === 'hidden');
-
this._viewState = {
changeView: {
changeNum: null,
@@ -404,10 +401,6 @@
this.$.registrationOverlay.close();
},
- _computeShadowClass(isShadowDom) {
- return isShadowDom ? 'shadow' : '';
- },
-
_goToOpenedChanges() {
Gerrit.Nav.navigateToStatusSearch('open');
},
@@ -431,8 +424,6 @@
if (window.VERSION_INFO) {
console.log(`UI Version Info: ${window.VERSION_INFO}`);
}
- const renderTime = new Date(window.performance.timing.loadEventStart);
- console.log(`Document loaded at: ${renderTime}`);
console.log(`Please file bugs and feedback at: ${this._feedbackUrl}`);
console.groupEnd();
},
diff --git a/polygerrit-ui/app/elements/gr-app-p2.html b/polygerrit-ui/app/elements/gr-app-p2.html
index 5742350..dbac7fe 100644
--- a/polygerrit-ui/app/elements/gr-app-p2.html
+++ b/polygerrit-ui/app/elements/gr-app-p2.html
@@ -19,7 +19,7 @@
</script>
<link rel="import" href="/bower_components/polymer/polymer.html">
-<link rel="import" href="/bower_components/polymer-resin/polymer-resin.html">
+<link rel="import" href="/bower_components/polymer-resin/standalone/polymer-resin.html">
<link rel="import" href="/bower_components/polymer/lib/legacy/legacy-data-mixin.html">
<link rel="import" href="../behaviors/safe-types-behavior/safe-types-behavior.html">
<script>
diff --git a/polygerrit-ui/app/elements/gr-app_test.html b/polygerrit-ui/app/elements/gr-app_test.html
index f934cff..73d012a 100644
--- a/polygerrit-ui/app/elements/gr-app_test.html
+++ b/polygerrit-ui/app/elements/gr-app_test.html
@@ -47,12 +47,18 @@
stub('gr-account-dropdown', {
_getTopContent: sinon.stub(),
});
+ stub('gr-router', {
+ start: sandbox.stub(),
+ });
stub('gr-rest-api-interface', {
getAccount() { return Promise.resolve({}); },
getAccountCapabilities() { return Promise.resolve({}); },
getConfig() {
return Promise.resolve({
plugin: {},
+ auth: {
+ auth_type: undefined,
+ },
});
},
getPreferences() { return Promise.resolve({my: []}); },
@@ -78,6 +84,13 @@
assert.isTrue(appElement().$.reporting.appStarted.calledOnce);
});
+ test('reporting called before router start', () => {
+ const element = appElement();
+ const appStartedStub = element.$.reporting.appStarted;
+ const routerStartStub = element.$.router.start;
+ sinon.assert.callOrder(appStartedStub, routerStartStub);
+ });
+
test('passes config to gr-plugin-host', () => {
const config = appElement().$.restAPI.getConfig;
return config.lastCall.returnValue.then(config => {
diff --git a/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style.js b/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style.js
index 16a2a35..e8b7212 100644
--- a/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style.js
+++ b/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style.js
@@ -47,9 +47,16 @@
_applyStyle(name) {
if (this._stylesApplied.includes(name)) { return; }
this._stylesApplied.push(name);
+ // Hybrid custom-style syntax:
+ // https://polymer-library.polymer-project.org/2.0/docs/devguide/style-shadow-dom
const s = document.createElement('style', 'custom-style');
s.setAttribute('include', name);
- Polymer.dom(this.root).appendChild(s);
+ const cs = document.createElement('custom-style');
+ cs.appendChild(s);
+ // When using Shadow DOM <custom-style> must be added to the <body>.
+ // Within <gr-external-style> itself the styles would have no effect.
+ const topEl = document.getElementsByTagName('body')[0];
+ topEl.insertBefore(cs, topEl.firstChild);
},
_importAndApply() {
diff --git a/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.html b/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.html
index 8de8db8..3403d0d 100644
--- a/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.html
+++ b/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.html
@@ -34,7 +34,7 @@
margin-right: .15em;
vertical-align: -.25em;
}
- .hide {
+ div section.hide {
display: none;
}
</style>
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown.html b/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown.html
index 383d129..64758ca 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown.html
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown.html
@@ -19,6 +19,7 @@
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
<link rel="import" href="/bower_components/iron-dropdown/iron-dropdown.html">
+<link rel="import" href="/bower_components/iron-fit-behavior/iron-fit-behavior.html">
<link rel="import" href="../../shared/gr-cursor-manager/gr-cursor-manager.html">
<script src="../../../scripts/rootElement.js"></script>
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js
index 11c9864..e422b7e 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js
@@ -528,7 +528,11 @@
// HTML import polyfill adds __importElement pointing to the import tag.
const script = document.currentScript &&
(document.currentScript.__importElement || document.currentScript);
- const src = opt_src || (script && (script.src || script.baseURI));
+
+ let src = opt_src || (script && script.src);
+ if (!src || src.startsWith('data:')) {
+ src = script && script.baseURI;
+ }
const name = getPluginNameFromUrl(src);
if (opt_version && opt_version !== API_VERSION) {
diff --git a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
index 74bd895..1f9615f 100644
--- a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
+++ b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
@@ -96,10 +96,8 @@
{/if}
{if $polymer2}
- <link rel="preload" href="{$staticResourcePath}/elements/gr-app-p2.js" as="script" crossorigin="anonymous">{\n}
<link rel="import" href="{$staticResourcePath}/elements/gr-app-p2.html">{\n}
{else}
- <link rel="preload" href="{$staticResourcePath}/elements/gr-app.js" as="script" crossorigin="anonymous">{\n}
<link rel="import" href="{$staticResourcePath}/elements/gr-app.html">{\n}
{/if}
diff --git a/resources/com/google/gerrit/pgm/init/gerrit.sh b/resources/com/google/gerrit/pgm/init/gerrit.sh
index 23f86ee..d92ec51 100755
--- a/resources/com/google/gerrit/pgm/init/gerrit.sh
+++ b/resources/com/google/gerrit/pgm/init/gerrit.sh
@@ -63,7 +63,7 @@
running() {
test -f $1 || return 1
PID=`cat $1`
- ps -p $PID >/dev/null 2>/dev/null || return 1
+ ps ax -o pid | grep -w $PID >/dev/null 2>/dev/null || return 1
return 0
}
diff --git a/resources/com/google/gerrit/server/mail/Merged.soy b/resources/com/google/gerrit/server/mail/Merged.soy
index 04d54c4..899d1c0 100644
--- a/resources/com/google/gerrit/server/mail/Merged.soy
+++ b/resources/com/google/gerrit/server/mail/Merged.soy
@@ -25,7 +25,7 @@
{@param change: ?}
{@param email: ?}
{@param fromName: ?}
- {$fromName} has submitted this change and it was merged.
+ {$fromName} has submitted this change.
{if $email.changeUrl} ( {$email.changeUrl} ){/if}{\n}
{\n}
Change subject: {$change.subject}{\n}
diff --git a/resources/com/google/gerrit/server/mail/MergedHtml.soy b/resources/com/google/gerrit/server/mail/MergedHtml.soy
index e8c04a5..f0a47c7 100644
--- a/resources/com/google/gerrit/server/mail/MergedHtml.soy
+++ b/resources/com/google/gerrit/server/mail/MergedHtml.soy
@@ -21,7 +21,7 @@
{@param email: ?}
{@param fromName: ?}
<p>
- {$fromName} <strong>merged</strong> this change.
+ {$fromName} <strong>submitted</strong> this change.
</p>
{if $email.changeUrl}
diff --git a/tools/bzl/js.bzl b/tools/bzl/js.bzl
index 188a2a1..0408b2b 100644
--- a/tools/bzl/js.bzl
+++ b/tools/bzl/js.bzl
@@ -81,7 +81,7 @@
out = ctx.execute(cmd)
if out.return_code:
- fail("failed %s: %s" % (" ".join(cmd), out.stderr))
+ fail("failed %s: %s" % (cmd, out.stderr))
_bash(ctx, " && ".join([
"TMP=$(mktemp -d || mktemp -d -t bazel-tmp)",
@@ -117,7 +117,7 @@
cmd_list = ["bash", "-c", cmd]
out = ctx.execute(cmd_list)
if out.return_code:
- fail("failed %s: %s" % (" ".join(cmd_list), out.stderr))
+ fail("failed %s: %s" % (cmd_list, out.stderr))
bower_archive = repository_rule(
_bower_archive,