Line data Source code
1 : // Copyright (C) 2019 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.change; 16 : 17 : import static java.util.concurrent.TimeUnit.MINUTES; 18 : 19 : import com.google.common.collect.ImmutableListMultimap; 20 : import com.google.common.flogger.FluentLogger; 21 : import com.google.gerrit.entities.Change; 22 : import com.google.gerrit.extensions.common.PluginDefinedInfo; 23 : import com.google.gerrit.extensions.registration.Extension; 24 : import com.google.gerrit.server.DynamicOptions.BeanProvider; 25 : import com.google.gerrit.server.query.change.ChangeData; 26 : import java.util.Collection; 27 : import java.util.stream.Stream; 28 : 29 : /** Static helpers for use by {@link PluginDefinedInfosFactory} implementations. */ 30 : public class PluginDefinedAttributesFactories { 31 71 : private static final FluentLogger logger = FluentLogger.forEnclosingClass(); 32 : 33 : public static ImmutableListMultimap<Change.Id, PluginDefinedInfo> createAll( 34 : Collection<ChangeData> cds, 35 : BeanProvider beanProvider, 36 : Stream<Extension<ChangePluginDefinedInfoFactory>> infoFactories) { 37 : ImmutableListMultimap.Builder<Change.Id, PluginDefinedInfo> pluginInfosByChangeBuilder = 38 71 : ImmutableListMultimap.builder(); 39 71 : infoFactories.forEach( 40 3 : e -> tryCreate(cds, beanProvider, e.getPluginName(), e.get(), pluginInfosByChangeBuilder)); 41 71 : ImmutableListMultimap<Change.Id, PluginDefinedInfo> result = pluginInfosByChangeBuilder.build(); 42 71 : return result; 43 : } 44 : 45 : private static void tryCreate( 46 : Collection<ChangeData> cds, 47 : BeanProvider beanProvider, 48 : String plugin, 49 : ChangePluginDefinedInfoFactory infoFactory, 50 : ImmutableListMultimap.Builder<Change.Id, PluginDefinedInfo> pluginInfosByChangeBuilder) { 51 : try { 52 3 : infoFactory 53 3 : .createPluginDefinedInfos(cds, beanProvider, plugin) 54 3 : .forEach( 55 : (id, pdi) -> { 56 3 : if (pdi != null) { 57 3 : pdi.name = plugin; 58 3 : pluginInfosByChangeBuilder.put(id, pdi); 59 : } 60 3 : }); 61 3 : } catch (RuntimeException ex) { 62 : /* Propagate runtime exceptions as structured API data types so that queries don't fail. */ 63 3 : logger.atWarning().atMostEvery(1, MINUTES).withCause(ex).log( 64 : "error populating attribute on changes from plugin %s", plugin); 65 3 : PluginDefinedInfo errorInfo = new PluginDefinedInfo(); 66 3 : errorInfo.name = plugin; 67 3 : errorInfo.message = "Something went wrong in plugin: " + plugin; 68 3 : cds.forEach(cd -> pluginInfosByChangeBuilder.put(cd.getId(), errorInfo)); 69 3 : } 70 3 : } 71 : 72 : private PluginDefinedAttributesFactories() {} 73 : }