You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sk...@apache.org on 2021/01/12 21:30:25 UTC
[ignite-teamcity-bot] branch master updated: Added mute issues from
board. Fixes #181
This is an automated email from the ASF dual-hosted git repository.
sk0x50 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite-teamcity-bot.git
The following commit(s) were added to refs/heads/master by this push:
new 0b493be Added mute issues from board. Fixes #181
0b493be is described below
commit 0b493bee998a32e771cf2bf7096f2250ed40c13a
Author: sergeyuttsel <ut...@gmail.com>
AuthorDate: Wed Jan 13 00:29:47 2021 +0300
Added mute issues from board. Fixes #181
Signed-off-by: Slava Koptilin <sl...@gmail.com>
---
.../ignite/ci/web/rest/board/BoardRestService.java | 57 +++++
.../src/main/webapp/board/index.html | 109 +++++++++-
.../src/main/webapp/js/common-1.6.js | 4 +-
.../main/webapp/{board => mutedissues}/index.html | 240 +++++++++++----------
.../ignite/tcbot/engine/TcBotEngineModule.java | 4 +-
.../ignite/tcbot/engine/board/BoardService.java | 148 ++++++++++++-
.../tcbot/engine/board/IssueResolveStatus.java | 2 +-
.../tcbot/engine/boardmute/MutedIssueInfo.java | 78 +++++++
.../tcbot/engine/boardmute/MutedIssueKey.java | 87 ++++++++
.../tcbot/engine/boardmute/MutedIssuesDao.java | 60 ++++++
.../ignite/tcbot/engine/issue/IssueType.java | 20 ++
.../ignite/tcbot/engine/ui/BoardDefectIssueUi.java | 17 ++
.../tcbot/engine/ui/BoardDefectSummaryUi.java | 13 +-
.../ignite/tcbot/engine/ui/MutedIssueUi.java | 120 +++++++++++
.../tcignited/buildlog/BuildLogProcessor.java | 9 +-
15 files changed, 834 insertions(+), 134 deletions(-)
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/board/BoardRestService.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/board/BoardRestService.java
index 362b06c..58a5650 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/board/BoardRestService.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/board/BoardRestService.java
@@ -16,9 +16,14 @@
*/
package org.apache.ignite.ci.web.rest.board;
+import java.util.Collection;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
+import javax.ws.rs.PATCH;
+import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
@@ -28,12 +33,18 @@ import org.apache.ignite.ci.user.ITcBotUserCreds;
import org.apache.ignite.ci.web.CtxListener;
import org.apache.ignite.tcbot.engine.board.BoardService;
import org.apache.ignite.tcbot.engine.ui.BoardSummaryUi;
+import org.apache.ignite.tcbot.engine.ui.MutedIssueUi;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
@Path(BoardRestService.BOARD)
@Produces(MediaType.APPLICATION_JSON)
public class BoardRestService {
static final String BOARD = "board";
+ /** */
+ private static final Logger logger = LoggerFactory.getLogger(BoardRestService.class);
+
/** Servlet Context. */
@Context
private ServletContext ctx;
@@ -49,4 +60,50 @@ public class BoardRestService {
return CtxListener.getInjector(ctx).getInstance(BoardService.class).summary(creds, baseBranch);
}
+
+ @PUT
+ @Path("muteIssue")
+ public void muteIssue(
+ @FormParam("tcSrvId") int tcSrvId,
+ @FormParam("nameId") int nameId,
+ @FormParam("branch") String branch,
+ @FormParam("trackedBranch") String trackedBranch,
+ @FormParam("issueType") String issueType,
+ @FormParam("jiraTicket") String jiraTicket,
+ @FormParam("comment") String comment,
+ @FormParam("userName") String userName,
+ @FormParam("webUrl") String webUrl) {
+ CtxListener.getInjector(ctx).getInstance(BoardService.class)
+ .muteIssue(tcSrvId, nameId, branch, trackedBranch, issueType, jiraTicket, comment, userName, webUrl);
+ }
+
+ @PATCH
+ @Path("updateIssue")
+ public void updateIssue(
+ @FormParam("tcSrvId") int tcSrvId,
+ @FormParam("nameId") int nameId,
+ @FormParam("branch") String branch,
+ @FormParam("issueType") String issueType,
+ @FormParam("jiraTicket") String jiraTicket,
+ @FormParam("comment") String comment) {
+ CtxListener.getInjector(ctx).getInstance(BoardService.class)
+ .updateIssue(tcSrvId, nameId, branch, issueType, jiraTicket, comment);
+ }
+
+ @DELETE
+ @Path("unmuteIssue")
+ public void unmuteIssue(
+ @FormParam("tcSrvId") int tcSrvId,
+ @FormParam("nameId") int nameId,
+ @FormParam("branch") String branch,
+ @FormParam("issueType") String issueType) {
+ CtxListener.getInjector(ctx).getInstance(BoardService.class)
+ .unmuteIssue(tcSrvId, nameId, branch, issueType);
+ }
+
+ @GET
+ @Path("mutedIssues")
+ public Collection<MutedIssueUi> getMutedIssues(@QueryParam("baseBranch") String baseBranch) {
+ return CtxListener.getInjector(ctx).getInstance(BoardService.class).getAllMutedIssues(baseBranch);
+ }
}
diff --git a/ignite-tc-helper-web/src/main/webapp/board/index.html b/ignite-tc-helper-web/src/main/webapp/board/index.html
index 3db0e03..1469b8c 100644
--- a/ignite-tc-helper-web/src/main/webapp/board/index.html
+++ b/ignite-tc-helper-web/src/main/webapp/board/index.html
@@ -22,6 +22,9 @@
<script src="/js/common-1.6.js"></script>
<style>
+ input.solid {border-style: solid;}
+ textarea.solid {border-style: solid;}
+ select.solid {border-style: solid;}
select#selBranch {
border-style: solid;
-webkit-appearance: auto;
@@ -31,6 +34,75 @@
</style>
</head>
<body>
+
+<div id="message" title="Mute issue">
+ <label>Issue</label><br>
+ <textarea rows="2" cols="60" class="solid" id="issueName" readonly></textarea><br>
+ <label>Jira ticket</label><br>
+ <textarea maxlength = "100" rows="2" cols="60" class="solid" id="jiraTicket"></textarea><br>
+ <label>Comment</label><br>
+ <textarea maxlength = "500" rows="7" cols="60" class="solid" id="comment"></textarea><br>
+</div>
+
+<script>
+ $('#message').dialog({
+ autoOpen: false,
+ modal: true,
+ maxWidth:600,
+ maxHeight: 500,
+ width: 600,
+ height: 350,
+ show: {
+ effect: "fade",
+ duration: 1000
+ },
+ hide: {
+ effect: "blind",
+ duration: 500
+ },
+ open: function() {
+ $(this).parent().promise().done(function () {
+ document.getElementById('issueName').value = $("#message").data('issue').name;
+ document.getElementById('jiraTicket').value = '';
+ document.getElementById('comment').value = '';
+ });
+ },
+ close: function() {
+ $(this).parent().promise().done(function () {
+ document.getElementById('issueName').value = '';
+ document.getElementById('jiraTicket').value = '';
+ document.getElementById('comment').value = '';
+ });
+ },
+ buttons: {
+ Mute: function() {
+ document.getElementsByClassName('issue_' + $("#message").data('item').id + '_' + $("#message").data('index')).item(0).value = 'BotMuted';
+ $.ajax({
+ url: "/rest/board/muteIssue",
+ type: 'PUT',
+ data: { tcSrvId: $("#message").data('issue').tcSrvId,
+ nameId: $("#message").data('issue').nameId,
+ trackedBranch: $("#message").data('item').trackedBranch,
+ branch: $("#message").data('item').branch,
+ issueType: $("#message").data('issue').issueType,
+ jiraTicket: document.getElementById('jiraTicket').value,
+ comment: document.getElementById('comment').value,
+ userName: document.getElementById('userName').text,
+ webUrl: $("#message").data('issue').webUrl
+ },
+ error: function (jqXHR, exception) {
+ showErrInLoadStatus(jqXHR, exception);
+ }
+ });
+ $(this).dialog("close");
+ },
+ Cancel: function() {
+ $(this).dialog("close");
+ }
+ }
+ });
+ </script>
+
<script>
var g_shownDataHashCodeHex = "";
let gVue, g_Loading, g_TcBotVersion;
@@ -90,7 +162,14 @@
},
error: showErrInLoadStatus
});
- }
+ },
+ muteModal: function (item, issue, index) {
+ $('#message')
+ .data('item', item)
+ .data('issue', issue)
+ .data('index', index)
+ .dialog("open");
+ },
}
});
}
@@ -207,6 +286,7 @@
:expanded.sync="expanded"
show-expand
dense
+ multi-sort
>
<!-- expand item/row -->
<template v-slot:expanded-item="{ headers, item }">
@@ -220,15 +300,17 @@
Tests affected:
<table>
- <tr v-for="(issue) in item.allIssues">
- <td v-if="issue.status === 'FIXED'">
- Fixed
- </td>
- <td v-else-if="issue.status === 'FAILING'">
- Still Failing
- </td>
- <td v-else>
- {{ issue.status }}
+ <tr v-for="(issue, i) in item.allIssues">
+ <td v-bind:class="'issue_' + item.id + '_' + i">
+ <td v-if="issue.status === 'FIXED'">
+ Fixed
+ </td>
+ <td v-else-if="issue.status === 'FAILING'">
+ Still Failing
+ </td>
+ <td v-else>
+ {{ issue.status }}
+ </td>
</td>
<td>{{ issue.issueType }}</td>
@@ -240,6 +322,11 @@
{{ issue.name }}
</span>
</td>
+ <td>
+ <template v-if="issue.status !== 'BOT_MUTED' && issue.status !== 'FIXED'">
+ <button class="muteModal" v-on:click="muteModal(item, issue, i)">Mute</button>
+ </template>
+ </td>
</tr>
</table>
@@ -293,4 +380,4 @@
<div id="version"></div>
<div style="visibility:hidden;"><div id="triggerConfirm" title="Trigger Confirmation"></div><div id="triggerDialog" title="Trigger Result"></div></div>
</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/ignite-tc-helper-web/src/main/webapp/js/common-1.6.js b/ignite-tc-helper-web/src/main/webapp/js/common-1.6.js
index f80ad3f..8c96d23 100644
--- a/ignite-tc-helper-web/src/main/webapp/js/common-1.6.js
+++ b/ignite-tc-helper-web/src/main/webapp/js/common-1.6.js
@@ -174,6 +174,8 @@ function showMenu(menuData) {
res += "<a href=\"/issues.html\" title='Detected issues list'>Issues history</a>";
res += "<a href=\"/visas.html\" title='Issued TC Bot Visa history'>Visas history</a>";
res += "<a href=\"/mutes.html\" title='Muted tests list'>Muted tests</a>";
+ res += "<a href=\"/mutedissues/index.html\" title='Muted issues list'>Muted issues</a>";
+ res += "<a href=\"/board/index.html\" title='Board'>Board</a>";
res += "<div class='topnav-right'>";
@@ -183,7 +185,7 @@ function showMenu(menuData) {
res += "<a href='/monitoring.html'>Server state</a>";
- res += "<a href='/user.html'>" + userName + "</a>";
+ res += "<a id='userName' href='/user.html'>" + userName + "</a>";
var logout = "/login.html" + "?exit=true&backref=" + encodeURIComponent(window.location.href);
res += "<a href='" + logout + "'>Logout</a>";
diff --git a/ignite-tc-helper-web/src/main/webapp/board/index.html b/ignite-tc-helper-web/src/main/webapp/mutedissues/index.html
similarity index 50%
copy from ignite-tc-helper-web/src/main/webapp/board/index.html
copy to ignite-tc-helper-web/src/main/webapp/mutedissues/index.html
index 3db0e03..d190347 100644
--- a/ignite-tc-helper-web/src/main/webapp/board/index.html
+++ b/ignite-tc-helper-web/src/main/webapp/mutedissues/index.html
@@ -1,6 +1,6 @@
<html>
<head>
- <title>Apache Ignite Teamcity Bot - Tracked branch - Detailed status of failures</title>
+ <title>Apache Ignite Teamcity Bot - Muted issues</title>
<link rel="icon" href="/img/leaf-icon-png-7066.png">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
@@ -22,6 +22,9 @@
<script src="/js/common-1.6.js"></script>
<style>
+ input.solid {border-style: solid;}
+ textarea.solid {border-style: solid;}
+ select.solid {border-style: solid;}
select#selBranch {
border-style: solid;
-webkit-appearance: auto;
@@ -31,7 +34,82 @@
</style>
</head>
<body>
+
+<div id="message" title="Edit issue">
+ <label>Issue</label><br>
+ <textarea rows="2" cols="60" class="solid" id="issueName" readonly></textarea><br>
+ <label>Jira ticket</label><br>
+ <textarea maxlength = "100" rows="2" cols="60" class="solid" id="jiraTicket"></textarea><br>
+ <label>Comment</label><br>
+ <textarea maxlength = "500" rows="7" cols="60" class="solid" id="comment"></textarea><br>
+</div>
+
<script>
+ $('#message').dialog({
+ autoOpen: false,
+ modal: true,
+ maxWidth:600,
+ maxHeight: 500,
+ width: 600,
+ height: 350,
+ show: {
+ effect: "fade",
+ duration: 1000
+ },
+ hide: {
+ effect: "blind",
+ duration: 500
+ },
+ open: function() {
+ $(this).parent().promise().done(function () {
+ document.getElementById('issueName').value = $("#message").data('issue').name;
+ document.getElementById('jiraTicket').value = $("#message").data('issue').jiraTicket;
+ document.getElementById('comment').value = $("#message").data('issue').comment;
+ });
+ },
+ close: function() {
+ $(this).parent().promise().done(function () {
+ document.getElementById('issueName').value = '';
+ document.getElementById('jiraTicket').value = '';
+ document.getElementById('comment').value = '';
+ });
+ },
+ buttons: {
+ Save: function() {
+ $.ajax({
+ url: "/rest/board/updateIssue",
+ type: 'PATCH',
+ data: { tcSrvId: $("#message").data('issue').tcSrvId,
+ nameId: $("#message").data('issue').nameId,
+ branch: $("#message").data('issue').branch,
+ issueType: $("#message").data('issue').issueType,
+ jiraTicket: document.getElementById('jiraTicket').value,
+ comment: document.getElementById('comment').value
+ },
+ error: function (jqXHR, exception) {
+ showErrInLoadStatus(jqXHR, exception);
+ }
+ });
+ $(this).dialog("close");
+ },
+ Unmute: function() {
+ $.ajax({
+ url: "/rest/board/unmuteIssue",
+ type: 'DELETE',
+ data: { tcSrvId: $("#message").data('issue').tcSrvId,
+ nameId: $("#message").data('issue').nameId,
+ branch: $("#message").data('issue').branch,
+ issueType: $("#message").data('issue').issueType
+ }
+ });
+ $(this).dialog("close");
+ },
+ Cancel: function() {
+ $(this).dialog("close");
+ }
+ }
+ });
+
var g_shownDataHashCodeHex = "";
let gVue, g_Loading, g_TcBotVersion;
@@ -59,43 +137,31 @@
data: {
baseBranchSelected: '',
baseBranches: new Set(),
- defects: [],
+ issues: [],
expanded: [],
headers: [
- {text: "Branch", value: 'branch'},
- {text: 'Tags', value: 'tags'},
- {text: 'Suites', value: 'suitesSummary'},
- {text: "Commits", value: 'blameCandidateSummary'},
- {text: "Issues", value: 'cntissues'},
- {text: "Fixed", value: 'cntfixedissues'},
- {text: "Ignored", value: 'cntignoredissues'},
- {text: "Not Fixed", value: 'cntfailingissues'},
- {text: "Unclear", value: 'cntunclearissues'}
+ {text: "Name", value: 'name'},
+ {text: 'Issue type', value: 'issueType'},
+ {text: 'Branch', value: 'trackedBranch'},
+ {text: "Ticket", value: 'jiraTicket'},
+ {text: "Comment", value: 'comment'},
+ {text: "User", value: 'userName'},
+ {text: "Edit", value: 'edit'},
]
},
methods: {
formChanged: function () {
loadDataSilent();
},
-
- onResolve: function (id, force) {
- $.ajax({
- url: "/rest/defect/resolve",
- type: 'POST',
- data: { id: id, forceResolve: force } ,
- success: function (res) {
- window.alert("Resolved defect [" + id + "]");
-
- loadData();
- },
- error: showErrInLoadStatus
- });
- }
+ editModal: function (item) {
+ $('#message')
+ .data('issue', item)
+ .dialog("open");
+ },
}
});
}
-
function parmsForRest() {
var curReqParms = "";
var branch = findGetParameter("branch");
@@ -117,14 +183,13 @@
g_Loading = true;
if (!silent) $("#loadStatus").html("<img src='https://www.wallies.com/filebin/images/loading_apple.gif' width=20px height=20px> Please wait");
- var curFailuresUrl = "/rest/board/summary" + parmsForRest();
+ var curFailuresUrl = "/rest/board/mutedIssues" + parmsForRest();
$.ajax({
url: curFailuresUrl,
success: function (result) {
$("#loadStatus").html("");
showData(result);
- g_shownDataHashCodeHex = isDefinedAndFilled(result.hashCodeHex) ? result.hashCodeHex : "";
g_Loading = false;
},
@@ -163,13 +228,13 @@
}
}
- function showData(result) {
- gVue.$data.defects = result.defects;
+ function showData(issues) {
+ gVue.$data.issues = issues;
branches = [];
- result.defects.forEach(function (defect, index) {
- branches.push(defect.trackedBranch)
+ issues.forEach(function (issue, index) {
+ branches.push(issue.trackedBranch)
});
branches.sort();
@@ -182,7 +247,7 @@
</script>
<div id="loadStatus"></div>
-<div id="vueQueryForm">
+<div id="vueQueryForm" class="h-25">
<div class="formgroup">
<span>Branch:</span>
@@ -195,96 +260,47 @@
</select>
</div>
- <v-app id="queryForm">
-
+ <v-app id="queryForm" class="h-25">
<v-data-table
:headers="headers"
- :items="defects"
- itrackedBranchtem-key="id"
- class="elevation-1"
- sort-by="branch"
- :expanded.sync="expanded"
- show-expand
+ :items="issues"
+ sort-by="name"
dense
+ multi-sort
>
- <!-- expand item/row -->
- <template v-slot:expanded-item="{ headers, item }">
- <td :colspan="headers.length">
- Branch: <a :href="'/current.html?branch=' + item.trackedBranch">{{item.trackedBranch}}</a>
-
- Commits from:
- <div v-for="(candidate) in item.blameCandidates">
- {{ candidate }}
- </div>
-
- Tests affected:
- <table>
- <tr v-for="(issue) in item.allIssues">
- <td v-if="issue.status === 'FIXED'">
- Fixed
+ <template v-slot:item="{ headers, item }">
+ <tr>
+ <td style="width:20%">
+ <a v-if="item.webUrl !== null && item.webUrl !== ''" :href="item.webUrl">
+ {{ item.name }}
+ </a>
+ <span v-else>
+ {{ item.name }}
+ </span>
</td>
- <td v-else-if="issue.status === 'FAILING'">
- Still Failing
+ <td style="width:10%">
+ {{ item.issueType }}
</td>
- <td v-else>
- {{ issue.status }}
+ <td style="width:10%">
+ {{ item.trackedBranch }}
</td>
-
- <td>{{ issue.issueType }}</td>
- <td>
- <a v-if="issue.webUrl != null" :href="issue.webUrl">
- {{ issue.name }}
+ <td style="width:15%">
+ <a :href="item.jiraTicket">
+ {{ item.jiraTicket }}
</a>
- <span v-else>
- {{ issue.name }}
- </span>
+ </td>
+ <td style="width:35%">
+ {{ item.comment }}
+ </td>
+ <td style="width:5%">
+ {{ item.userName }}
+ </td>
+ <td style="width:5%">
+ <button class="editModal" v-on:click="editModal(item)">Edit</button>
</td>
</tr>
- </table>
-
- <button v-if="item.cntFailingIssues === 0" v-on:click="onResolve(item.id, false)">Resolve</button>
- <button v-if="item.forceResolveAllowed === true" v-on:click="onResolve(item.id, true)" class='disabledbtn'>Force resolve</button>
- </td>
- </template>
-
- <template v-slot:item.tags="{ item }">
- <span v-for="(tag) in item.tags">
- {{ tag }}
- </span>
</template>
-
- <template v-slot:item.suites="{ item }">
- <span v-for="(suite) in item.suites">
- {{ suite }}
- </span>
- </template>
-
- <template v-slot:item.cntIssues="{ item }">
- {{ item.cntIssues }}
- </template>
- <template v-slot:item.cntFixedIssues="{ item }">
- <span class='visaStage' style="background: #12AD5E"
- v-if="item.cntFixedIssues!=0"
- :title="item.summaryFixedIssues"> {{ item.cntFixedIssues }} </span>
- </template>
- <template v-slot:item.cntIgnoredIssues="{ item }">
- <span class='visaStage' style="background: darkorange"
- v-if="item.cntIgnoredIssues!=0"
- :title="item.summaryIgnoredIssues"> {{ item.cntIgnoredIssues }} </span>
- </template>
- <template v-slot:item.cntFailingIssues="{ item }" >
- <span class='visaStage' style="background: red"
- v-if="item.cntFailingIssues!=0"
- :title="item.summaryFailingIssues"> {{ item.cntFailingIssues }} </span>
- </template>
-
- <template v-slot:item.cntUnclearIssues="{ item }" >
- <span class='visaStage' style="background: grey"
- v-if="item.cntUnclearIssues!=0"
- :title="item.summaryUnclearIssues" > {{ item.cntUnclearIssues }} </span>
- </template>
-
</v-data-table>
</v-app>
@@ -293,4 +309,4 @@
<div id="version"></div>
<div style="visibility:hidden;"><div id="triggerConfirm" title="Trigger Confirmation"></div><div id="triggerDialog" title="Trigger Result"></div></div>
</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/TcBotEngineModule.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/TcBotEngineModule.java
index 657de21..cc0ed61 100644
--- a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/TcBotEngineModule.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/TcBotEngineModule.java
@@ -21,12 +21,12 @@ import com.google.inject.AbstractModule;
import com.google.inject.internal.SingletonScope;
import org.apache.ignite.tcbot.common.TcBotCommonModule;
import org.apache.ignite.tcbot.engine.board.BoardService;
+import org.apache.ignite.tcbot.engine.boardmute.MutedIssuesDao;
import org.apache.ignite.tcbot.engine.build.SingleBuildResultsService;
import org.apache.ignite.tcbot.engine.buildtime.BuildTimeService;
import org.apache.ignite.tcbot.engine.chain.BuildChainProcessor;
import org.apache.ignite.tcbot.engine.issue.IIssuesStorage;
import org.apache.ignite.tcbot.engine.issue.IssuesStorage;
-import org.apache.ignite.tcbot.engine.newtests.NewTestsStorage;
import org.apache.ignite.tcbot.engine.tracked.IDetailedStatusForTrackedBranch;
import org.apache.ignite.tcbot.engine.tracked.TrackedBranchChainsProcessor;
import org.apache.ignite.tcbot.engine.user.IUserStorage;
@@ -50,7 +50,7 @@ public class TcBotEngineModule extends AbstractModule {
bind(IUserStorage.class).to(UserAndSessionsStorage.class).in(new SingletonScope());
- bind(NewTestsStorage.class).in(new SingletonScope());
+ bind(MutedIssuesDao.class).in(new SingletonScope());
install(new TcBotCommonModule());
}
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/board/BoardService.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/board/BoardService.java
index 4e8001e..7144d7c 100644
--- a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/board/BoardService.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/board/BoardService.java
@@ -20,6 +20,7 @@ import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -29,7 +30,6 @@ import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import javax.inject.Inject;
@@ -43,6 +43,8 @@ import org.apache.ignite.ci.user.TcHelperUser;
import org.apache.ignite.tcbot.common.conf.ITcServerConfig;
import org.apache.ignite.tcbot.common.interceptor.MonitoredTask;
import org.apache.ignite.tcbot.common.util.FutureUtil;
+import org.apache.ignite.tcbot.engine.boardmute.MutedIssuesDao;
+import org.apache.ignite.tcbot.engine.boardmute.MutedIssueKey;
import org.apache.ignite.tcbot.engine.chain.BuildChainProcessor;
import org.apache.ignite.tcbot.engine.chain.SingleBuildRunCtx;
import org.apache.ignite.tcbot.engine.conf.ITcBotConfig;
@@ -58,16 +60,22 @@ import org.apache.ignite.tcbot.engine.ui.BoardDefectSummaryUi;
import org.apache.ignite.tcbot.engine.ui.BoardSummaryUi;
import org.apache.ignite.tcbot.engine.ui.DsSuiteUi;
import org.apache.ignite.tcbot.engine.ui.DsTestFailureUi;
+import org.apache.ignite.tcbot.engine.ui.MutedIssueUi;
import org.apache.ignite.tcbot.engine.user.IUserStorage;
import org.apache.ignite.tcbot.persistence.IStringCompactor;
import org.apache.ignite.tcbot.persistence.scheduler.IScheduler;
import org.apache.ignite.tcignited.ITeamcityIgnited;
import org.apache.ignite.tcignited.ITeamcityIgnitedProvider;
+import org.apache.ignite.tcbot.engine.boardmute.MutedIssueInfo;
import org.apache.ignite.tcignited.build.FatBuildDao;
import org.apache.ignite.tcignited.build.ITest;
import org.apache.ignite.tcignited.creds.ICredentialsProv;
import org.apache.ignite.tcignited.history.IRunHistory;
+import static java.util.stream.Collectors.toList;
+import static org.apache.ignite.tcbot.engine.board.IssueResolveStatus.BOT_MUTED;
+import static org.apache.ignite.tcbot.engine.boardmute.MutedIssueKey.parseName;
+import static org.apache.ignite.tcbot.engine.issue.IssueType.convertDisplayName;
import static org.apache.ignite.tcignited.history.RunStatus.RES_MISSING;
import static org.apache.ignite.tcignited.history.RunStatus.RES_OK;
@@ -75,6 +83,7 @@ public class BoardService {
@Inject IIssuesStorage issuesStorage;
@Inject FatBuildDao fatBuildDao;
@Inject ChangeDao changeDao;
+ @Inject MutedIssuesDao mutedIssuesDao;
@Inject ITeamcityIgnitedProvider tcProv;
@Inject DefectsStorage defectStorage;
@Inject IScheduler scheduler;
@@ -126,7 +135,7 @@ public class BoardService {
List<Future<FatBuildCompacted>> futures = buildChainProcessor.replaceWithRecent(fatBuild, allBuildsMap, tcIgn);
Stream<FatBuildCompacted> results = FutureUtil.getResults(futures);
- List<FatBuildCompacted> freshRebuild = results.collect(Collectors.toList());
+ List<FatBuildCompacted> freshRebuild = results.collect(toList());
Optional<FatBuildCompacted> rebuild;
@@ -138,6 +147,17 @@ public class BoardService {
BoardDefectIssueUi issueUi = processIssue(tcIgn, rebuild, issue, firstBuild.buildTypeId());
if (issueUi.status() != IssueResolveStatus.FIXED)
defectUi.addTags(tags);
+
+ issueUi.setTcSrvId(next.tcSrvId());
+
+ MutedIssueKey issueKey = new MutedIssueKey(next.tcSrvId(), issue.testNameCid(),
+ fatBuild.branchName(), IssueType.valueOf(compactor.getStringFromId(issue.issueTypeCode())));
+
+ MutedIssueInfo mutedIssueInfo = mutedIssuesDao.getMutedIssue(issueKey);
+
+ if (mutedIssueInfo != null)
+ issueUi.setStatus(BOT_MUTED);
+
defectUi.addIssue(issueUi);
}
}
@@ -192,8 +212,10 @@ public class BoardService {
if (testResult.isPresent()) {
ITest test = testResult.get();
- if (test.isIgnoredTest() || test.isMutedTest())
+ if (test.isIgnoredTest())
status = IssueResolveStatus.IGNORED;
+ else if (test.isMutedTest())
+ status = IssueResolveStatus.TC_MUTED;
else if (IssueType.newTestWithHighFlakyRate.code().equals(issueType)) {
int fullSuiteNameAndFullTestName = issue.testNameCid();
@@ -377,4 +399,124 @@ public class BoardService {
defectStorage.save(defect);
}
+
+ public void muteIssue(
+ int tcSrvId,
+ int nameId,
+ String branch,
+ String trackedBranch,
+ String issueType,
+ String jiraTicket,
+ String comment,
+ String userName,
+ String webUrl) {
+
+ if (branch == null || trackedBranch == null || issueType == null|| jiraTicket == null||
+ comment == null || userName == null || webUrl == null ||
+ userName.isEmpty() ||
+ jiraTicket.length() > 100 || comment.length() > 500 ||
+ userName.length() > 100 || webUrl.length() > 250
+ )
+ throw new IllegalArgumentException(String.format("branch: %s, trackedBranch: %s, issueType: %s, jiraTicket: %s, " +
+ "comment: %s, userName: %s, webUrl: %s, ",
+ String.valueOf(branch), String.valueOf(trackedBranch), String.valueOf(issueType), String.valueOf(jiraTicket),
+ String.valueOf(comment), String.valueOf(userName), String.valueOf(webUrl)));
+
+ Integer branchId = compactor.getStringIdIfPresent(branch);
+
+ if (branchId <= 0)
+ throw new IllegalArgumentException("There is no id in the stringsCache for string: \"" + branch + "\"");
+
+ MutedIssueKey issueKey = new MutedIssueKey(tcSrvId, nameId, branchId, IssueType.valueOf(issueType));
+
+ if (mutedIssuesDao.getMutedIssue(issueKey) == null) {
+ Integer trackedBranchId = compactor.getStringIdIfPresent(trackedBranch);
+
+ if (trackedBranchId <= 0)
+ throw new IllegalArgumentException("There is no id in the stringsCache for string: \"" + trackedBranch + "\"");
+
+ MutedIssueInfo issueInfo = new MutedIssueInfo(trackedBranchId, userName, jiraTicket, comment, webUrl);
+
+ mutedIssuesDao.putIssue(issueKey, issueInfo);
+ }
+ }
+
+ public void updateIssue(
+ int tcSrvId,
+ int nameId,
+ String branch,
+ String issueType,
+ String jiraTicket,
+ String comment) {
+
+ if (branch == null || issueType == null|| jiraTicket == null|| comment == null ||
+ jiraTicket.length() > 100 || comment.length() > 500
+ )
+ throw new IllegalArgumentException(String.format("branch: %s, issueType: %s, jiraTicket: %s, comment: %s",
+ String.valueOf(branch), String.valueOf(issueType), String.valueOf(jiraTicket), String.valueOf(comment)));
+
+ Integer branchId = compactor.getStringIdIfPresent(branch);
+
+ if (branchId <= 0)
+ throw new IllegalArgumentException("There is no id in the stringsCache for string: \"" + branch + "\"");
+
+ MutedIssueKey issueKey = new MutedIssueKey(tcSrvId, nameId, branchId, convertDisplayName(issueType));
+
+ MutedIssueInfo issueInfo = mutedIssuesDao.getMutedIssue(issueKey);
+
+ if (issueInfo != null) {
+ issueInfo.setJiraTicket(jiraTicket);
+
+ issueInfo.setComment(comment);
+
+ mutedIssuesDao.putIssue(issueKey, issueInfo);
+ }
+ }
+
+ public void unmuteIssue(
+ int tcSrvId,
+ int nameId,
+ String branch,
+ String issueType) {
+ MutedIssueKey issueKey = new MutedIssueKey(tcSrvId, nameId, compactor.getStringId(branch), convertDisplayName(issueType));
+
+ mutedIssuesDao.removeIssue(issueKey);
+ }
+
+ public Collection<MutedIssueUi> getAllMutedIssues(String baseBranch) {
+ return mutedIssuesDao.getAllMutedIssues().entrySet().stream()
+ .map(entry -> {
+ MutedIssueKey key = entry.getKey();
+ MutedIssueInfo value = entry.getValue();
+
+ MutedIssueUi issueUi = new MutedIssueUi();
+
+ issueUi.tcSrvId = key.getTcSrvId();
+ issueUi.nameId = key.getNameId();
+ issueUi.branch = compactor.getStringFromId(key.branchNameId());
+ issueUi.trackedBranch = compactor.getStringFromId(value.getTrackedBranchId());
+ issueUi.issueType = key.getIssueType().displayName();
+ issueUi.userName = value.getUserName();
+ issueUi.jiraTicket = value.getJiraTicket();
+ issueUi.comment = value.getComment();
+ issueUi.webUrl = value.getWebUrl();
+
+ if (key.getIssueType() == IssueType.newCriticalFailure
+ || key.getIssueType() == IssueType.newTrustedSuiteFailure)
+ issueUi.name = compactor.getStringFromId(key.getNameId());
+ else
+ issueUi.name = parseName(compactor.getStringFromId(key.getNameId()));
+
+ return issueUi;
+ })
+ .filter(issue -> {
+ if (baseBranch == null || baseBranch.equals("") || issue.trackedBranch.equals(baseBranch))
+ return true;
+ else
+ return false;
+
+ })
+ .sorted(Comparator.comparing(MutedIssueUi::getName).thenComparing(MutedIssueUi::getIssueType))
+ .collect(toList());
+ }
}
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/board/IssueResolveStatus.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/board/IssueResolveStatus.java
index d76fac9..c7c4393 100644
--- a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/board/IssueResolveStatus.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/board/IssueResolveStatus.java
@@ -17,5 +17,5 @@
package org.apache.ignite.tcbot.engine.board;
public enum IssueResolveStatus {
- FIXED, FAILING, IGNORED, UNKNOWN
+ FIXED, FAILING, IGNORED, TC_MUTED, BOT_MUTED, UNKNOWN
}
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/boardmute/MutedIssueInfo.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/boardmute/MutedIssueInfo.java
new file mode 100644
index 0000000..d346dbd
--- /dev/null
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/boardmute/MutedIssueInfo.java
@@ -0,0 +1,78 @@
+/*
+ * 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.tcbot.engine.boardmute;
+
+public class MutedIssueInfo {
+ private int trackedBranchId;
+
+ private String userName;
+
+ private String jiraTicket;
+
+ private String comment;
+
+ private String webUrl;
+
+ public MutedIssueInfo(int trackedBranchId, String userName, String jiraTicket, String comment, String webUrl) {
+ this.trackedBranchId = trackedBranchId;
+ this.userName = userName;
+ this.jiraTicket = jiraTicket;
+ this.comment = comment;
+ this.webUrl = webUrl;
+ }
+
+ public int getTrackedBranchId() {
+ return trackedBranchId;
+ }
+
+ public void setTrackedBranchId(int trackedBranchId) {
+ this.trackedBranchId = trackedBranchId;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getJiraTicket() {
+ return jiraTicket;
+ }
+
+ public void setJiraTicket(String jiraTicket) {
+ this.jiraTicket = jiraTicket;
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+
+ public String getWebUrl() {
+ return webUrl;
+ }
+
+ public void setWebUrl(String webUrl) {
+ this.webUrl = webUrl;
+ }
+}
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/boardmute/MutedIssueKey.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/boardmute/MutedIssueKey.java
new file mode 100644
index 0000000..9c7085e
--- /dev/null
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/boardmute/MutedIssueKey.java
@@ -0,0 +1,87 @@
+/*
+ * 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.tcbot.engine.boardmute;
+
+import com.google.common.base.Strings;
+import org.apache.ignite.tcbot.engine.issue.IssueType;
+import org.apache.ignite.tcbot.engine.ui.ShortTestFailureUi;
+
+public class MutedIssueKey {
+ private int tcSrvId;
+
+ private int nameId;
+
+ private int branchId;
+
+ private IssueType issueType;
+
+ public MutedIssueKey(int tcSrvId, int nameId, int branchId, IssueType issueType) {
+ this.tcSrvId = tcSrvId;
+ this.nameId = nameId;
+ this.branchId = branchId;
+ this.issueType = issueType;
+ }
+
+ public int getTcSrvId() {
+ return tcSrvId;
+ }
+
+ public void setTcSrvId(int tcSrvId) {
+ this.tcSrvId = tcSrvId;
+ }
+
+ public int getNameId() {
+ return nameId;
+ }
+
+ public void setNameId(int nameId) {
+ this.nameId = nameId;
+ }
+
+ public int branchNameId() {
+ return branchId;
+ }
+
+ public void setBranchId(int branchId) {
+ this.branchId = branchId;
+ }
+
+ public IssueType getIssueType() {
+ return issueType;
+ }
+
+ public void setIssueType(IssueType issueType) {
+ this.issueType = issueType;
+ }
+
+ public static String parseName(String name) {
+ String suiteName = null, testName = null;
+
+ String[] split = Strings.nullToEmpty(name).split("\\:");
+ if (split.length >= 2) {
+ suiteName = ShortTestFailureUi.extractSuite(split[0]);
+ testName = ShortTestFailureUi.extractTest(split[1]);
+ }
+
+ if (testName != null && suiteName != null)
+ return suiteName + ":" + testName;
+
+ return name;
+
+ }
+}
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/boardmute/MutedIssuesDao.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/boardmute/MutedIssuesDao.java
new file mode 100644
index 0000000..9054c02
--- /dev/null
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/boardmute/MutedIssuesDao.java
@@ -0,0 +1,60 @@
+/*
+ * 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.tcbot.engine.boardmute;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.inject.Inject;
+import javax.inject.Provider;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.tcbot.persistence.CacheConfigs;
+
+/**
+ *
+ */
+public class MutedIssuesDao {
+ /** Cache name. */
+ private static final String BOARD_MUTE_CACHE_NAME = "mutedIssues";
+
+ /** Ignite provider. */
+ @Inject private Provider<Ignite> igniteProvider;
+
+ /** */
+ public IgniteCache<MutedIssueKey, MutedIssueInfo> cache() {
+ return igniteProvider.get().getOrCreateCache(CacheConfigs.getCache8PartsConfig(BOARD_MUTE_CACHE_NAME));
+ }
+
+ public void putIssue(MutedIssueKey issueKey, MutedIssueInfo issueInfo) {
+ cache().put(issueKey, issueInfo);
+ }
+
+ public void removeIssue(MutedIssueKey issueKey) {
+ cache().remove(issueKey);
+ }
+
+ public MutedIssueInfo getMutedIssue(MutedIssueKey issueKey) {
+ return cache().get(issueKey);
+ }
+
+ public Map<MutedIssueKey, MutedIssueInfo> getAllMutedIssues() {
+ Map<MutedIssueKey, MutedIssueInfo> issues = new HashMap<>();
+ cache().forEach(e -> issues.put(e.getKey(), e.getValue()));
+ return issues;
+ }
+}
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/IssueType.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/IssueType.java
index 25171c4..7ba27b1 100644
--- a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/IssueType.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/IssueType.java
@@ -44,6 +44,25 @@ public enum IssueType {
/** Display name. */
private final String displayName;
+ static public IssueType convertDisplayName(String displayName) {
+ switch (displayName) {
+ case "New test failure":
+ return newFailure;
+ case "Recently contributed test failed":
+ return newContributedTestFailure;
+ case "New stable failure of a flaky test":
+ return newFailureForFlakyTest;
+ case "New Critical Failure":
+ return newCriticalFailure;
+ case "New Trusted Suite failure":
+ return newTrustedSuiteFailure;
+ case "Test with high flaky rate":
+ return newTestWithHighFlakyRate;
+ }
+
+ throw new IllegalArgumentException("Illegal issue type: " + displayName);
+ }
+
/**
* @param code Code.
* @param displayName Display name.
@@ -66,4 +85,5 @@ public enum IssueType {
public String displayName() {
return displayName;
}
+
}
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BoardDefectIssueUi.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BoardDefectIssueUi.java
index ee05ba1..b005147 100644
--- a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BoardDefectIssueUi.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BoardDefectIssueUi.java
@@ -31,6 +31,7 @@ public class BoardDefectIssueUi {
private transient IStringCompactor compactor;
private transient DefectIssue issue;
private boolean suiteProblem;
+ private int tcSrvId;
@Nullable
private String webUrl;
private IssueResolveStatus status;
@@ -66,6 +67,10 @@ public class BoardDefectIssueUi {
}
+ public int getNameId() {
+ return issue.testNameCid();
+ }
+
public String getIssueType() {
return compactor.getStringFromId(issue.issueTypeCode());
}
@@ -78,8 +83,20 @@ public class BoardDefectIssueUi {
return status;
}
+ public void setStatus(IssueResolveStatus status) {
+ this.status = status;
+ }
+
@Nullable
public String getWebUrl() {
return webUrl;
}
+
+ public int getTcSrvId() {
+ return tcSrvId;
+ }
+
+ public void setTcSrvId(int tcSrvId) {
+ this.tcSrvId = tcSrvId;
+ }
}
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BoardDefectSummaryUi.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BoardDefectSummaryUi.java
index 035aefe..7b99cbd 100644
--- a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BoardDefectSummaryUi.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BoardDefectSummaryUi.java
@@ -135,8 +135,15 @@ public class BoardDefectSummaryUi {
return issuesList.size();
}
- private Stream<BoardDefectIssueUi> issues(IssueResolveStatus type) {
- return issuesList.stream().filter(iss -> iss.status() == type);
+ private Stream<BoardDefectIssueUi> issues(IssueResolveStatus... types) {
+ return issuesList.stream().filter(iss -> {
+ for (IssueResolveStatus type : types) {
+ if (iss.status() == type)
+ return true;
+ }
+
+ return false;
+ });
}
public List<BoardDefectIssueUi> getIgnoredIssues() {
@@ -148,7 +155,7 @@ public class BoardDefectSummaryUi {
}
public Integer getCntIgnoredIssues() {
- return (int) issues(IssueResolveStatus.IGNORED).count();
+ return (int) issues(IssueResolveStatus.IGNORED, IssueResolveStatus.TC_MUTED, IssueResolveStatus.BOT_MUTED).count();
}
public List<BoardDefectIssueUi> getFailingIssues() {
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/MutedIssueUi.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/MutedIssueUi.java
new file mode 100644
index 0000000..dba6e76
--- /dev/null
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/MutedIssueUi.java
@@ -0,0 +1,120 @@
+/*
+ * 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.tcbot.engine.ui;
+
+public class MutedIssueUi {
+ public int tcSrvId;
+
+ public int nameId;
+
+ public String name;
+
+ public String branch;
+
+ public String trackedBranch;
+
+ public String issueType;
+
+ public String userName;
+
+ public String jiraTicket;
+
+ public String comment;
+
+ public String webUrl;
+
+ public int getTcSrvId() {
+ return tcSrvId;
+ }
+
+ public void setTcSrvId(int tcSrvId) {
+ this.tcSrvId = tcSrvId;
+ }
+
+ public int getNameId() {
+ return nameId;
+ }
+
+ public void setNameId(int nameId) {
+ this.nameId = nameId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getBranch() {
+ return branch;
+ }
+
+ public void setBranch(String branch) {
+ this.branch = branch;
+ }
+
+ public String getTrackedBranch() {
+ return trackedBranch;
+ }
+
+ public void setTrackedBranch(String trackedBranch) {
+ this.trackedBranch = trackedBranch;
+ }
+
+ public String getIssueType() {
+ return issueType;
+ }
+
+ public void setIssueType(String issueType) {
+ this.issueType = issueType;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getJiraTicket() {
+ return jiraTicket;
+ }
+
+ public void setJiraTicket(String jiraTicket) {
+ this.jiraTicket = jiraTicket;
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+
+ public String getWebUrl() {
+ return webUrl;
+ }
+
+ public void setWebUrl(String webUrl) {
+ this.webUrl = webUrl;
+ }
+}
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildlog/BuildLogProcessor.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildlog/BuildLogProcessor.java
index 58dbeed..67bf01e 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildlog/BuildLogProcessor.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildlog/BuildLogProcessor.java
@@ -78,7 +78,14 @@ class BuildLogProcessor implements IBuildLogProcessor {
logCheckResultCompacted = new LogCheckResultCompacted();
}
- logCheckResultDao.put(teamcity.serverCode(), buildId, logCheckResultCompacted);
+ try {
+ logCheckResultDao.put(teamcity.serverCode(), buildId, logCheckResultCompacted);
+ }
+ catch (Exception ex) {
+ logger.error("serverCode: " + teamcity.serverCode() + "; buildId: " + buildId +
+ "; logCheck: " + logCheckResultCompacted.toString());
+ throw ex;
+ }
return logCheckResultCompacted;
});