// Copyright (C) 2018 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// 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.restapi.project;

import static com.google.gerrit.server.git.QueueProvider.QueueType.BATCH;

import com.google.common.flogger.FluentLogger;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.gerrit.extensions.api.projects.IndexProjectInput;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.index.project.ProjectIndexer;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.index.IndexExecutor;
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.project.ProjectResource;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
import java.util.concurrent.Future;

@Singleton
public class Index implements RestModifyView<ProjectResource, IndexProjectInput> {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  private final PermissionBackend permissionBackend;
  private final ProjectIndexer indexer;
  private final ListeningExecutorService executor;
  private final Provider<ListChildProjects> listChildProjectsProvider;

  @Inject
  Index(
      PermissionBackend permissionBackend,
      ProjectIndexer indexer,
      @IndexExecutor(BATCH) ListeningExecutorService executor,
      Provider<ListChildProjects> listChildProjectsProvider) {
    this.permissionBackend = permissionBackend;
    this.indexer = indexer;
    this.executor = executor;
    this.listChildProjectsProvider = listChildProjectsProvider;
  }

  @Override
  public Response.Accepted apply(ProjectResource rsrc, IndexProjectInput input)
      throws IOException, AuthException, OrmException, PermissionBackendException,
          ResourceConflictException {
    permissionBackend.currentUser().check(GlobalPermission.MAINTAIN_SERVER);
    String response = "Project " + rsrc.getName() + " submitted for reindexing";

    reindexAsync(rsrc.getNameKey());
    if (Boolean.TRUE.equals(input.indexChildren)) {
      ListChildProjects listChildProjects = listChildProjectsProvider.get();
      listChildProjects.setRecursive(true);
      listChildProjects.apply(rsrc).forEach(p -> reindexAsync(new Project.NameKey(p.name)));

      response += " (indexing children recursively)";
    }
    return Response.accepted(response);
  }

  private void reindexAsync(Project.NameKey project) {
    @SuppressWarnings("unused")
    Future<?> possiblyIgnoredError =
        executor.submit(
            () -> {
              try {
                indexer.index(project);
              } catch (IOException e) {
                logger.atWarning().withCause(e).log("reindexing project %s failed", project);
              }
            });
  }
}

@@ -838,24 +838,147 @@
 torService;%0A
+import com.google.gerrit.common.data.GlobalCapability;%0Aimport com.google.gerrit.extensions.annotations.RequiresCapability;%0A
 import com.g
@@ -1033,16 +1033,16 @@
 tInput;%0A
-
 import c
@@ -1439,133 +1439,8 @@
 or;%0A
-import com.google.gerrit.server.permissions.GlobalPermission;%0Aimport com.google.gerrit.server.permissions.PermissionBackend;%0A
 impo
@@ -1779,16 +1779,70 @@
 uture;%0A%0A
+@RequiresCapability(GlobalCapability.MAINTAIN_SERVER)%0A
 @Singlet
@@ -2011,61 +2011,8 @@
 );%0A%0A
-  private final PermissionBackend permissionBackend;%0A
   pr
@@ -2193,51 +2193,8 @@
 ex(%0A
-      PermissionBackend permissionBackend,%0A
     
@@ -2349,56 +2349,8 @@
 ) %7B%0A
-    this.permissionBackend = permissionBackend;%0A
     
@@ -2647,16 +2647,16 @@
 eption,%0A
+
         
@@ -2689,85 +2689,8 @@
 n %7B%0A
-    permissionBackend.currentUser().check(GlobalPermission.MAINTAIN_SERVER);%0A
     

Use capability annotation for Index (Projects)