You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by dp...@apache.org on 2018/09/25 18:24:27 UTC

[ignite-teamcity-bot] 01/01: DI refactoring for Observer task

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

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

commit 04efd1b2d6a9c3155bd4dbb3dac4483b679acdb2
Author: Dmitriy Pavlov <dp...@apache.org>
AuthorDate: Tue Sep 25 21:24:16 2018 +0300

    DI refactoring for Observer task
---
 .../main/java/org/apache/ignite/ci/ITcHelper.java  |  4 --
 .../main/java/org/apache/ignite/ci/TcHelper.java   | 28 ++---------
 .../{IServerFactory.java => ITcServerFactory.java} | 10 +++-
 .../org/apache/ignite/ci/di/IgniteTcBotModule.java | 37 +++++++++------
 .../ignite/ci/di/TcServerCachingProvider.java      | 16 ++++---
 .../apache/ignite/ci/jira/IJiraIntegration.java    | 15 ++++++
 .../apache/ignite/ci/observer/BuildObserver.java   | 11 ++---
 .../apache/ignite/ci/observer/ObserverTask.java    | 55 ++++++++++++++++++----
 .../java/org/apache/ignite/ci/web/CtxListener.java |  8 ++++
 .../ignite/ci/web/rest/GetChainResultsAsHtml.java  | 12 +++--
 .../apache/ignite/ci/web/rest/TriggerBuild.java    |  5 +-
 .../org/apache/ignite/ci/di/DiContextTest.java     | 10 +++-
 12 files changed, 141 insertions(+), 70 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 e083468..5c25432 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
@@ -43,10 +43,6 @@ public interface ITcHelper extends ITcServerProvider {
 
     IssueDetector issueDetector();
 
-    /**
-     * @return Build observer.
-     */
-    BuildObserver buildObserver();
 
     ITcAnalytics tcAnalytics(String serverId);
 
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 469e9a0..8edfae4 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
@@ -17,18 +17,14 @@
 
 package org.apache.ignite.ci;
 
-import com.google.common.base.Strings;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
 import org.apache.ignite.ci.conf.BranchesTracked;
-import org.apache.ignite.ci.di.IServerFactory;
 import org.apache.ignite.ci.issue.IssueDetector;
 import org.apache.ignite.ci.issue.IssuesStorage;
+import org.apache.ignite.ci.jira.IJiraIntegration;
 import org.apache.ignite.ci.observer.BuildObserver;
 import org.apache.ignite.ci.tcmodel.hist.BuildRef;
 import org.apache.ignite.ci.user.ICredentialsProv;
 import org.apache.ignite.ci.user.UserAndSessionsStorage;
-import org.apache.ignite.ci.util.ExceptionUtil;
 import org.apache.ignite.ci.web.TcUpdatePool;
 import org.apache.ignite.ci.web.model.current.ChainAtServerCurrentStatus;
 import org.apache.ignite.ci.web.model.current.SuiteCurrentStatus;
@@ -42,10 +38,7 @@ import org.slf4j.LoggerFactory;
 
 import javax.inject.Inject;
 import java.util.*;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import static org.apache.ignite.ci.analysis.RunStat.MAX_LATEST_RUNS;
@@ -54,7 +47,7 @@ import static org.apache.ignite.ci.util.XmlUtil.xmlEscapeText;
 /**
  * TC Bot implementation
  */
-public class TcHelper implements ITcHelper {
+public class TcHelper implements ITcHelper, IJiraIntegration {
     /** Logger. */
     private static final Logger logger = LoggerFactory.getLogger(TcHelper.class);
 
@@ -69,13 +62,9 @@ public class TcHelper implements ITcHelper {
 
     @Inject private IssueDetector detector;
 
-    /** Build observer. */
-    private BuildObserver buildObserver;
-
     @Inject private UserAndSessionsStorage userAndSessionsStorage;
 
     public TcHelper() {
-        buildObserver = new BuildObserver(this);
     }
 
     /** {@inheritDoc} */
@@ -89,11 +78,6 @@ public class TcHelper implements ITcHelper {
     }
 
     /** {@inheritDoc} */
-    @Override public BuildObserver buildObserver() {
-        return buildObserver;
-    }
-
-    /** {@inheritDoc} */
     @Override public IAnalyticsEnabledTeamcity server(String srvId, @Nullable ICredentialsProv prov) {
         if (stop.get())
             throw new IllegalStateException("Shutdown");
@@ -166,7 +150,7 @@ public class TcHelper implements ITcHelper {
      * @param srvId Server id.
      * @param prov Credentials.
      * @param webUrl Build URL.
-     * @param executorService Executor service to process TC communication requests there.
+     * @param executorSvc Executor service to process TC communication requests there.
      * @return Comment, which should be sent to the JIRA ticket.
      */
     private String generateJiraComment(
@@ -175,12 +159,12 @@ public class TcHelper implements ITcHelper {
             String srvId,
             ICredentialsProv prov,
             String webUrl,
-            @Nullable ExecutorService executorService
+            @Nullable ExecutorService executorSvc
     ) {
         StringBuilder res = new StringBuilder();
         TestFailuresSummary summary = GetPrTestFailures.getTestFailuresSummary(
             this, prov, srvId, buildTypeId, branchForTc,
-            "Latest", null, null, executorService);
+            "Latest", null, null, executorSvc);
 
         if (summary != null) {
             for (ChainAtServerCurrentStatus server : summary.servers) {
@@ -296,8 +280,6 @@ public class TcHelper implements ITcHelper {
             tcUpdatePool.stop();
 
             detector.stop();
-
-            buildObserver.stop();
         }
     }
 
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/IServerFactory.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/ITcServerFactory.java
similarity index 82%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/IServerFactory.java
rename to ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/ITcServerFactory.java
index e257248..50fb1b6 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/IServerFactory.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/ITcServerFactory.java
@@ -18,6 +18,12 @@ package org.apache.ignite.ci.di;
 
 import org.apache.ignite.ci.IAnalyticsEnabledTeamcity;
 
-public interface IServerFactory {
-    IAnalyticsEnabledTeamcity createServer(String serverId);
+/**
+ * Factory for creating new servers
+ */
+public interface ITcServerFactory {
+    /**
+     * @param srvId Server id.
+     */
+    public IAnalyticsEnabledTeamcity createServer(String srvId);
 }
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 8020229..bd841f1 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
@@ -25,6 +25,10 @@ import com.google.inject.matcher.Matchers;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.ci.*;
 import org.apache.ignite.ci.db.Ignite1Init;
+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.user.ICredentialsProv;
 import org.apache.ignite.ci.util.ExceptionUtil;
 import org.apache.ignite.ci.web.TcUpdatePool;
 import org.apache.ignite.ci.web.rest.exception.ServiceStartingException;
@@ -34,19 +38,19 @@ import javax.inject.Provider;
 import java.util.concurrent.*;
 
 public class IgniteTcBotModule extends AbstractModule {
-    private Future<Ignite> igniteFuture;
+    /** Ignite future. */
+    private Future<Ignite> igniteFut;
 
     /** {@inheritDoc} */
-    @Override
-    protected void configure() {
+    @Override protected void configure() {
         configProfiling();
         configTaskMonitor();
 
         bind(Ignite.class).toProvider((Provider<Ignite>) () -> {
-            Preconditions.checkNotNull(igniteFuture, "Ignite future is not yet initialized");
+            Preconditions.checkNotNull(igniteFut, "Ignite future is not yet initialized");
 
             try {
-                return igniteFuture.get(10, TimeUnit.SECONDS);
+                return igniteFut.get(10, TimeUnit.SECONDS);
             } catch (TimeoutException e) {
                 throw new ServiceStartingException(e);
             } catch (Exception e) {
@@ -60,10 +64,15 @@ public class IgniteTcBotModule extends AbstractModule {
         bind(ITeamcity.class).to(IgniteTeamcityConnection.class);
         //With REST persistence
         bind(IAnalyticsEnabledTeamcity.class).to(IgnitePersistentTeamcity.class);
-        bind(IServerFactory.class).to(InitializingServerFactory.class).in(new SingletonScope());
+        bind(ITcServerFactory.class).to(InitializingServerFactory.class).in(new SingletonScope());
         bind(ITcServerProvider.class).to(TcServerCachingProvider.class).in(new SingletonScope());
         bind(TcUpdatePool.class).in(new SingletonScope());
        //todo bind(IssueDetector.clas)
+        bind(ObserverTask.class).in(new SingletonScope());
+        bind(BuildObserver.class).in(new SingletonScope());
+        bind(ITcHelper.class).to(TcHelper.class).in(new SingletonScope());
+
+        bind(IJiraIntegration.class).to(Jira.class).in(new SingletonScope());
     }
 
     private void configProfiling() {
@@ -87,19 +96,19 @@ public class IgniteTcBotModule extends AbstractModule {
         bind(MonitoredTaskInterceptor.class).toInstance(profilingInterceptor);
     }
 
-    public void setIgniteFuture(Future<Ignite> igniteFuture) {
-        this.igniteFuture = igniteFuture;
+    public void setIgniteFut(Future<Ignite> igniteFut) {
+        this.igniteFut = igniteFut;
     }
 
     public Injector startIgniteInit(Injector injector) {
         final Ignite1Init instance = injector.getInstance(Ignite1Init.class);
         final Future<Ignite> submit = instance.getIgniteFuture();
-        setIgniteFuture(submit);
+        setIgniteFut(submit);
 
         return injector;
     }
 
-    private static class InitializingServerFactory implements IServerFactory {
+    private static class InitializingServerFactory implements ITcServerFactory {
         @Inject
         Provider<IAnalyticsEnabledTeamcity> tcPersistProv;
 
@@ -107,12 +116,12 @@ public class IgniteTcBotModule extends AbstractModule {
         Provider<ITeamcity> tcConnProv;
 
         @Inject
-        TcUpdatePool tcUpdatePool;
+        private TcUpdatePool tcUpdatePool;
 
-        @Override
-        public IAnalyticsEnabledTeamcity createServer(String serverId) {
+        /** {@inheritDoc} */
+        @Override public IAnalyticsEnabledTeamcity createServer(String srvId) {
             ITeamcity tcConn = tcConnProv.get();
-            tcConn.init(Strings.emptyToNull(serverId));
+            tcConn.init(Strings.emptyToNull(srvId));
 
             IAnalyticsEnabledTeamcity instance = tcPersistProv.get();
             instance.init(tcConn);
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/di/TcServerCachingProvider.java
index 52185d8..e8e9da3 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/di/TcServerCachingProvider.java
@@ -30,9 +30,13 @@ import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 
+/**
+ *
+ */
 public class TcServerCachingProvider implements ITcServerProvider {
+    /** Server factory. */
     @Inject
-    private IServerFactory serverFactory;
+    private ITcServerFactory srvFactory;
 
     private final Cache<String, IAnalyticsEnabledTeamcity> srvs
             = CacheBuilder.<String, String>newBuilder()
@@ -41,16 +45,16 @@ public class TcServerCachingProvider implements ITcServerProvider {
             .softValues()
             .build();
 
-    @Override
-    public IAnalyticsEnabledTeamcity server(String srvId, @Nullable ICredentialsProv prov) {
+    /** {@inheritDoc} */
+    @Override public IAnalyticsEnabledTeamcity server(String srvId, @Nullable ICredentialsProv prov) {
         Callable<IAnalyticsEnabledTeamcity> call = () -> {
-            IAnalyticsEnabledTeamcity teamcity = serverFactory.createServer(srvId);
+            IAnalyticsEnabledTeamcity teamcity = srvFactory.createServer(srvId);
 
 
             if (prov != null) {
                 final String user = prov.getUser(srvId);
-                final String password = prov.getPassword(srvId);
-                teamcity.setAuthData(user, password);
+                final String pwd = prov.getPassword(srvId);
+                teamcity.setAuthData(user, pwd);
             }
 
             return teamcity;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/IJiraIntegration.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/IJiraIntegration.java
new file mode 100644
index 0000000..2185a6f
--- /dev/null
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/IJiraIntegration.java
@@ -0,0 +1,15 @@
+package org.apache.ignite.ci.jira;
+
+import org.apache.ignite.ci.user.ICredentialsProv;
+
+public interface IJiraIntegration {
+    /**
+     * @param srvId TC Server ID to take information about token from.
+     * @param prov Credentials.
+     * @param buildTypeId Suite name.
+     * @param branchForTc Branch for TeamCity.
+     * @param ticket JIRA ticket full name.
+     * @return {@code True} if JIRA was notified.
+     */
+    boolean notifyJira(String srvId, ICredentialsProv prov, String buildTypeId, String branchForTc, String ticket);
+}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/observer/BuildObserver.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/observer/BuildObserver.java
index a7a7b1b..ced9593 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/observer/BuildObserver.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/observer/BuildObserver.java
@@ -18,7 +18,7 @@
 package org.apache.ignite.ci.observer;
 
 import java.util.Timer;
-import org.apache.ignite.ci.ITcHelper;
+import javax.inject.Inject;
 import org.apache.ignite.ci.tcmodel.result.Build;
 import org.apache.ignite.ci.user.ICredentialsProv;
 
@@ -33,15 +33,14 @@ public class BuildObserver {
     private final Timer timer;
 
     /** Task, which should be done periodically. */
-    private final ObserverTask task;
+    @Inject ObserverTask observerTask;
 
     /**
-     * @param helper Helper.
      */
-    public BuildObserver(ITcHelper helper) {
+    public BuildObserver() {
         timer = new Timer();
 
-        timer.schedule(task = new ObserverTask(helper), period, period);
+        timer.schedule(observerTask, 0, period);
     }
 
     /**
@@ -58,6 +57,6 @@ public class BuildObserver {
      * @param ticket JIRA ticket name.
      */
     public void observe(Build build, String srvId, ICredentialsProv prov, String ticket) {
-        task.builds.add(new BuildInfo(build, srvId, prov, ticket));
+        observerTask.builds.add(new BuildInfo(build, srvId, prov, ticket));
     }
 }
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 3821972..823cc07 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
@@ -17,43 +17,82 @@
 
 package org.apache.ignite.ci.observer;
 
+import java.util.HashSet;
 import java.util.Queue;
+import java.util.Set;
 import java.util.TimerTask;
 import java.util.concurrent.ConcurrentLinkedQueue;
+import javax.inject.Inject;
 import org.apache.ignite.ci.IAnalyticsEnabledTeamcity;
-import org.apache.ignite.ci.ITcHelper;
+import org.apache.ignite.ci.ITcServerProvider;
+import org.apache.ignite.ci.di.AutoProfiling;
+import org.apache.ignite.ci.di.MonitoredTask;
+import org.apache.ignite.ci.jira.IJiraIntegration;
 import org.apache.ignite.ci.tcmodel.result.Build;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Checks observed builds for finished status and comments JIRA ticket.
  */
 public class ObserverTask extends TimerTask {
+    /** Logger. */
+    private static final Logger logger = LoggerFactory.getLogger(ObserverTask.class);
+
+    /** Helper. */
+    @Inject private ITcServerProvider srvProvider;
+
     /** Helper. */
-    private final ITcHelper helper;
+    @Inject private IJiraIntegration jiraIntegration;
 
     /** Builds. */
     final Queue<BuildInfo> builds;
 
     /**
-     * @param helper Helper.
      */
-    ObserverTask(ITcHelper helper) {
-        this.helper = helper;
+    ObserverTask() {
         builds = new ConcurrentLinkedQueue<>();
     }
 
     /** {@inheritDoc} */
     @Override public void run() {
+        try {
+            runObserverTask();
+        }
+        catch (Exception e) {
+            logger.error("Observer task failure: " + e.getMessage(), e);
+        }
+    }
+
+    /**
+     *
+     */
+    @AutoProfiling
+    @MonitoredTask(name = "Build Observer")
+    protected String runObserverTask() {
+        int checkedBuilds = 0;
+        int notFinihedBuilds = 0;
+        Set<String> ticketsNotified = new HashSet<>();
+
         for (BuildInfo info : builds) {
-            IAnalyticsEnabledTeamcity teamcity = helper.server(info.srvId, info.prov);
+            checkedBuilds++;
+            IAnalyticsEnabledTeamcity teamcity = srvProvider.server(info.srvId, info.prov);
 
             Build build = teamcity.getBuild(info.build.getId());
 
-            if (!"finished".equals(build.state))
+            if (!"finished".equals(build.state)) {
+                notFinihedBuilds++;
+
                 continue;
+            }
+
+            if (jiraIntegration.notifyJira(info.srvId, info.prov, info.build.buildTypeId, info.build.branchName, info.ticket)) {
+                ticketsNotified.add(info.ticket);
 
-            if (helper.notifyJira(info.srvId, info.prov, info.build.buildTypeId, info.build.branchName, info.ticket))
                 builds.remove(info);
+            }
         }
+
+        return "Checked " + checkedBuilds + " not finished " + notFinihedBuilds + " notified: " + ticketsNotified;
     }
 }
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 f3f4a4a..db1bd75 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
@@ -34,6 +34,7 @@ import org.apache.ignite.ci.ITcHelper;
 import org.apache.ignite.ci.TcHelper;
 import org.apache.ignite.ci.db.TcHelperDb;
 import org.apache.ignite.ci.di.IgniteTcBotModule;
+import org.apache.ignite.ci.observer.BuildObserver;
 import org.apache.ignite.ci.user.ICredentialsProv;
 import org.jetbrains.annotations.Nullable;
 
@@ -115,6 +116,13 @@ public class CtxListener implements ServletContextListener {
 
         TcHelper helper = (TcHelper)getTcHelper(ctx);
         helper.close();
+
+        try {
+            injector.getInstance(BuildObserver.class).stop();
+        }
+        catch (Exception e) {
+            e.printStackTrace();
+        }
     }
 }
 
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/GetChainResultsAsHtml.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/GetChainResultsAsHtml.java
index 113773b..64d064f 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/GetChainResultsAsHtml.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/GetChainResultsAsHtml.java
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.Optional;
 import java.util.concurrent.ExecutionException;
 import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
@@ -31,8 +32,8 @@ import javax.ws.rs.core.Context;
 
 import com.google.common.util.concurrent.MoreExecutors;
 import org.apache.ignite.ci.BuildChainProcessor;
+import org.apache.ignite.ci.IAnalyticsEnabledTeamcity;
 import org.apache.ignite.ci.ITeamcity;
-import org.apache.ignite.ci.IgnitePersistentTeamcity;
 import org.apache.ignite.ci.analysis.FullChainRunCtx;
 import org.apache.ignite.ci.analysis.mode.LatestRebuildMode;
 import org.apache.ignite.ci.analysis.mode.ProcessLogsMode;
@@ -55,14 +56,15 @@ public class GetChainResultsAsHtml {
 
     @Context
     private ServletContext context;
+
+    @Context
+    private HttpServletRequest request;
     
     //test here http://localhost:8080/rest/chainResults/html?serverId=public&buildId=1086222
-    public void showChainOnServersResults(StringBuilder res, Integer buildId, String serverId) {
-
+    public void showChainOnServersResults(StringBuilder res, Integer buildId, String srvId) {
         //todo solve report auth problem
-        IgnitePersistentTeamcity teamcity = new IgnitePersistentTeamcity(CtxListener.getIgnite(context), serverId);
 
-        teamcity.setExecutor(CtxListener.getPool(context));
+        IAnalyticsEnabledTeamcity teamcity = CtxListener.server(srvId, context, request);
 
         //processChainByRef(teamcity, includeLatestRebuild, build, true, true)
         String hrefById = teamcity.getBuildHrefById(buildId);
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/TriggerBuild.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/TriggerBuild.java
index 95d2875..c5da089 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/TriggerBuild.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/TriggerBuild.java
@@ -31,6 +31,7 @@ import javax.ws.rs.core.MediaType;
 import org.apache.ignite.ci.ITcHelper;
 import org.apache.ignite.ci.ITeamcity;
 import org.apache.ignite.ci.github.PullRequest;
+import org.apache.ignite.ci.observer.BuildObserver;
 import org.apache.ignite.ci.tcmodel.result.Build;
 import org.apache.ignite.ci.user.ICredentialsProv;
 import org.apache.ignite.ci.web.CtxListener;
@@ -164,7 +165,9 @@ public class TriggerBuild {
             }
         }
 
-        helper.buildObserver().observe(build, srvId, prov, "ignite-" + ticketId);
+        BuildObserver observer = CtxListener.getInjector(context).getInstance(BuildObserver.class);
+
+        observer.observe(build, srvId, prov, "ignite-" + ticketId);
 
         return "JIRA ticket IGNITE-" + ticketId + " will be notified after the tests are completed.";
     }
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 440ce10..5f21dff 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,19 +20,27 @@ import com.google.common.base.Preconditions;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import org.apache.ignite.ci.ITcServerProvider;
+import org.apache.ignite.ci.observer.ObserverTask;
 import org.apache.ignite.ci.web.TcUpdatePool;
 import org.junit.Test;
 
 public class DiContextTest {
+    /**
+     *
+     */
     @Test
     public void checkSingletons() {
         IgniteTcBotModule igniteTcBotModule = new IgniteTcBotModule();
         Injector injector = Guice.createInjector(igniteTcBotModule);
 
         validateInstanceCachedFor(injector, ITcServerProvider.class);
-        validateInstanceCachedFor(injector, IServerFactory.class);
+        validateInstanceCachedFor(injector, ITcServerFactory.class);
+        validateInstanceCachedFor(injector, ObserverTask.class);
     }
 
+    /**
+     *
+     */
     @Test
     public void checkPoolIsOne() {
         IgniteTcBotModule igniteTcBotModule = new IgniteTcBotModule();