This is an automated email from the ASF dual-hosted git repository.

dpavlov pushed a commit to branch ignite-9800-2
in repository https://gitbox.apache.org/repos/asf/ignite-teamcity-bot.git

commit 49aa7e9c669f6a728137726a50a84258e5cfdd20
Author: Dmitriy Pavlov <[email protected]>
AuthorDate: Sat Oct 6 21:09:07 2018 +0300

    IGNITE-9800: Faster builds search engine development: not used yet
---
 .../main/java/org/apache/ignite/ci/ITcHelper.java  |   1 +
 .../main/java/org/apache/ignite/ci/TcHelper.java   |   1 +
 .../org/apache/ignite/ci/di/IgniteTcBotModule.java |   5 +-
 .../ignite/ci/di/MonitoredTaskInterceptor.java     |  19 +--
 .../org/apache/ignite/ci/issue/IssueDetector.java  |   2 +-
 .../org/apache/ignite/ci/jobs/CheckQueueJob.java   |   2 +-
 .../apache/ignite/ci/observer/ObserverTask.java    |   2 +-
 .../ignite/ci/tcbot/TcBotSystemProperties.java     |   2 +
 .../ignite/ci/tcbot/chain/PrChainsProcessor.java   |   2 +-
 .../tcbot/chain/TrackedBranchChainsProcessor.java  |   2 +-
 .../tcbot/visa/TcBotTriggerAndSignOffService.java  |  30 +++-
 .../ignited/BuildRefCompacted.java}                |  25 ++-
 .../ignited/IStringCompacter.java}                 |   8 +-
 .../ignited/ITeamcityIgnited.java}                 |  11 +-
 .../ignited/ITeamcityIgnitedProvider.java}         |   8 +-
 .../IgniteStringCompacter.java}                    |  33 ++--
 .../ignited/TcIgnitedCachingProvider.java}         |  52 +++---
 .../ci/teamcity/ignited/TeamcityIgnitedImpl.java   | 187 +++++++++++++++++++++
 .../TeamcityIgnitedModule.java}                    |  11 +-
 .../ci/{ => teamcity/pure}/ITcServerProvider.java  |   3 +-
 .../ignite/ci/teamcity/pure/TcLoginImpl.java       |   2 +-
 .../ci/teamcity/pure/TcRealConnectionModule.java   |   1 +
 .../pure}/TcServerCachingProvider.java             |  43 +++--
 .../ignite/ci/teamcity/pure/TeamcityRecorder.java  |   5 +-
 .../teamcity/pure/TeamcityRecordingConnection.java |   1 +
 .../java/org/apache/ignite/ci/web/CtxListener.java |   2 +-
 .../ignite/ci/web/rest/visa/TcBotVisaService.java  |  24 ++-
 .../org/apache/ignite/ci/di/DiContextTest.java     |   4 +-
 28 files changed, 372 insertions(+), 116 deletions(-)

diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/ITcHelper.java 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/ITcHelper.java
index 5d68ce9..00623f7 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/ITcHelper.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/ITcHelper.java
@@ -20,6 +20,7 @@ package org.apache.ignite.ci;
 import java.util.List;
 import org.apache.ignite.ci.issue.IssueDetector;
 import org.apache.ignite.ci.issue.IssuesStorage;
+import org.apache.ignite.ci.teamcity.pure.ITcServerProvider;
 import org.apache.ignite.ci.user.ICredentialsProv;
 import org.apache.ignite.ci.user.UserAndSessionsStorage;
 
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/TcHelper.java 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/TcHelper.java
index 5be9135..5e0422d 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/TcHelper.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/TcHelper.java
@@ -24,6 +24,7 @@ import org.apache.ignite.ci.issue.IssuesStorage;
 import org.apache.ignite.ci.jira.IJiraIntegration;
 import org.apache.ignite.ci.tcmodel.hist.BuildRef;
 import org.apache.ignite.ci.tcmodel.result.problems.ProblemOccurrence;
+import org.apache.ignite.ci.teamcity.pure.ITcServerProvider;
 import org.apache.ignite.ci.user.ICredentialsProv;
 import org.apache.ignite.ci.user.UserAndSessionsStorage;
 import org.apache.ignite.ci.web.model.current.ChainAtServerCurrentStatus;
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/IgniteTcBotModule.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/IgniteTcBotModule.java
index 2f802d4..a3fcc60 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/IgniteTcBotModule.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/IgniteTcBotModule.java
@@ -31,6 +31,7 @@ import org.apache.ignite.ci.issue.IssueDetector;
 import org.apache.ignite.ci.jira.IJiraIntegration;
 import org.apache.ignite.ci.observer.BuildObserver;
 import org.apache.ignite.ci.observer.ObserverTask;
+import org.apache.ignite.ci.teamcity.ignited.TeamcityIgnitedModule;
 import org.apache.ignite.ci.teamcity.pure.TcRealConnectionModule;
 import org.apache.ignite.ci.user.ICredentialsProv;
 import org.apache.ignite.ci.util.ExceptionUtil;
@@ -75,7 +76,6 @@ public class IgniteTcBotModule extends AbstractModule {
         //With REST persistence
         
bind(IAnalyticsEnabledTeamcity.class).to(IgnitePersistentTeamcity.class);
         
bind(ITcServerFactory.class).to(InitializingServerFactory.class).in(new 
SingletonScope());
-        bind(ITcServerProvider.class).to(TcServerCachingProvider.class).in(new 
SingletonScope());
         bind(TcUpdatePool.class).in(new SingletonScope());
         bind(IssueDetector.class).in(new SingletonScope());
         bind(ObserverTask.class).in(new SingletonScope());
@@ -85,7 +85,8 @@ public class IgniteTcBotModule extends AbstractModule {
         bind(IJiraIntegration.class).to(Jira.class).in(new SingletonScope());
 
         bind(BackgroundUpdater.class).in(new SingletonScope());
-        install(new TcRealConnectionModule());
+
+        install(new TeamcityIgnitedModule());
         install(new GitHubIgnitedModule());
         install(new SchedulerModule());
     }
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/MonitoredTaskInterceptor.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/MonitoredTaskInterceptor.java
index 45fb425..262530c 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/MonitoredTaskInterceptor.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/MonitoredTaskInterceptor.java
@@ -86,8 +86,7 @@ public class MonitoredTaskInterceptor implements 
MethodInterceptor {
         }
     }
 
-    @Override
-    public Object invoke(MethodInvocation invocation) throws Throwable {
+    @Override public Object invoke(MethodInvocation invocation) throws 
Throwable {
         final long startTs = System.currentTimeMillis();
 
         String fullKey = taskName(invocation);
@@ -121,21 +120,19 @@ public class MonitoredTaskInterceptor implements 
MethodInterceptor {
 
         final MonitoredTask annotation = 
method.getAnnotation(MonitoredTask.class);
         if (annotation != null) {
-            if (!Strings.isNullOrEmpty(annotation.name())) {
-                fullKey = annotation.name();
-            } else {
-                fullKey = cls + "." + mtd;
-            }
+            String activityName = annotation.name();
+
+            fullKey = !Strings.isNullOrEmpty(activityName) ? activityName : 
cls + "." + mtd;
 
             final Object[] arguments = invocation.getArguments();
 
             final int idx = annotation.nameExtArgIndex();
-            if(arguments!=null && idx >=0 && idx<arguments.length) {
+            if (arguments != null && idx >= 0 && idx < arguments.length)
                 fullKey += "." + Objects.toString(arguments[idx]);
-            }
-        } else {
-            fullKey = cls + "." + mtd;
         }
+        else
+            fullKey = cls + "." + mtd;
+
         return fullKey;
     }
 
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueDetector.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueDetector.java
index 7e2afa8..405f0ea 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueDetector.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueDetector.java
@@ -35,7 +35,7 @@ import javax.inject.Provider;
 import org.apache.ignite.ci.HelperConfig;
 import org.apache.ignite.ci.IAnalyticsEnabledTeamcity;
 import org.apache.ignite.ci.ITcHelper;
-import org.apache.ignite.ci.ITcServerProvider;
+import org.apache.ignite.ci.teamcity.pure.ITcServerProvider;
 import org.apache.ignite.ci.ITeamcity;
 import org.apache.ignite.ci.analysis.RunStat;
 import org.apache.ignite.ci.analysis.SuiteInBranch;
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jobs/CheckQueueJob.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jobs/CheckQueueJob.java
index 5a15afa..5535595 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jobs/CheckQueueJob.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jobs/CheckQueueJob.java
@@ -27,7 +27,7 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import jersey.repackaged.com.google.common.base.Throwables;
 import org.apache.ignite.ci.HelperConfig;
-import org.apache.ignite.ci.ITcServerProvider;
+import org.apache.ignite.ci.teamcity.pure.ITcServerProvider;
 import org.apache.ignite.ci.ITeamcity;
 import org.apache.ignite.ci.conf.BranchTracked;
 import org.apache.ignite.ci.conf.ChainAtServerTracked;
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/observer/ObserverTask.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/observer/ObserverTask.java
index 374099b..d0a222e 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/observer/ObserverTask.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/observer/ObserverTask.java
@@ -24,7 +24,7 @@ import java.util.TimerTask;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import javax.inject.Inject;
 import org.apache.ignite.ci.IAnalyticsEnabledTeamcity;
-import org.apache.ignite.ci.ITcServerProvider;
+import org.apache.ignite.ci.teamcity.pure.ITcServerProvider;
 import org.apache.ignite.ci.di.AutoProfiling;
 import org.apache.ignite.ci.di.MonitoredTask;
 import org.apache.ignite.ci.jira.IJiraIntegration;
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotSystemProperties.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotSystemProperties.java
index a77dbd2..f5ae24c 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotSystemProperties.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotSystemProperties.java
@@ -19,4 +19,6 @@ package org.apache.ignite.ci.tcbot;
 
 public class TcBotSystemProperties {
     public static final String DEV_MODE = "DEV_MODE";
+    public static final String TEAMCITY_BOT_RECORDER_URLS = 
"teamcity.bot.recorder.urls";
+    public static final String TEAMCITY_BOT_RECORDER = "teamcity.bot.recorder";
 }
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessor.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessor.java
index be2a7a3..9f65be2 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessor.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessor.java
@@ -18,7 +18,7 @@ package org.apache.ignite.ci.tcbot.chain;
 
 import com.google.common.base.Strings;
 import org.apache.ignite.ci.IAnalyticsEnabledTeamcity;
-import org.apache.ignite.ci.ITcServerProvider;
+import org.apache.ignite.ci.teamcity.pure.ITcServerProvider;
 import org.apache.ignite.ci.ITeamcity;
 import org.apache.ignite.ci.analysis.FullChainRunCtx;
 import org.apache.ignite.ci.analysis.mode.LatestRebuildMode;
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/TrackedBranchChainsProcessor.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/TrackedBranchChainsProcessor.java
index c29a964..ccb8b32 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/TrackedBranchChainsProcessor.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/TrackedBranchChainsProcessor.java
@@ -23,7 +23,7 @@ import java.util.stream.Collectors;
 import javax.inject.Inject;
 import org.apache.ignite.ci.HelperConfig;
 import org.apache.ignite.ci.IAnalyticsEnabledTeamcity;
-import org.apache.ignite.ci.ITcServerProvider;
+import org.apache.ignite.ci.teamcity.pure.ITcServerProvider;
 import org.apache.ignite.ci.analysis.FullChainRunCtx;
 import org.apache.ignite.ci.analysis.mode.LatestRebuildMode;
 import org.apache.ignite.ci.analysis.mode.ProcessLogsMode;
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java
index d3429e3..70a5096 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java
@@ -23,7 +23,10 @@ import java.util.List;
 import java.util.stream.Collectors;
 import javax.inject.Inject;
 import javax.ws.rs.QueryParam;
-import org.apache.ignite.ci.ITcServerProvider;
+import org.apache.ignite.ci.tcmodel.hist.BuildRef;
+import org.apache.ignite.ci.teamcity.ignited.ITeamcityIgnited;
+import org.apache.ignite.ci.teamcity.ignited.ITeamcityIgnitedProvider;
+import org.apache.ignite.ci.teamcity.pure.ITcServerProvider;
 import org.apache.ignite.ci.ITeamcity;
 import org.apache.ignite.ci.github.GitHubUser;
 import org.apache.ignite.ci.github.ignited.IGitHubConnIgnited;
@@ -54,6 +57,8 @@ public class TcBotTriggerAndSignOffService {
 
     @Inject IJiraIntegration jiraIntegration;
 
+    @Inject ITeamcityIgnitedProvider teamcityIgnitedProvider;
+
     /**
      * @param pr Pull Request.
      * @return JIRA ticket number.
@@ -199,4 +204,27 @@ public class TcBotTriggerAndSignOffService {
             return check;
         }).collect(Collectors.toList());
     }
+
+    public List<BuildRef> buildsForContribution(String srvId, ICredentialsProv 
prov,
+        String suiteId, String prId) {
+
+        ITeamcityIgnited srv = teamcityIgnitedProvider.server(srvId, prov);
+
+        List<BuildRef> buildHist = srv.getBuildHistory(suiteId, 
branchForTcA(prId));
+
+        if (!buildHist.isEmpty())
+            return buildHist;
+
+        buildHist = srv.getBuildHistory(suiteId, branchForTcB(prId));
+
+        return buildHist;
+    }
+
+    String branchForTcA(String prId) {
+        return "pull/" + prId + "/head";
+    }
+
+    String branchForTcB(String prId) {
+        return "pull/" + prId + "/merge";
+    }
 }
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/ITcServerProvider.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefCompacted.java
similarity index 64%
copy from 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/ITcServerProvider.java
copy to 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefCompacted.java
index 702ca22..452551a 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/ITcServerProvider.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefCompacted.java
@@ -14,15 +14,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.ignite.ci;
+package org.apache.ignite.ci.teamcity.ignited;
 
-import org.apache.ignite.ci.user.ICredentialsProv;
+import org.apache.ignite.ci.tcmodel.hist.BuildRef;
 
-import javax.annotation.Nullable;
+public class BuildRefCompacted {
+    int buildId = -1;
 
-/**
- * Provides instance to server with appropriate credentials, may cache 
instances to avoid odd server instances.
- */
-public interface ITcServerProvider {
-    public IAnalyticsEnabledTeamcity server(String srvId, @Nullable 
ICredentialsProv prov);
+    public BuildRefCompacted() {
+
+    }
+
+    public BuildRefCompacted(BuildRef ref) {
+        buildId = ref.getId() == null ? -1 : ref.getId();
+    }
+
+    public BuildRef toBuildRef() {
+        BuildRef ref = new BuildRef();
+        ref.setId(buildId < 0 ? null : buildId);
+        return ref;
+    }
 }
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotSystemProperties.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/IStringCompacter.java
similarity index 82%
copy from 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotSystemProperties.java
copy to 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/IStringCompacter.java
index a77dbd2..c76cc21 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotSystemProperties.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/IStringCompacter.java
@@ -14,9 +14,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.ignite.ci.teamcity.ignited;
 
-package org.apache.ignite.ci.tcbot;
-
-public class TcBotSystemProperties {
-    public static final String DEV_MODE = "DEV_MODE";
+public interface IStringCompacter {
+    public int getStringId(String value);
+    public String getStringFromId(int id);
 }
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotSystemProperties.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java
similarity index 72%
copy from 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotSystemProperties.java
copy to 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java
index a77dbd2..829eaff 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotSystemProperties.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java
@@ -14,9 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.ignite.ci.teamcity.ignited;
 
-package org.apache.ignite.ci.tcbot;
+import java.util.List;
+import javax.annotation.Nullable;
+import org.apache.ignite.ci.tcmodel.hist.BuildRef;
 
-public class TcBotSystemProperties {
-    public static final String DEV_MODE = "DEV_MODE";
+public interface ITeamcityIgnited {
+    public List<BuildRef> getBuildHistory(
+        @Nullable String buildTypeId,
+        @Nullable String branchName);
 }
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotSystemProperties.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnitedProvider.java
similarity index 79%
copy from 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotSystemProperties.java
copy to 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnitedProvider.java
index a77dbd2..590e755 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotSystemProperties.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnitedProvider.java
@@ -14,9 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.ignite.ci.teamcity.ignited;
 
-package org.apache.ignite.ci.tcbot;
+import org.apache.ignite.ci.user.ICredentialsProv;
 
-public class TcBotSystemProperties {
-    public static final String DEV_MODE = "DEV_MODE";
+public interface ITeamcityIgnitedProvider {
+
+    ITeamcityIgnited server(String srvId, ICredentialsProv prov);
 }
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TeamcityRecordingConnection.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/IgniteStringCompacter.java
similarity index 50%
copy from 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TeamcityRecordingConnection.java
copy to 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/IgniteStringCompacter.java
index 72ded81..82e3587 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TeamcityRecordingConnection.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/IgniteStringCompacter.java
@@ -14,19 +14,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.ignite.ci.teamcity.pure;
+package org.apache.ignite.ci.teamcity.ignited;
 
-import org.apache.ignite.ci.util.HttpUtil;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.jetbrains.annotations.NotNull;
 
-import javax.inject.Inject;
-import java.io.IOException;
-import java.io.InputStream;
+public class IgniteStringCompacter implements IStringCompacter {
+    AtomicBoolean initGuard=new AtomicBoolean();
 
-public class TeamcityRecordingConnection implements ITeamcityHttpConnection {
-    @Inject private TeamcityRecorder recorder;
+    @Override public int getStringId(String value) {
+        return 0;
+    }
+
+    @Override public String getStringFromId(int id) {
+        return null;
+    }
+
+
+
+    @NotNull
+    public static <K, V> CacheConfiguration<K, V> getCache8PartsConfig(String 
name) {
+        CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(name);
+
+        ccfg.setAffinity(new RendezvousAffinityFunction(false, 8));
 
-    /** {@inheritDoc} */
-    @Override public InputStream sendGet(String basicAuthTok, String url) 
throws IOException {
-        return recorder.onGet(HttpUtil.sendGetWithBasicAuth(basicAuthTok, 
url), url);
+        return ccfg;
     }
 }
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/TcServerCachingProvider.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TcIgnitedCachingProvider.java
similarity index 61%
copy from 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/TcServerCachingProvider.java
copy to 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TcIgnitedCachingProvider.java
index e8e9da3..8218b62 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/TcServerCachingProvider.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TcIgnitedCachingProvider.java
@@ -14,60 +14,56 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.ignite.ci.di;
+package org.apache.ignite.ci.teamcity.ignited;
 
 import com.google.common.base.Strings;
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
-import org.apache.ignite.ci.IAnalyticsEnabledTeamcity;
-import org.apache.ignite.ci.ITcServerProvider;
-import org.apache.ignite.ci.user.ICredentialsProv;
-import org.apache.ignite.ci.util.ExceptionUtil;
-
-import javax.annotation.Nullable;
-import javax.inject.Inject;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
+import javax.annotation.Nullable;
+import javax.inject.Inject;
+import org.apache.ignite.ci.ITeamcity;
+import org.apache.ignite.ci.teamcity.pure.ITcServerProvider;
+import org.apache.ignite.ci.user.ICredentialsProv;
+import org.apache.ignite.ci.util.ExceptionUtil;
 
 /**
  *
  */
-public class TcServerCachingProvider implements ITcServerProvider {
+class TcIgnitedCachingProvider implements ITeamcityIgnitedProvider {
     /** Server factory. */
     @Inject
-    private ITcServerFactory srvFactory;
+    private ITcServerProvider srvFactory;
 
-    private final Cache<String, IAnalyticsEnabledTeamcity> srvs
-            = CacheBuilder.<String, String>newBuilder()
+    private final Cache<String, ITeamcityIgnited> srvs
+            = CacheBuilder.newBuilder()
             .maximumSize(100)
             .expireAfterAccess(16, TimeUnit.MINUTES)
             .softValues()
             .build();
 
     /** {@inheritDoc} */
-    @Override public IAnalyticsEnabledTeamcity server(String srvId, @Nullable 
ICredentialsProv prov) {
-        Callable<IAnalyticsEnabledTeamcity> call = () -> {
-            IAnalyticsEnabledTeamcity teamcity = 
srvFactory.createServer(srvId);
+    @Override public ITeamcityIgnited server(String srvId, @Nullable 
ICredentialsProv prov) {
+        String fullKey = Strings.nullToEmpty(prov == null ? null : 
prov.getUser(srvId)) + ":" + Strings.nullToEmpty(srvId);
 
+        try {
+            return srvs.get(fullKey, () -> {
+                ITeamcity teamcity1 = srvFactory.server(srvId, prov);
 
-            if (prov != null) {
-                final String user = prov.getUser(srvId);
-                final String pwd = prov.getPassword(srvId);
-                teamcity.setAuthData(user, pwd);
-            }
+                if (prov != null) {
+                    final String user = prov.getUser(srvId);
+                    final String pwd = prov.getPassword(srvId);
+                    teamcity1.setAuthData(user, pwd);
+                }
 
-            return teamcity;
-        };
-        String fullKey = Strings.nullToEmpty(prov == null ? null : 
prov.getUser(srvId)) + ":" + Strings.nullToEmpty(srvId);
+                TeamcityIgnitedImpl impl = new TeamcityIgnitedImpl();
 
-        IAnalyticsEnabledTeamcity teamcity;
-        try {
-            teamcity = srvs.get(fullKey, call);
+                return impl;
+            });
         }
         catch (ExecutionException e) {
             throw ExceptionUtil.propagateException(e);
         }
-        return teamcity;
     }
 }
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedImpl.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedImpl.java
new file mode 100644
index 0000000..435222d
--- /dev/null
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedImpl.java
@@ -0,0 +1,187 @@
+/*
+ * 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.teamcity.ignited;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+import javax.annotation.Nullable;
+import javax.inject.Inject;
+import javax.inject.Provider;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
+import org.apache.ignite.ci.ITeamcity;
+import org.apache.ignite.ci.db.TcHelperDb;
+import org.apache.ignite.ci.di.AutoProfiling;
+import org.apache.ignite.ci.di.MonitoredTask;
+import org.apache.ignite.ci.di.scheduler.IScheduler;
+import org.apache.ignite.ci.tcmodel.hist.BuildRef;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.jetbrains.annotations.NotNull;
+
+//todo currently this implementation is shared between all users
+public class TeamcityIgnitedImpl implements ITeamcityIgnited {
+    /** Cache name*/
+    public static final String TEAMCITY_BUILD_CACHE_NAME = "teamcityBuild";
+
+    //todo move to string compacter
+    /** Cache name */
+    public static final String STRING_CACHE_NAME = "strings";
+
+    /** Server id. */
+    private String srvId;
+
+    /** Pure HTTP Connection API. */
+    private ITeamcity conn;
+
+    /** Ignite provider. */
+    @Inject Provider<Ignite> igniteProvider;
+
+    /** Scheduler. */
+    @Inject IScheduler scheduler;
+
+    /** Server ID mask for cache Entries. */
+    private long srvIdMaskHigh;
+
+    /** PPs cache. */
+    private IgniteCache<Long, BuildRefCompacted> buildsCache;
+
+    public void init(String srvId, ITeamcity conn) {
+        this.srvId = srvId;
+        this.conn = conn;
+
+        srvIdMaskHigh = Math.abs(srvId.hashCode());
+
+        Ignite ignite = igniteProvider.get();
+        buildsCache = 
ignite.getOrCreateCache(TcHelperDb.getCacheV2Config(TEAMCITY_BUILD_CACHE_NAME));
+    }
+
+    @NotNull
+    public static <K, V> CacheConfiguration<K, V> getCache8PartsConfig(String 
name) {
+        CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(name);
+
+        ccfg.setAffinity(new RendezvousAffinityFunction(false, 8));
+
+        return ccfg;
+    }
+
+    /** {@inheritDoc} */
+    @AutoProfiling
+    @Override public List<BuildRef> getBuildHistory(
+        @Nullable String buildTypeId,
+        @Nullable String branchName) {
+        scheduler.sheduleNamed(ITeamcityIgnited.class.getSimpleName() + 
".actualizeRecentBuilds",
+            this::actualizeRecentBuilds, 2, TimeUnit.MINUTES);
+
+        return allBuildsEver()
+            .filter(e -> Objects.equals(e.buildTypeId, buildTypeId))
+            .filter(e -> Objects.equals(e.branchName, branchName))
+            .collect(Collectors.toList());
+    }
+
+    @NotNull private Stream<BuildRef> allBuildsEver() {
+        return StreamSupport.stream(buildsCache.spliterator(), false)
+            .filter(entry -> entry.getKey() >> 32 == srvIdMaskHigh)
+            .map(javax.cache.Cache.Entry::getValue)
+            .map(BuildRefCompacted::toBuildRef);
+    }
+
+    private void actualizeRecentBuilds() {
+        runAtualizeBuilds(srvId, false);
+
+        // schedule full resync later
+        scheduler.invokeLater(this::sheduleResync, 20, TimeUnit.SECONDS);
+    }
+
+    /**
+     *
+     */
+    private void sheduleResync() {
+        scheduler.sheduleNamed(ITeamcityIgnited.class.getSimpleName() + 
".fullReindex",
+            this::fullReindex, 60, TimeUnit.MINUTES);
+    }
+
+    /**
+     *
+     */
+    private void fullReindex() {
+        runAtualizeBuilds(srvId, true);
+    }
+
+    /**
+     * @param srvId Server id.
+     * @param fullReindex Reindex all open PRs
+     */
+    @MonitoredTask(name = "Actualize BuildRefs, full resync", nameExtArgIndex 
= 1)
+    @AutoProfiling
+    protected String runAtualizeBuilds(String srvId, boolean fullReindex) {
+        AtomicReference<String> outLinkNext = new AtomicReference<>();
+
+        List<BuildRef> tcData = conn.getFinishedBuilds(null, null);//todo, 
outLinkNext);
+        int cntSaved = saveChunk(tcData);
+        int totalChecked = tcData.size();
+        while (outLinkNext.get() != null) {
+            String nextPageUrl = outLinkNext.get();
+            tcData = conn.getFinishedBuilds(null,null); //todo nextPageUrl, 
outLinkNext);
+            cntSaved += saveChunk(tcData);
+            totalChecked += tcData.size();
+
+            if(!fullReindex)
+                break; // 2 pages
+        }
+
+        return "Entries saved " + cntSaved + " Builds checked " + totalChecked;
+    }
+
+    private int saveChunk(List<BuildRef> ghData) {
+        Set<Long> ids = ghData.stream().map(BuildRef::getId)
+            .filter(Objects::nonNull)
+            .map(this::buildIdToCacheKey)
+            .collect(Collectors.toSet());
+
+        Map<Long, BuildRefCompacted> existingEntries = buildsCache.getAll(ids);
+        Map<Long, BuildRefCompacted> entriesToPut = new TreeMap<>();
+
+        List<BuildRefCompacted> collect = 
ghData.stream().map(BuildRefCompacted::new)
+            .collect(Collectors.toList());
+
+        for (BuildRefCompacted next : collect) {
+            long cacheKey = buildIdToCacheKey(next.buildId );
+            BuildRefCompacted buildPersisted = existingEntries.get(cacheKey);
+
+            if (buildPersisted == null || !buildPersisted.equals(next))
+                entriesToPut.put(cacheKey, next);
+        }
+
+        int size = entriesToPut.size();
+        if (size != 0)
+            buildsCache.putAll(entriesToPut);
+        return size;
+    }
+
+    private long buildIdToCacheKey(int buildId) {
+        return (long)buildId | srvIdMaskHigh << 32;
+    }
+}
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TcRealConnectionModule.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedModule.java
similarity index 76%
copy from 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TcRealConnectionModule.java
copy to 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedModule.java
index 4d154e7..202c834 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TcRealConnectionModule.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedModule.java
@@ -14,19 +14,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.ignite.ci.teamcity.pure;
+package org.apache.ignite.ci.teamcity.ignited;
 
 import com.google.inject.AbstractModule;
 import com.google.inject.internal.SingletonScope;
+import org.apache.ignite.ci.teamcity.pure.TcRealConnectionModule;
 
 /**
  * Guice module to setup real connected server and all related implementations.
  */
-public class TcRealConnectionModule extends AbstractModule {
+public class TeamcityIgnitedModule extends AbstractModule {
     /** {@inheritDoc} */
     @Override protected void configure() {
-        
bind(ITeamcityHttpConnection.class).to(TeamcityRecordingConnection.class);
-        bind(TeamcityRecorder.class).in(new SingletonScope());
-        bind(ITcLogin.class).to(TcLoginImpl.class).in(new SingletonScope());
+        
bind(ITeamcityIgnitedProvider.class).to(TcIgnitedCachingProvider.class).in(new 
SingletonScope());
+
+        install(new TcRealConnectionModule());
     }
 }
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/ITcServerProvider.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/ITcServerProvider.java
similarity index 92%
rename from 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/ITcServerProvider.java
rename to 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/ITcServerProvider.java
index 702ca22..cefafac 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/ITcServerProvider.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/ITcServerProvider.java
@@ -14,8 +14,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.ignite.ci;
+package org.apache.ignite.ci.teamcity.pure;
 
+import org.apache.ignite.ci.IAnalyticsEnabledTeamcity;
 import org.apache.ignite.ci.user.ICredentialsProv;
 
 import javax.annotation.Nullable;
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TcLoginImpl.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TcLoginImpl.java
index f8aad00..e16a2d9 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TcLoginImpl.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TcLoginImpl.java
@@ -28,7 +28,7 @@ import javax.inject.Provider;
 /**
  * Real implementation of login based on getting current user preferences from 
the server.
  */
-public class TcLoginImpl implements ITcLogin {
+class TcLoginImpl implements ITcLogin {
     /** Logger. */
     private static final Logger logger = 
LoggerFactory.getLogger(TcLoginImpl.class);
 
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TcRealConnectionModule.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TcRealConnectionModule.java
index 4d154e7..8a2f9ba 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TcRealConnectionModule.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TcRealConnectionModule.java
@@ -25,6 +25,7 @@ import com.google.inject.internal.SingletonScope;
 public class TcRealConnectionModule extends AbstractModule {
     /** {@inheritDoc} */
     @Override protected void configure() {
+        bind(ITcServerProvider.class).to(TcServerCachingProvider.class).in(new 
SingletonScope());
         
bind(ITeamcityHttpConnection.class).to(TeamcityRecordingConnection.class);
         bind(TeamcityRecorder.class).in(new SingletonScope());
         bind(ITcLogin.class).to(TcLoginImpl.class).in(new SingletonScope());
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/TcServerCachingProvider.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TcServerCachingProvider.java
similarity index 68%
rename from 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/TcServerCachingProvider.java
rename to 
ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TcServerCachingProvider.java
index e8e9da3..cb5d629 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/TcServerCachingProvider.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TcServerCachingProvider.java
@@ -14,13 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.ignite.ci.di;
+package org.apache.ignite.ci.teamcity.pure;
 
 import com.google.common.base.Strings;
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
 import org.apache.ignite.ci.IAnalyticsEnabledTeamcity;
-import org.apache.ignite.ci.ITcServerProvider;
+import org.apache.ignite.ci.di.ITcServerFactory;
 import org.apache.ignite.ci.user.ICredentialsProv;
 import org.apache.ignite.ci.util.ExceptionUtil;
 
@@ -33,41 +33,38 @@ import java.util.concurrent.TimeUnit;
 /**
  *
  */
-public class TcServerCachingProvider implements ITcServerProvider {
+class TcServerCachingProvider implements ITcServerProvider {
     /** Server factory. */
     @Inject
     private ITcServerFactory srvFactory;
 
+    /** Servers. */
     private final Cache<String, IAnalyticsEnabledTeamcity> srvs
-            = CacheBuilder.<String, String>newBuilder()
-            .maximumSize(100)
-            .expireAfterAccess(16, TimeUnit.MINUTES)
-            .softValues()
-            .build();
+        = CacheBuilder.newBuilder()
+        .maximumSize(100)
+        .expireAfterAccess(16, TimeUnit.MINUTES)
+        .softValues()
+        .build();
 
     /** {@inheritDoc} */
     @Override public IAnalyticsEnabledTeamcity server(String srvId, @Nullable 
ICredentialsProv prov) {
-        Callable<IAnalyticsEnabledTeamcity> call = () -> {
-            IAnalyticsEnabledTeamcity teamcity = 
srvFactory.createServer(srvId);
-
-
-            if (prov != null) {
-                final String user = prov.getUser(srvId);
-                final String pwd = prov.getPassword(srvId);
-                teamcity.setAuthData(user, pwd);
-            }
-
-            return teamcity;
-        };
         String fullKey = Strings.nullToEmpty(prov == null ? null : 
prov.getUser(srvId)) + ":" + Strings.nullToEmpty(srvId);
 
-        IAnalyticsEnabledTeamcity teamcity;
         try {
-            teamcity = srvs.get(fullKey, call);
+            return srvs.get(fullKey, () -> {
+                IAnalyticsEnabledTeamcity teamcity = 
srvFactory.createServer(srvId);
+
+                if (prov != null) {
+                    final String user = prov.getUser(srvId);
+                    final String pwd = prov.getPassword(srvId);
+                    teamcity.setAuthData(user, pwd);
+                }
+
+                return teamcity;
+            });
         }
         catch (ExecutionException e) {
             throw ExceptionUtil.propagateException(e);
         }
-        return teamcity;
     }
 }
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TeamcityRecorder.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TeamcityRecorder.java
index 7cae7f3..540e16c 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TeamcityRecorder.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TeamcityRecorder.java
@@ -24,6 +24,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.locks.ReentrantLock;
+import org.apache.ignite.ci.tcbot.TcBotSystemProperties;
 
 /**
  *
@@ -43,14 +44,14 @@ public class TeamcityRecorder {
      * @param url Url.
      */
     public InputStream onGet(InputStream inputStream, String url) throws 
IOException {
-        if (Boolean.valueOf(System.getProperty("teamcity.bot.recorder.urls"))) 
{
+        if 
(Boolean.valueOf(System.getProperty(TcBotSystemProperties.TEAMCITY_BOT_RECORDER_URLS)))
 {
             urls.add(url);
 
             if (urls.size() > 100)
                 urls.remove();
         }
 
-        if (Boolean.valueOf(System.getProperty("teamcity.bot.recorder"))) {
+        if 
(Boolean.valueOf(System.getProperty(TcBotSystemProperties.TEAMCITY_BOT_RECORDER)))
 {
             boolean success = false;
 
             lock.lock();
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TeamcityRecordingConnection.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TeamcityRecordingConnection.java
index 72ded81..b5125d7 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TeamcityRecordingConnection.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/TeamcityRecordingConnection.java
@@ -23,6 +23,7 @@ import java.io.IOException;
 import java.io.InputStream;
 
 public class TeamcityRecordingConnection implements ITeamcityHttpConnection {
+    /** Recorder. */
     @Inject private TeamcityRecorder recorder;
 
     /** {@inheritDoc} */
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/CtxListener.java 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/CtxListener.java
index 249d554..914da02 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/CtxListener.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/CtxListener.java
@@ -29,7 +29,7 @@ import com.google.inject.Guice;
 import com.google.inject.Injector;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.ci.IAnalyticsEnabledTeamcity;
-import org.apache.ignite.ci.ITcServerProvider;
+import org.apache.ignite.ci.teamcity.pure.ITcServerProvider;
 import org.apache.ignite.ci.ITcHelper;
 import org.apache.ignite.ci.TcHelper;
 import org.apache.ignite.ci.db.TcHelperDb;
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/visa/TcBotVisaService.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/visa/TcBotVisaService.java
index 9b9da8c..fa57009 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/visa/TcBotVisaService.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/visa/TcBotVisaService.java
@@ -17,6 +17,7 @@
 package org.apache.ignite.ci.web.rest.visa;
 
 import java.util.List;
+import javax.annotation.Nonnull;
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.GET;
@@ -25,6 +26,7 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
+import org.apache.ignite.ci.tcmodel.hist.BuildRef;
 import org.apache.ignite.ci.user.ICredentialsProv;
 import org.apache.ignite.ci.tcbot.visa.ContributionToCheck;
 import org.apache.ignite.ci.tcbot.visa.TcBotTriggerAndSignOffService;
@@ -43,20 +45,32 @@ public class TcBotVisaService {
     @Context
     private HttpServletRequest req;
 
+    /**
+     * @param srvId Server id.
+     */
     @GET
     @Path("contributions")
-    public List<ContributionToCheck> contributions(
-        @Nullable @QueryParam("serverId") String srvId
-    ) {
+    public List<ContributionToCheck> contributions(@Nullable 
@QueryParam("serverId") String srvId) {
+        if (!ICredentialsProv.get(req).hasAccess(srvId))
+            throw ServiceUnauthorizedException.noCreds(srvId);
 
-        final ICredentialsProv prov = ICredentialsProv.get(req);
+        return CtxListener.getInjector(ctx)
+            
.getInstance(TcBotTriggerAndSignOffService.class).getContributionsToCheck(srvId);
+    }
 
+    @GET
+    @Path("buildsForContribution")
+    public List<BuildRef> buildsForContribution(@Nullable 
@QueryParam("serverId") String srvId,
+        @Nonnull @QueryParam("suiteId") String suiteId,
+        @QueryParam("prId") String prId) {
+        ICredentialsProv prov = ICredentialsProv.get(req);
         if (!prov.hasAccess(srvId))
             throw ServiceUnauthorizedException.noCreds(srvId);
 
+
         TcBotTriggerAndSignOffService instance = CtxListener.getInjector(ctx)
             .getInstance(TcBotTriggerAndSignOffService.class);
 
-        return instance.getContributionsToCheck(srvId);
+        return instance.buildsForContribution(srvId, prov, suiteId, prId);
     }
 }
diff --git 
a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/di/DiContextTest.java 
b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/di/DiContextTest.java
index 1888ea0..1c04650 100644
--- 
a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/di/DiContextTest.java
+++ 
b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/di/DiContextTest.java
@@ -20,15 +20,13 @@ import com.google.common.base.Preconditions;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import org.apache.ignite.ci.ITcHelper;
-import org.apache.ignite.ci.ITcServerProvider;
-import org.apache.ignite.ci.TcHelper;
+import org.apache.ignite.ci.teamcity.pure.ITcServerProvider;
 import org.apache.ignite.ci.observer.BuildObserver;
 import org.apache.ignite.ci.observer.ObserverTask;
 import org.apache.ignite.ci.web.TcUpdatePool;
 import org.junit.Test;
 
 import java.util.Collection;
-import java.util.Iterator;
 
 import static org.junit.Assert.assertTrue;
 

Reply via email to