LCOV - code coverage report
Current view: top level - server/extensions/events - EventUtil.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 39 42 92.9 %
Date: 2022-11-19 15:00:39 Functions: 7 8 87.5 %

          Line data    Source code
       1             : // Copyright (C) 2015 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.extensions.events;
      16             : 
      17             : import com.google.common.collect.ImmutableSet;
      18             : import com.google.common.collect.Sets;
      19             : import com.google.common.flogger.FluentLogger;
      20             : import com.google.gerrit.common.Nullable;
      21             : import com.google.gerrit.entities.Account;
      22             : import com.google.gerrit.entities.PatchSet;
      23             : import com.google.gerrit.entities.Project;
      24             : import com.google.gerrit.extensions.client.ListChangesOption;
      25             : import com.google.gerrit.extensions.common.AccountInfo;
      26             : import com.google.gerrit.extensions.common.ApprovalInfo;
      27             : import com.google.gerrit.extensions.common.ChangeInfo;
      28             : import com.google.gerrit.extensions.common.RevisionInfo;
      29             : import com.google.gerrit.server.GpgException;
      30             : import com.google.gerrit.server.account.AccountState;
      31             : import com.google.gerrit.server.change.ChangeJson;
      32             : import com.google.gerrit.server.change.RevisionJson;
      33             : import com.google.gerrit.server.config.GerritServerConfig;
      34             : import com.google.gerrit.server.patch.PatchListNotAvailableException;
      35             : import com.google.gerrit.server.permissions.PermissionBackendException;
      36             : import com.google.gerrit.server.query.change.ChangeData;
      37             : import com.google.inject.Inject;
      38             : import com.google.inject.Singleton;
      39             : import java.io.IOException;
      40             : import java.time.Instant;
      41             : import java.util.EnumSet;
      42             : import java.util.HashMap;
      43             : import java.util.Map;
      44             : import org.eclipse.jgit.lib.Config;
      45             : 
      46             : /**
      47             :  * Formats change and revision info objects to serve as payload for Gerrit events.
      48             :  *
      49             :  * <p>Uses configurable options ({@code event.payload.listChangeOptions}) to decide which change
      50             :  * fields to populate.
      51             :  */
      52             : @Singleton
      53             : public class EventUtil {
      54         151 :   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
      55             : 
      56             :   private static final ImmutableSet<ListChangesOption> DEFAULT_CHANGE_OPTIONS;
      57             : 
      58             :   static {
      59         151 :     EnumSet<ListChangesOption> opts = EnumSet.allOf(ListChangesOption.class);
      60             :     // Some options, like actions, are expensive to compute because they potentially have to walk
      61             :     // lots of history and inspect lots of other changes.
      62         151 :     opts.remove(ListChangesOption.CHANGE_ACTIONS);
      63         151 :     opts.remove(ListChangesOption.CURRENT_ACTIONS);
      64             :     // CHECK suppresses some exceptions on corrupt changes, which is not appropriate for passing
      65             :     // through the event system as we would rather let them propagate.
      66         151 :     opts.remove(ListChangesOption.CHECK);
      67         151 :     DEFAULT_CHANGE_OPTIONS = Sets.immutableEnumSet(opts);
      68         151 :   }
      69             : 
      70             :   private final ChangeData.Factory changeDataFactory;
      71             :   private final ChangeJson.Factory changeJsonFactory;
      72             :   private final RevisionJson.Factory revisionJsonFactory;
      73             :   private final ImmutableSet<ListChangesOption> changeOptions;
      74             : 
      75             :   @Inject
      76             :   EventUtil(
      77             :       ChangeJson.Factory changeJsonFactory,
      78             :       RevisionJson.Factory revisionJsonFactory,
      79             :       ChangeData.Factory changeDataFactory,
      80         151 :       @GerritServerConfig Config gerritConfig) {
      81         151 :     this.changeDataFactory = changeDataFactory;
      82         151 :     this.changeJsonFactory = changeJsonFactory;
      83         151 :     this.revisionJsonFactory = revisionJsonFactory;
      84         151 :     this.changeOptions = parseChangeListOptions(gerritConfig);
      85         151 :   }
      86             : 
      87             :   public ChangeInfo changeInfo(ChangeData changeData) {
      88         100 :     return changeJsonFactory.create(changeOptions).format(changeData);
      89             :   }
      90             : 
      91             :   public RevisionInfo revisionInfo(Project project, PatchSet ps)
      92             :       throws PatchListNotAvailableException, GpgException, IOException, PermissionBackendException {
      93           0 :     return revisionInfo(project.getNameKey(), ps);
      94             :   }
      95             : 
      96             :   public RevisionInfo revisionInfo(Project.NameKey project, PatchSet ps)
      97             :       throws PatchListNotAvailableException, GpgException, IOException, PermissionBackendException {
      98          99 :     ChangeData cd = changeDataFactory.create(project, ps.id().changeId());
      99          99 :     return revisionJsonFactory.create(changeOptions).getRevisionInfo(cd, ps);
     100             :   }
     101             : 
     102             :   @Nullable
     103             :   public AccountInfo accountInfo(@Nullable AccountState accountState) {
     104         151 :     if (accountState == null || accountState.account().id() == null) {
     105         151 :       return null;
     106             :     }
     107         151 :     Account account = accountState.account();
     108         151 :     AccountInfo accountInfo = new AccountInfo(account.id().get());
     109         151 :     accountInfo.email = account.preferredEmail();
     110         151 :     accountInfo.name = account.fullName();
     111         151 :     accountInfo.username = accountState.userName().orElse(null);
     112         151 :     return accountInfo;
     113             :   }
     114             : 
     115             :   public Map<String, ApprovalInfo> approvals(
     116             :       AccountState accountState, Map<String, Short> approvals, Instant ts) {
     117          61 :     Map<String, ApprovalInfo> result = new HashMap<>();
     118          61 :     for (Map.Entry<String, Short> e : approvals.entrySet()) {
     119          61 :       Integer value = e.getValue() != null ? Integer.valueOf(e.getValue()) : null;
     120          61 :       result.put(
     121          61 :           e.getKey(), new ApprovalInfo(accountState.account().id().get(), value, null, null, ts));
     122          61 :     }
     123          61 :     return result;
     124             :   }
     125             : 
     126             :   private static ImmutableSet<ListChangesOption> parseChangeListOptions(Config gerritConfig) {
     127         151 :     String[] config = gerritConfig.getStringList("event", "payload", "listChangeOptions");
     128         151 :     if (config.length == 0) {
     129         151 :       return DEFAULT_CHANGE_OPTIONS;
     130             :     }
     131             : 
     132           1 :     ImmutableSet.Builder<ListChangesOption> result = ImmutableSet.builder();
     133           1 :     for (String c : config) {
     134             :       try {
     135           1 :         result.add(ListChangesOption.valueOf(c));
     136           0 :       } catch (IllegalArgumentException e) {
     137           0 :         logger.atWarning().withCause(e).log("could not parse list change option %s", c);
     138           1 :       }
     139             :     }
     140           1 :     return result.build();
     141             :   }
     142             : }

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