Implement new numDocs() method

which was introduced in Ib054133d2592f40ae96a6b029097db49fc378cd0.

Change-Id: If4e5c7a5b390ad10b00a8fcb1c94e6dae78826b7
diff --git a/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java b/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
index c022978..85ce166 100644
--- a/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
+++ b/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
@@ -75,6 +75,7 @@
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpStatus;
 import org.apache.http.StatusLine;
+import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.entity.ContentType;
 import org.apache.http.nio.entity.NStringEntity;
@@ -86,6 +87,7 @@
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
 
   protected static final String BULK = "_bulk";
+  protected static final String COUNT = "_count";
   protected static final String MAPPINGS = "mappings";
   protected static final String ORDER = "order";
   protected static final String DESC_SORT_ORDER = "desc";
@@ -190,6 +192,27 @@
   }
 
   @Override
+  public int numDocs() {
+    String uri = getURI(COUNT);
+    Response response = performRequest(HttpGet.METHOD_NAME, uri);
+    int statusCode = response.getStatusLine().getStatusCode();
+    if (statusCode != HttpStatus.SC_OK) {
+      throw new StorageException(
+          String.format(
+              "Request to get number of %s index documents failed: %s",
+              indexName, response.getStatusLine().getReasonPhrase()));
+    }
+    String content;
+    try {
+      content = getContent(response);
+      return JsonParser.parseString(content).getAsJsonObject().get("count").getAsInt();
+    } catch (IOException e) {
+      throw new StorageException(
+          String.format("Request to get number of %s index documents failed", indexName), e);
+    }
+  }
+
+  @Override
   public void delete(K id) {
     String uri = getURI(BULK);
     Response response = postRequestWithRefreshParam(uri, getDeleteActions(id));
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryAccountsTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryAccountsTest.java
index ce16b2e..a5f05dd 100644
--- a/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryAccountsTest.java
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryAccountsTest.java
@@ -18,8 +18,10 @@
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
 
 import com.google.gerrit.exceptions.StorageException;
+import com.google.gerrit.server.index.account.AccountIndexDefinition;
 import com.google.gerrit.server.query.account.AbstractQueryAccountsTest;
 import com.google.gerrit.testing.ConfigSuite;
+import com.google.inject.Inject;
 import com.google.inject.Injector;
 import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
 import org.eclipse.jgit.lib.Config;
@@ -55,6 +57,8 @@
     }
   }
 
+  @Inject private AccountIndexDefinition accountIndexDefinition;
+
   @Override
   protected void initAfterLifecycleStart() throws Exception {
     super.initAfterLifecycleStart();
@@ -75,4 +79,10 @@
         assertThrows(StorageException.class, () -> gApi.accounts().self().index());
     assertThat(thrown).hasMessageThat().contains("Failed to replace account");
   }
+
+  @Test
+  public void testNumDocs() throws Exception {
+    assertThat(accountIndexDefinition.getIndexCollection().getSearchIndex().numDocs())
+        .isGreaterThan(-1);
+  }
 }
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryChangesTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryChangesTest.java
index 2fa004e..8a0af62 100644
--- a/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryChangesTest.java
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryChangesTest.java
@@ -20,9 +20,11 @@
 import com.google.gerrit.entities.Change;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.exceptions.StorageException;
+import com.google.gerrit.server.index.change.ChangeIndexDefinition;
 import com.google.gerrit.server.query.change.AbstractQueryChangesTest;
 import com.google.gerrit.testing.ConfigSuite;
 import com.google.gerrit.testing.GerritTestName;
+import com.google.inject.Inject;
 import com.google.inject.Injector;
 import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
 import org.eclipse.jgit.junit.TestRepository;
@@ -63,6 +65,7 @@
   }
 
   @Rule public final GerritTestName testName = new GerritTestName();
+  @Inject private ChangeIndexDefinition changeIndexDefinition;
 
   @After
   public void closeIndex() throws Exception {
@@ -94,4 +97,10 @@
         assertThrows(StorageException.class, () -> gApi.changes().id(c.getChangeId()).index());
     assertThat(thrown).hasMessageThat().contains("Failed to reindex change");
   }
+
+  @Test
+  public void testNumDocs() throws Exception {
+    assertThat(changeIndexDefinition.getIndexCollection().getSearchIndex().numDocs())
+        .isGreaterThan(-1);
+  }
 }
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryGroupsTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryGroupsTest.java
index f449bca..4835116 100644
--- a/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryGroupsTest.java
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryGroupsTest.java
@@ -19,8 +19,10 @@
 
 import com.google.gerrit.exceptions.StorageException;
 import com.google.gerrit.extensions.api.groups.GroupApi;
+import com.google.gerrit.server.index.group.GroupIndexDefinition;
 import com.google.gerrit.server.query.group.AbstractQueryGroupsTest;
 import com.google.gerrit.testing.ConfigSuite;
+import com.google.inject.Inject;
 import com.google.inject.Injector;
 import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
 import org.eclipse.jgit.lib.Config;
@@ -56,6 +58,8 @@
     }
   }
 
+  @Inject private GroupIndexDefinition groupIndexDefinition;
+
   @Override
   protected void initAfterLifecycleStart() throws Exception {
     super.initAfterLifecycleStart();
@@ -76,4 +80,10 @@
     StorageException thrown = assertThrows(StorageException.class, () -> group.index());
     assertThat(thrown).hasMessageThat().contains("Failed to replace group");
   }
+
+  @Test
+  public void testNumDocs() throws Exception {
+    assertThat(groupIndexDefinition.getIndexCollection().getSearchIndex().numDocs())
+        .isGreaterThan(-1);
+  }
 }
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryProjectsTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryProjectsTest.java
index 5f4847c..71ef093 100644
--- a/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryProjectsTest.java
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryProjectsTest.java
@@ -19,8 +19,10 @@
 
 import com.google.gerrit.exceptions.StorageException;
 import com.google.gerrit.extensions.api.projects.ProjectApi;
+import com.google.gerrit.server.index.project.ProjectIndexDefinition;
 import com.google.gerrit.server.query.project.AbstractQueryProjectsTest;
 import com.google.gerrit.testing.ConfigSuite;
+import com.google.inject.Inject;
 import com.google.inject.Injector;
 import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
 import org.eclipse.jgit.lib.Config;
@@ -56,6 +58,8 @@
     }
   }
 
+  @Inject private ProjectIndexDefinition projectIndexDefinition;
+
   @Override
   protected void initAfterLifecycleStart() throws Exception {
     super.initAfterLifecycleStart();
@@ -76,4 +80,10 @@
     StorageException thrown = assertThrows(StorageException.class, () -> project.index(false));
     assertThat(thrown).hasMessageThat().contains("Failed to replace project");
   }
+
+  @Test
+  public void testNumDocs() throws Exception {
+    assertThat(projectIndexDefinition.getIndexCollection().getSearchIndex().numDocs())
+        .isGreaterThan(-1);
+  }
 }