| // 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.googlesource.gerrit.plugins.its.jira; |
| |
| import com.google.common.annotations.VisibleForTesting; |
| import com.google.common.base.CharMatcher; |
| import com.google.common.base.Strings; |
| import com.google.gerrit.entities.Project; |
| import com.google.gerrit.entities.StoredCommentLinkInfo; |
| import com.google.gerrit.extensions.annotations.PluginName; |
| import com.google.gerrit.server.GerritPersonIdent; |
| import com.google.gerrit.server.config.GerritServerConfig; |
| import com.google.gerrit.server.config.PluginConfig; |
| import com.google.gerrit.server.config.PluginConfigFactory; |
| import com.google.gerrit.server.extensions.events.GitReferenceUpdated; |
| import com.google.gerrit.server.git.GitRepositoryManager; |
| import com.google.gerrit.server.git.meta.MetaDataUpdate; |
| import com.google.gerrit.server.project.NoSuchProjectException; |
| import com.google.gerrit.server.project.ProjectCache; |
| import com.google.gerrit.server.project.ProjectConfig; |
| import com.google.inject.Inject; |
| import com.google.inject.Singleton; |
| import com.googlesource.gerrit.plugins.its.jira.restapi.JiraURL; |
| import java.io.IOException; |
| import org.eclipse.jgit.errors.ConfigInvalidException; |
| import org.eclipse.jgit.lib.Config; |
| import org.eclipse.jgit.lib.PersonIdent; |
| import org.eclipse.jgit.lib.Repository; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| /** The JIRA plugin configuration as read from project config. */ |
| @Singleton |
| public class JiraConfig { |
| static final String PROJECT_CONFIG_URL_KEY = "instanceUrl"; |
| static final String PROJECT_CONFIG_USERNAME_KEY = "username"; |
| static final String PROJECT_CONFIG_PASSWORD_KEY = "password"; |
| |
| private static final Logger log = LoggerFactory.getLogger(JiraConfig.class); |
| private static final String COMMENTLINK = "commentlink"; |
| private static final String GERRIT_CONFIG_URL = "url"; |
| private static final String GERRIT_CONFIG_USERNAME = "username"; |
| private static final String GERRIT_CONFIG_PASSWORD = "password"; |
| |
| private final String pluginName; |
| private final PluginConfigFactory cfgFactory; |
| private final Config gerritConfig; |
| private final JiraItsServerInfo defaultJiraServerInfo; |
| private final GitRepositoryManager repoManager; |
| private final ProjectCache projectCache; |
| private final ProjectConfig.Factory projectConfigFactory; |
| private final PersonIdent serverUser; |
| |
| @Inject |
| JiraConfig( |
| @GerritServerConfig Config config, |
| @PluginName String pluginName, |
| PluginConfigFactory cfgFactory, |
| @GerritPersonIdent PersonIdent serverUser, |
| ProjectCache projectCache, |
| GitRepositoryManager repoManager, |
| ProjectConfig.Factory projectConfigFactory) { |
| this.gerritConfig = config; |
| this.pluginName = pluginName; |
| this.cfgFactory = cfgFactory; |
| this.serverUser = serverUser; |
| this.projectCache = projectCache; |
| this.repoManager = repoManager; |
| this.projectConfigFactory = projectConfigFactory; |
| this.defaultJiraServerInfo = buildDefaultServerInfo(gerritConfig, pluginName); |
| } |
| |
| private static JiraItsServerInfo buildDefaultServerInfo(Config gerritConfig, String pluginName) { |
| return JiraItsServerInfo.builder() |
| .url(gerritConfig.getString(pluginName, null, GERRIT_CONFIG_URL)) |
| .username(gerritConfig.getString(pluginName, null, GERRIT_CONFIG_USERNAME)) |
| .password(gerritConfig.getString(pluginName, null, GERRIT_CONFIG_PASSWORD)) |
| .build(); |
| } |
| |
| JiraItsServerInfo getDefaultServerInfo() { |
| return defaultJiraServerInfo; |
| } |
| |
| String getCommentLinkFromGerritConfig(String key) { |
| return gerritConfig.getString(COMMENTLINK, pluginName, key); |
| } |
| |
| JiraItsServerInfo getServerInfoFor(String projectName) { |
| PluginConfig pluginConfig = getPluginConfigFor(projectName); |
| return JiraItsServerInfo.builder() |
| .url(pluginConfig.getString(PROJECT_CONFIG_URL_KEY, null)) |
| .username(pluginConfig.getString(PROJECT_CONFIG_USERNAME_KEY, null)) |
| .password(pluginConfig.getString(PROJECT_CONFIG_PASSWORD_KEY, null)) |
| .build(); |
| } |
| |
| void addCommentLinksSection(Project.NameKey projectName, JiraItsServerInfo jiraItsServerInfo) { |
| try (Repository git = repoManager.openRepository(projectName); |
| MetaDataUpdate md = new MetaDataUpdate(GitReferenceUpdated.DISABLED, projectName, git)) { |
| ProjectConfig config = projectConfigFactory.read(md); |
| String link = |
| CharMatcher.is('/').trimFrom(jiraItsServerInfo.getUrl().toString()) + JiraURL.URL_SUFFIX; |
| if (!commentLinksExist(config, link)) { |
| String match = getCommentLinkFromGerritConfig("match"); |
| StoredCommentLinkInfo commentlinkSection = |
| StoredCommentLinkInfo.builder(pluginName) |
| .setMatch(match) |
| .setLink(link) |
| .setEnabled(true) |
| .build(); |
| config.addCommentLinkSection(commentlinkSection); |
| md.getCommitBuilder().setAuthor(serverUser); |
| md.getCommitBuilder().setCommitter(serverUser); |
| projectCache.evict(config.getProject()); |
| config.commit(md); |
| } |
| } catch (ConfigInvalidException | IOException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| private boolean commentLinksExist(ProjectConfig config, String link) { |
| return config.getCommentLinkSections().stream().map(c -> c.getLink()).anyMatch(link::equals); |
| } |
| |
| @VisibleForTesting |
| PluginConfig getPluginConfigFor(String projectName) { |
| if (!Strings.isNullOrEmpty(projectName)) { |
| try { |
| return cfgFactory.getFromProjectConfigWithInheritance( |
| Project.nameKey(projectName), pluginName); |
| } catch (NoSuchProjectException e) { |
| log.warn( |
| "Unable to get project configuration for {}: project '{}' not found ", |
| pluginName, |
| projectName, |
| e); |
| } |
| } |
| return PluginConfig.create(pluginName, new Config(), null); |
| } |
| } |