Merge branch 'stable-2.16'

* stable-2.16:
  AccountApi: Add method to set account name
  Silence non-critical messages from JGit in tests
  Silence non-critical messages from Jetty in tests
  ReceiveCommits: Fix setting [PRIVATE] and [WIP] for updated changes
  ElasticContainer: Use 6.5.3 for V6_5 tests
  Upgrade elasticsearch-rest-client to 6.5.3

Change-Id: I5485e3f3be46cc7fc049974b6a4d7a4ca7aa81a5
diff --git a/WORKSPACE b/WORKSPACE
index 9e51fcd..2325001 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1016,8 +1016,8 @@
 # and httpasyncclient as necessary.
 maven_jar(
     name = "elasticsearch-rest-client",
-    artifact = "org.elasticsearch.client:elasticsearch-rest-client:6.5.2",
-    sha1 = "6ad0dd15affe56be7dfe638fe317bc5f7456b730",
+    artifact = "org.elasticsearch.client:elasticsearch-rest-client:6.5.3",
+    sha1 = "ac8df46fce1c01b61cbf1f84186bf910d12b577e",
 )
 
 JACKSON_VERSION = "2.9.7"
diff --git a/java/com/google/gerrit/acceptance/GerritServer.java b/java/com/google/gerrit/acceptance/GerritServer.java
index 077dd65..6f54e84 100644
--- a/java/com/google/gerrit/acceptance/GerritServer.java
+++ b/java/com/google/gerrit/acceptance/GerritServer.java
@@ -226,6 +226,10 @@
 
           // Silence non-critical messages from Jetty.
           .put("org.eclipse.jetty", Level.WARN)
+
+          // Silence non-critical messages from JGit.
+          .put("org.eclipse.jgit.transport.PacketLineIn", Level.WARN)
+          .put("org.eclipse.jgit.transport.PacketLineOut", Level.WARN)
           .build();
 
   private static boolean forceLocalDisk() {
diff --git a/java/com/google/gerrit/extensions/api/accounts/AccountApi.java b/java/com/google/gerrit/extensions/api/accounts/AccountApi.java
index b7fce5f..056565e 100644
--- a/java/com/google/gerrit/extensions/api/accounts/AccountApi.java
+++ b/java/com/google/gerrit/extensions/api/accounts/AccountApi.java
@@ -112,6 +112,8 @@
   List<DeletedDraftCommentInfo> deleteDraftComments(DeleteDraftCommentsInput input)
       throws RestApiException;
 
+  void setName(String name) throws RestApiException;
+
   /**
    * A default implementation which allows source compatibility when adding new methods to the
    * interface.
@@ -310,5 +312,10 @@
         throws RestApiException {
       throw new NotImplementedException();
     }
+
+    @Override
+    public void setName(String name) throws RestApiException {
+      throw new NotImplementedException();
+    }
   }
 }
diff --git a/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java b/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java
index 15e21fe..6f89058 100644
--- a/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java
+++ b/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java
@@ -41,6 +41,7 @@
 import com.google.gerrit.extensions.common.GpgKeyInfo;
 import com.google.gerrit.extensions.common.GroupInfo;
 import com.google.gerrit.extensions.common.Input;
+import com.google.gerrit.extensions.common.NameInput;
 import com.google.gerrit.extensions.common.SshKeyInfo;
 import com.google.gerrit.extensions.restapi.IdString;
 import com.google.gerrit.extensions.restapi.Response;
@@ -74,6 +75,7 @@
 import com.google.gerrit.server.restapi.account.PostWatchedProjects;
 import com.google.gerrit.server.restapi.account.PutActive;
 import com.google.gerrit.server.restapi.account.PutAgreement;
+import com.google.gerrit.server.restapi.account.PutName;
 import com.google.gerrit.server.restapi.account.PutStatus;
 import com.google.gerrit.server.restapi.account.SetDiffPreferences;
 import com.google.gerrit.server.restapi.account.SetEditPreferences;
@@ -132,6 +134,7 @@
   private final PutStatus putStatus;
   private final GetGroups getGroups;
   private final EmailApiImpl.Factory emailApi;
+  private final PutName putName;
 
   @Inject
   AccountApiImpl(
@@ -173,6 +176,7 @@
       PutStatus putStatus,
       GetGroups getGroups,
       EmailApiImpl.Factory emailApi,
+      PutName putName,
       @Assisted AccountResource account) {
     this.account = account;
     this.accountLoaderFactory = ailf;
@@ -213,6 +217,7 @@
     this.putStatus = putStatus;
     this.getGroups = getGroups;
     this.emailApi = emailApi;
+    this.putName = putName;
   }
 
   @Override
@@ -577,4 +582,15 @@
       throw asRestApiException("Cannot delete draft comments", e);
     }
   }
+
+  @Override
+  public void setName(String name) throws RestApiException {
+    NameInput input = new NameInput();
+    input.name = name;
+    try {
+      putName.apply(account, input);
+    } catch (Exception e) {
+      throw asRestApiException("Cannot set account name", e);
+    }
+  }
 }
diff --git a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
index c958fcc..d594657 100644
--- a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
+++ b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
@@ -725,44 +725,39 @@
       addMessage("");
       addMessage("Updated Changes:");
       boolean edit = magicBranch != null && (magicBranch.edit || magicBranch.draft);
-      Boolean isPrivate = null;
-      Boolean wip = null;
-      if (magicBranch != null) {
-        if (magicBranch.isPrivate) {
-          isPrivate = true;
-        } else if (magicBranch.removePrivate) {
-          isPrivate = false;
-        }
-        if (magicBranch.workInProgress) {
-          wip = true;
-        } else if (magicBranch.ready) {
-          wip = false;
-        }
-      }
       for (ReplaceRequest u : updated) {
         String subject;
+        Change change = u.notes.getChange();
         if (edit) {
           try {
             subject = receivePack.getRevWalk().parseCommit(u.newCommitId).getShortMessage();
           } catch (IOException e) {
             // Log and fall back to original change subject
             logger.atWarning().withCause(e).log("failed to get subject for edit patch set");
-            subject = u.notes.getChange().getSubject();
+            subject = change.getSubject();
           }
         } else {
           subject = u.info.getSubject();
         }
 
-        if (isPrivate == null) {
-          isPrivate = u.notes.getChange().isPrivate();
-        }
-        if (wip == null) {
-          wip = u.notes.getChange().isWorkInProgress();
+        boolean isPrivate = change.isPrivate();
+        boolean wip = change.isWorkInProgress();
+        if (magicBranch != null) {
+          if (magicBranch.isPrivate) {
+            isPrivate = true;
+          } else if (magicBranch.removePrivate) {
+            isPrivate = false;
+          }
+          if (magicBranch.workInProgress) {
+            wip = true;
+          } else if (magicBranch.ready) {
+            wip = false;
+          }
         }
 
         ChangeReportFormatter.Input input =
             ChangeReportFormatter.Input.builder()
-                .setChange(u.notes.getChange())
+                .setChange(change)
                 .setSubject(subject)
                 .setIsEdit(edit)
                 .setIsPrivate(isPrivate)
diff --git a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
index c4a66a5..58a8a03 100644
--- a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
@@ -52,6 +52,7 @@
 import com.google.gerrit.acceptance.AbstractDaemonTest;
 import com.google.gerrit.acceptance.GerritConfig;
 import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.Sandboxed;
 import com.google.gerrit.acceptance.TestAccount;
 import com.google.gerrit.acceptance.UseSsh;
 import com.google.gerrit.acceptance.testsuite.account.AccountOperations;
@@ -1176,6 +1177,33 @@
   }
 
   @Test
+  public void setName() throws Exception {
+    gApi.accounts().self().setName("Admin McAdminface");
+    assertThat(gApi.accounts().self().get().name).isEqualTo("Admin McAdminface");
+  }
+
+  @Test
+  public void adminCanSetNameOfOtherUser() throws Exception {
+    gApi.accounts().id(user.username).setName("User McUserface");
+    assertThat(gApi.accounts().id(user.username).get().name).isEqualTo("User McUserface");
+  }
+
+  @Test
+  public void userCannotSetNameOfOtherUser() throws Exception {
+    setApiUser(user);
+    exception.expect(AuthException.class);
+    gApi.accounts().id(admin.username).setName("Admin McAdminface");
+  }
+
+  @Test
+  @Sandboxed
+  public void userCanSetNameOfOtherUserWithModifyAccountPermission() throws Exception {
+    allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.MODIFY_ACCOUNT);
+    gApi.accounts().id(admin.username).setName("Admin McAdminface");
+    assertThat(gApi.accounts().id(admin.username).get().name).isEqualTo("Admin McAdminface");
+  }
+
+  @Test
   public void fetchUserBranch() throws Exception {
     setApiUser(user);
 
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java b/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
index 19ea44b..9f07461 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
@@ -45,7 +45,7 @@
       case V6_4:
         return "docker.elastic.co/elasticsearch/elasticsearch-oss:6.4.3";
       case V6_5:
-        return "docker.elastic.co/elasticsearch/elasticsearch-oss:6.5.2";
+        return "docker.elastic.co/elasticsearch/elasticsearch-oss:6.5.3";
       case V7_0:
         return "docker.elastic.co/elasticsearch/elasticsearch-oss:7.0.0-alpha1";
     }