LCOV - code coverage report
Current view: top level - server/restapi/config - ListTasks.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 32 50 64.0 %
Date: 2022-11-19 15:00:39 Functions: 4 7 57.1 %

          Line data    Source code
       1             : // Copyright (C) 2014 The Android Open Source Project
       2             : //
       3             : // Licensed under the Apache License, Version 2.0 (the "License");
       4             : // you may not use this file except in compliance with the License.
       5             : // You may obtain a copy of the License at
       6             : //
       7             : // http://www.apache.org/licenses/LICENSE-2.0
       8             : //
       9             : // Unless required by applicable law or agreed to in writing, software
      10             : // distributed under the License is distributed on an "AS IS" BASIS,
      11             : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             : // See the License for the specific language governing permissions and
      13             : // limitations under the License.
      14             : 
      15             : package com.google.gerrit.server.restapi.config;
      16             : 
      17             : import static java.util.Comparator.comparing;
      18             : import static java.util.stream.Collectors.toList;
      19             : 
      20             : import com.google.gerrit.entities.Project;
      21             : import com.google.gerrit.extensions.restapi.AuthException;
      22             : import com.google.gerrit.extensions.restapi.Response;
      23             : import com.google.gerrit.extensions.restapi.RestReadView;
      24             : import com.google.gerrit.server.CurrentUser;
      25             : import com.google.gerrit.server.config.ConfigResource;
      26             : import com.google.gerrit.server.git.WorkQueue;
      27             : import com.google.gerrit.server.git.WorkQueue.ProjectTask;
      28             : import com.google.gerrit.server.git.WorkQueue.Task;
      29             : import com.google.gerrit.server.ioutil.HexFormat;
      30             : import com.google.gerrit.server.permissions.GlobalPermission;
      31             : import com.google.gerrit.server.permissions.PermissionBackend;
      32             : import com.google.gerrit.server.permissions.PermissionBackendException;
      33             : import com.google.gerrit.server.permissions.ProjectPermission;
      34             : import com.google.gerrit.server.project.ProjectCache;
      35             : import com.google.gerrit.server.project.ProjectState;
      36             : import com.google.inject.Inject;
      37             : import com.google.inject.Provider;
      38             : import com.google.inject.Singleton;
      39             : import java.sql.Timestamp;
      40             : import java.util.ArrayList;
      41             : import java.util.HashMap;
      42             : import java.util.List;
      43             : import java.util.Map;
      44             : import java.util.Optional;
      45             : import java.util.concurrent.TimeUnit;
      46             : 
      47             : @Singleton
      48             : public class ListTasks implements RestReadView<ConfigResource> {
      49             :   private final PermissionBackend permissionBackend;
      50             :   private final WorkQueue workQueue;
      51             :   private final Provider<CurrentUser> self;
      52             :   private final ProjectCache projectCache;
      53             : 
      54             :   @Inject
      55             :   public ListTasks(
      56             :       PermissionBackend permissionBackend,
      57             :       WorkQueue workQueue,
      58             :       Provider<CurrentUser> self,
      59         138 :       ProjectCache projectCache) {
      60         138 :     this.permissionBackend = permissionBackend;
      61         138 :     this.workQueue = workQueue;
      62         138 :     this.self = self;
      63         138 :     this.projectCache = projectCache;
      64         138 :   }
      65             : 
      66             :   @Override
      67             :   public Response<List<TaskInfo>> apply(ConfigResource resource)
      68             :       throws AuthException, PermissionBackendException {
      69           3 :     CurrentUser user = self.get();
      70           3 :     if (!user.isIdentifiedUser()) {
      71           0 :       throw new AuthException("Authentication required");
      72             :     }
      73             : 
      74           3 :     List<TaskInfo> allTasks = getTasks();
      75           3 :     if (permissionBackend.user(user).test(GlobalPermission.VIEW_QUEUE)) {
      76           3 :       return Response.ok(allTasks);
      77             :     }
      78             : 
      79           1 :     Map<String, Boolean> visibilityCache = new HashMap<>();
      80           1 :     List<TaskInfo> visibleTasks = new ArrayList<>();
      81           1 :     for (TaskInfo task : allTasks) {
      82           1 :       if (task.projectName != null) {
      83           0 :         Boolean visible = visibilityCache.get(task.projectName);
      84           0 :         if (visible == null) {
      85           0 :           Project.NameKey nameKey = Project.nameKey(task.projectName);
      86           0 :           Optional<ProjectState> state = projectCache.get(nameKey);
      87           0 :           if (!state.isPresent() || !state.get().statePermitsRead()) {
      88           0 :             visible = false;
      89             :           } else {
      90           0 :             if (permissionBackend.user(user).project(nameKey).test(ProjectPermission.ACCESS)) {
      91           0 :               visible = true;
      92             :             } else {
      93           0 :               visible = false;
      94             :             }
      95             :           }
      96           0 :           visibilityCache.put(task.projectName, visible);
      97             :         }
      98           0 :         if (visible) {
      99           0 :           visibleTasks.add(task);
     100             :         }
     101             :       }
     102           1 :     }
     103           1 :     return Response.ok(visibleTasks);
     104             :   }
     105             : 
     106             :   private List<TaskInfo> getTasks() {
     107           3 :     return workQueue.getTaskInfos(TaskInfo::new).stream()
     108           3 :         .sorted(
     109           3 :             comparing((TaskInfo t) -> t.state.ordinal())
     110           3 :                 .thenComparing(t -> t.delay)
     111           3 :                 .thenComparing(t -> t.command))
     112           3 :         .collect(toList());
     113             :   }
     114             : 
     115             :   public static class TaskInfo {
     116             :     public String id;
     117             :     public Task.State state;
     118             :     public Timestamp startTime;
     119             :     public long delay;
     120             :     public String command;
     121             :     public String remoteName;
     122             :     public String projectName;
     123             :     public String queueName;
     124             : 
     125           3 :     public TaskInfo(Task<?> task) {
     126           3 :       this.id = HexFormat.fromInt(task.getTaskId());
     127           3 :       this.state = task.getState();
     128           3 :       this.startTime = Timestamp.from(task.getStartTime());
     129           3 :       this.delay = task.getDelay(TimeUnit.MILLISECONDS);
     130           3 :       this.command = task.toString();
     131           3 :       this.queueName = task.getQueueName();
     132             : 
     133           3 :       if (task instanceof ProjectTask) {
     134           0 :         ProjectTask<?> projectTask = ((ProjectTask<?>) task);
     135           0 :         Project.NameKey name = projectTask.getProjectNameKey();
     136           0 :         if (name != null) {
     137           0 :           this.projectName = name.get();
     138             :         }
     139           0 :         this.remoteName = projectTask.getRemoteName();
     140             :       }
     141           3 :     }
     142             :   }
     143             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750