Skip to content
Permalink
Browse files
IGNITE-10436 Add ticket and PR links on report TC Bot page. - Fixes #85.
Signed-off-by: Dmitriy Pavlov <dpavlov@apache.org>
  • Loading branch information
ololo3000 authored and dspavlov committed Dec 3, 2018
1 parent 4701d40 commit 15bb973bb5084b5c7cbf90bfbcb71d07f25e29b3
Show file tree
Hide file tree
Showing 21 changed files with 455 additions and 73 deletions.
@@ -5,6 +5,7 @@ logs=apache_logs
git.api_url=https://api.github.com/repos/apache/ignite/
jira.api_url=https://issues.apache.org/jira/rest/api/2/

jira.url=https://issues.apache.org/jira/

#specify JIRA Auth token (if needed)
jira.auth_token=
@@ -60,6 +60,9 @@ public class HelperConfig {
/** JIRA authorization token property name. */
public static final String JIRA_API_URL = "jira.api_url";

/** JIRA URL to build links to tickets. */
public static final String JIRA_URL = "jira.url";

/** Slack authorization token property name. */
public static final String SLACK_AUTH_TOKEN = "slack.auth_token";
public static final String SLACK_CHANNEL = "slack.channel";
@@ -53,7 +53,7 @@
* TC Bot implementation. To be migrated to smaller injected classes
*/
@Deprecated
public class TcHelper implements ITcHelper, IJiraIntegration {
public class TcHelper implements ITcHelper {
/** Logger. */
private static final Logger logger = LoggerFactory.getLogger(TcHelper.class);

@@ -199,7 +199,7 @@ private BranchesTracked getTrackedBranches() {
return new Visa("JIRA wasn't commented - " + errMsg);
}

return new Visa(JIRA_COMMENTED, res, blockers);
return new Visa(IJiraIntegration.JIRA_COMMENTED, res, blockers);
}


@@ -24,7 +24,6 @@
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.inject.Inject;
import javax.inject.Provider;
import org.apache.ignite.Ignite;
import org.apache.ignite.ci.ITcHelper;
@@ -34,16 +33,14 @@
import org.apache.ignite.ci.di.scheduler.SchedulerModule;
import org.apache.ignite.ci.github.ignited.GitHubIgnitedModule;
import org.apache.ignite.ci.issue.IssueDetector;
import org.apache.ignite.ci.jira.IJiraIntegration;
import org.apache.ignite.ci.jira.JiraIntegrationModule;
import org.apache.ignite.ci.observer.BuildObserver;
import org.apache.ignite.ci.observer.ObserverTask;
import org.apache.ignite.ci.tcbot.trends.MasterTrendsService;
import org.apache.ignite.ci.teamcity.ignited.TeamcityIgnitedModule;
import org.apache.ignite.ci.user.ICredentialsProv;
import org.apache.ignite.ci.util.ExceptionUtil;
import org.apache.ignite.ci.web.BackgroundUpdater;
import org.apache.ignite.ci.web.TcUpdatePool;
import org.apache.ignite.ci.web.model.Visa;
import org.apache.ignite.ci.web.model.hist.VisasHistoryStorage;
import org.apache.ignite.ci.web.rest.exception.ServiceStartingException;

@@ -80,27 +77,15 @@ public class IgniteTcBotModule extends AbstractModule {
bind(BuildObserver.class).in(new SingletonScope());
bind(VisasHistoryStorage.class).in(new SingletonScope());
bind(ITcHelper.class).to(TcHelper.class).in(new SingletonScope());

bind(IJiraIntegration.class).to(Jira.class).in(new SingletonScope());

bind(BackgroundUpdater.class).in(new SingletonScope());
bind(MasterTrendsService.class).in(new SingletonScope());

install(new TeamcityIgnitedModule());
install(new JiraIntegrationModule());
install(new GitHubIgnitedModule());
install(new SchedulerModule());
}

//todo now it is just fallback to TC big class, extract JIRA integation module
private static class Jira implements IJiraIntegration {
@Inject ITcHelper helper;

@Override public Visa notifyJira(String srvId, ICredentialsProv prov, String buildTypeId, String branchForTc,
String ticket) {
return helper.notifyJira(srvId, prov, buildTypeId, branchForTc, ticket);
}
}

private void configProfiling() {
AutoProfilingInterceptor profilingInterceptor = new AutoProfilingInterceptor();

@@ -25,6 +25,7 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Provider;
import org.apache.ignite.Ignite;
@@ -70,6 +71,13 @@ public void init(String srvId, IGitHubConnection conn) {
prCache = igniteProvider.get().getOrCreateCache(TcHelperDb.getCache8PartsConfig(GIT_HUB_PR));
}

/** {@inheritDoc} */
@AutoProfiling
@Nullable
@Override public PullRequest getPullRequest(int prNum) {
return prCache.get(prNumberToCacheKey(prNum));
}

/** {@inheritDoc} */
@AutoProfiling
@Override public List<PullRequest> getPullRequests() {
@@ -16,8 +16,12 @@
*/
package org.apache.ignite.ci.github.ignited;

import com.google.common.base.Preconditions;
import java.util.List;
import javax.annotation.Nullable;
import org.apache.ignite.ci.di.AutoProfiling;
import org.apache.ignite.ci.github.PullRequest;
import org.apache.ignite.ci.github.pure.IGitHubConnection;

/**
*
@@ -27,4 +31,18 @@ public interface IGitHubConnIgnited {
* @return list of open pull requests
*/
public List<PullRequest> getPullRequests();

/** */
public PullRequest getPullRequest(int prNum);

/** */
@AutoProfiling
@Nullable
public default PullRequest getPullRequest(String branchForTc) {
Integer prId = IGitHubConnection.convertBranchToId(branchForTc);

Preconditions.checkNotNull(prId, "Invalid TC branch name");

return getPullRequest(prId);
}
}
@@ -92,24 +92,6 @@ class GitHubConnectionImpl implements IGitHubConnection {
gitApiUrl = (props.getProperty(HelperConfig.GIT_API_URL));
}

/** */
private Integer convertBranchToId(String branchForTc) {
String id = null;

// Get PR id from string "pull/XXXX/head"
for (int i = 5; i < branchForTc.length(); i++) {
char c = branchForTc.charAt(i);

if (!Character.isDigit(c)) {
id = branchForTc.substring(5, i);

break;
}
}

return Integer.parseInt(id);
}

/** {@inheritDoc} */
@AutoProfiling
@Override public PullRequest getPullRequest(Integer id) {
@@ -130,7 +112,11 @@ private Integer convertBranchToId(String branchForTc) {
/** {@inheritDoc} */
@AutoProfiling
@Override public PullRequest getPullRequest(String branchForTc) {
return getPullRequest(convertBranchToId(branchForTc));
Integer prId = IGitHubConnection.convertBranchToId(branchForTc);

Preconditions.checkNotNull(prId, "Invalid TC branch name");

return getPullRequest(prId);
}

/** {@inheritDoc} */
@@ -17,6 +17,7 @@
package org.apache.ignite.ci.github.pure;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.ignite.ci.github.PullRequest;
import org.jetbrains.annotations.Nullable;
@@ -54,4 +55,33 @@ public interface IGitHubConnection {
String gitApiUrl();

List<PullRequest> getPullRequests(@Nullable String fullUrl, @Nullable AtomicReference<String> outLinkNext);

/**
* @return PR id from string "pull/XXXX/head"
*/
public @Nullable static Integer convertBranchToId(String branchForTc) {
Integer res = null;

if (Objects.isNull(branchForTc))
return res;

String id = null;

for (int i = 5; i < branchForTc.length(); i++) {
char c = branchForTc.charAt(i);

if (!Character.isDigit(c)) {
id = branchForTc.substring(5, i);

break;
}
}

try {
res = Integer.parseInt(id);
}
finally {
return res;
}
}
}
@@ -37,4 +37,16 @@ public interface IJiraIntegration {
*/
public Visa notifyJira(String srvId, ICredentialsProv prov, String buildTypeId, String branchForTc,
String ticket);

/** */
public String jiraUrl();

/** */
public void init(String srvId);

/** */
public String generateTicketUrl(String ticketFullName);

/** */
public String generateCommentUrl(String ticketFullName, int commentId);
}
@@ -0,0 +1,28 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.ignite.ci.jira;

/**
*
*/
public interface IJiraIntegrationProvider {
/**
* @param srvId Server id.
*/
public IJiraIntegration server(String srvId);
}
@@ -0,0 +1,77 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.ignite.ci.jira;

import com.google.common.base.Preconditions;
import java.io.File;
import java.util.Properties;
import javax.inject.Inject;
import org.apache.ignite.ci.HelperConfig;
import org.apache.ignite.ci.ITcHelper;
import org.apache.ignite.ci.user.ICredentialsProv;
import org.apache.ignite.ci.web.model.Visa;

import static com.google.common.base.Strings.isNullOrEmpty;

/**
*
*/
public class Jira implements IJiraIntegration {
/** */
@Inject ITcHelper helper;

/** */
private String jiraUrl;

/** {@inheritDoc} */
@Override public void init(String srvId) {
final File workDir = HelperConfig.resolveWorkDir();

final String cfgName = HelperConfig.prepareConfigName(srvId);

final Properties props = HelperConfig.loadAuthProperties(workDir, cfgName);

jiraUrl = props.getProperty(HelperConfig.JIRA_URL);
}

/** {@inheritDoc} */
@Override public String jiraUrl() {
return jiraUrl;
}

/** {@inheritDoc} */
@Override public Visa notifyJira(String srvId, ICredentialsProv prov, String buildTypeId, String branchForTc,
String ticket) {
return helper.notifyJira(srvId, prov, buildTypeId, branchForTc, ticket);
}

/** {@inheritDoc} */
@Override public String generateTicketUrl(String ticketFullName) {
Preconditions.checkState(!isNullOrEmpty(jiraUrl), "Jira URL is not configured for this server.");

return jiraUrl + "browse/" + ticketFullName;
}

/** {@inheritDoc} */
@Override public String generateCommentUrl(String ticketFullName, int commentId) {
return generateTicketUrl(ticketFullName) +
"?focusedCommentId=" + commentId +
"&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-" +
commentId;
}
}
@@ -0,0 +1,32 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.ignite.ci.jira;

import com.google.inject.AbstractModule;
import com.google.inject.internal.SingletonScope;

/**
*
*/
public class JiraIntegrationModule extends AbstractModule {
/** {@inheritDoc} */
@Override protected void configure() {
bind(IJiraIntegration.class).to(Jira.class);
bind(IJiraIntegrationProvider.class).to(JiraIntegrationProvider.class).in(new SingletonScope());
}
}

0 comments on commit 15bb973

Please sign in to comment.