This is an automated email from the ASF dual-hosted git repository. dpavlov 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 2aefb27 IGNITE-10275 Several JIRA comments are issued in case ignite.cache.remove failed - Fixes #76. 2aefb27 is described below commit 2aefb27497a8ada00ccd90e931cec67d96c9c4b5 Author: ololo3000 <pmgheap....@gmail.com> AuthorDate: Wed Nov 21 18:52:38 2018 +0300 IGNITE-10275 Several JIRA comments are issued in case ignite.cache.remove failed - Fixes #76. Signed-off-by: Dmitriy Pavlov <dpav...@apache.org> --- .../apache/ignite/ci/IgnitePersistentTeamcity.java | 9 +- .../java/org/apache/ignite/ci/db/DbMigrations.java | 72 ++++++++++++- .../java/org/apache/ignite/ci/db/TcHelperDb.java | 15 +++ .../org/apache/ignite/ci/di/IgniteTcBotModule.java | 2 + .../apache/ignite/ci/observer/BuildObserver.java | 11 +- .../org/apache/ignite/ci/observer/BuildsInfo.java | 6 +- .../apache/ignite/ci/observer/ObserverTask.java | 111 +++++++-------------- .../ignite/ci/runners/RemoteClientTmpHelper.java | 25 ----- .../tcbot/visa/TcBotTriggerAndSignOffService.java | 20 ++-- .../ignite/ci/web/model/CompactVisaRequest.java | 16 ++- .../ignite/ci/web/model/ContributionKey.java | 20 ++++ .../apache/ignite/ci/web/model/VisaRequest.java | 15 +++ .../ci/web/model/hist/VisasHistoryStorage.java | 80 +++++++++++---- 13 files changed, 256 insertions(+), 146 deletions(-) diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgnitePersistentTeamcity.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgnitePersistentTeamcity.java index 3d39237..1fe97f5 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgnitePersistentTeamcity.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgnitePersistentTeamcity.java @@ -79,6 +79,7 @@ import org.apache.ignite.ci.tcmodel.user.User; import org.apache.ignite.ci.util.CacheUpdateUtil; import org.apache.ignite.ci.util.CollectionUtil; import org.apache.ignite.ci.util.ObjectInterner; +import org.apache.ignite.ci.web.model.hist.VisasHistoryStorage; import org.apache.ignite.ci.web.rest.parms.FullQueryParams; import org.jetbrains.annotations.NotNull; @@ -116,6 +117,11 @@ public class IgnitePersistentTeamcity implements IAnalyticsEnabledTeamcity, ITea @Inject private Ignite ignite; + + /** */ + @Inject + private VisasHistoryStorage visasHistStorage; + /** * Teamcity */ @@ -158,7 +164,8 @@ public class IgnitePersistentTeamcity implements IAnalyticsEnabledTeamcity, ITea buildsCache(), this::addBuildOccurrenceToFailuresStat, buildsFailureRunStatCache(), testRunStatCache(), testFullCache(), - buildProblemsCache()); + buildProblemsCache(), + visasHistStorage.visas()); } @Override diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/DbMigrations.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/DbMigrations.java index a8307ff..a1a92ad 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/DbMigrations.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/DbMigrations.java @@ -17,33 +17,40 @@ package org.apache.ignite.ci.db; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; import javax.cache.Cache; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; import org.apache.ignite.IgniteDataStreamer; +import org.apache.ignite.binary.BinaryObject; import org.apache.ignite.cache.CacheAtomicityMode; import org.apache.ignite.cache.CacheMode; import org.apache.ignite.ci.ITeamcity; import org.apache.ignite.ci.IgnitePersistentTeamcity; -import org.apache.ignite.ci.analysis.Expirable; import org.apache.ignite.ci.analysis.RunStat; import org.apache.ignite.ci.analysis.SuiteInBranch; import org.apache.ignite.ci.analysis.TestInBranch; import org.apache.ignite.ci.issue.Issue; import org.apache.ignite.ci.issue.IssueKey; import org.apache.ignite.ci.issue.IssuesStorage; -import org.apache.ignite.ci.tcmodel.hist.BuildRef; +import org.apache.ignite.ci.observer.CompactBuildsInfo; import org.apache.ignite.ci.tcmodel.result.Build; import org.apache.ignite.ci.tcmodel.result.problems.ProblemOccurrences; import org.apache.ignite.ci.tcmodel.result.stat.Statistics; import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrenceFull; import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrences; +import org.apache.ignite.ci.web.model.CompactContributionKey; +import org.apache.ignite.ci.web.model.CompactVisa; +import org.apache.ignite.ci.web.model.CompactVisaRequest; +import org.apache.ignite.ci.web.model.hist.VisasHistoryStorage; import org.apache.ignite.ci.web.rest.build.GetBuildTestFailures; -import org.apache.ignite.ci.web.rest.pr.GetPrTestFailures; import org.apache.ignite.ci.web.rest.tracked.GetTrackedBranchTestResults; import org.apache.ignite.configuration.CacheConfiguration; import org.slf4j.Logger; @@ -104,6 +111,9 @@ public class DbMigrations { @Deprecated public static final String TEAMCITY_BUILD_CACHE_NAME_OLD = "teamcityBuild"; + /** */ + @Deprecated + public static final String COMPACT_VISAS_HISTORY_CACHE_NAME = "compactVisasHistoryCache"; private static final String CHANGE_INFO_FULL = "changeInfoFull"; private static final String CHANGES_LIST = "changesList"; @@ -131,10 +141,62 @@ public class DbMigrations { IgniteCache<SuiteInBranch, RunStat> suiteHistCache, IgniteCache<TestInBranch, RunStat> testHistCache, Cache<String, TestOccurrenceFull> testFullCache, - Cache<String, ProblemOccurrences> problemsCache) { + Cache<String, ProblemOccurrences> problemsCache, + Cache<CompactContributionKey, List<CompactVisaRequest>> visasCache) { doneMigrations = doneMigrationsCache(); + applyMigration(COMPACT_VISAS_HISTORY_CACHE_NAME + "-to-" + VisasHistoryStorage.VISAS_CACHE_NAME, () -> { + IgniteCache<Object, Object> cache = ignite.cache(COMPACT_VISAS_HISTORY_CACHE_NAME); + if (cache == null) { + System.err.println("Cache not found " + COMPACT_VISAS_HISTORY_CACHE_NAME); + + return; + } + + IgniteCache<Object, Object> oldVisasCache = cache.withKeepBinary(); + + if (Objects.isNull(oldVisasCache)) { + System.out.println("Old cache [" + COMPACT_VISAS_HISTORY_CACHE_NAME + "] not found"); + + return; + } + + int size = oldVisasCache.size(); + + int i = 0; + + for (IgniteCache.Entry<Object, Object> entry : oldVisasCache) { + System.out.println("Migrating entry " + i++ + " from " + size); + + Collection<BinaryObject> binVisaReqs = null; + Object val = entry.getValue(); + if (val instanceof List) + binVisaReqs = (Collection<BinaryObject>)val; + else { + if (val instanceof Map) + binVisaReqs = ((Map<?, BinaryObject>)val).values(); + } + + if (binVisaReqs == null) + continue; + + List<CompactVisaRequest> compactVisaReqs = new ArrayList<>(); + + CompactContributionKey compactKey = ((BinaryObject)entry.getKey()).deserialize(); + + for (BinaryObject binVisaReq : binVisaReqs) { + CompactBuildsInfo compactInfo = ((BinaryObject)binVisaReq.field("compactInfo")).deserialize(); + + CompactVisa compactVisa = ((BinaryObject)binVisaReq.field("compactVisa")).deserialize(); + + compactVisaReqs.add(new CompactVisaRequest(compactVisa, compactInfo, false)); + } + + visasCache.put(compactKey, compactVisaReqs); + } + }); + applyMigration("InitialFillLatestRunsV3", () -> { int size = testOccurrencesCache.size(); if (size > 0) { @@ -429,6 +491,8 @@ public class DbMigrations { applyDestroyIgnCacheMigration(FINISHED_BUILDS); applyDestroyIgnCacheMigration(BUILD_HIST_FINISHED); applyDestroyIgnCacheMigration(BUILD_HIST_FINISHED_OR_FAILED); + + applyDestroyCacheMigration(COMPACT_VISAS_HISTORY_CACHE_NAME, COMPACT_VISAS_HISTORY_CACHE_NAME); } private void applyDestroyIgnCacheMigration(String cacheName) { diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/TcHelperDb.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/TcHelperDb.java index 28a181c..23f7e62 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/TcHelperDb.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/TcHelperDb.java @@ -93,6 +93,21 @@ public class TcHelperDb { Ignition.stop(ignite.name(), false); } + /** */ + @NotNull + public static <K, V> CacheConfiguration<K, V> getCacheV3Config(String name) { + CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(name); + + ccfg.setAffinity(new RendezvousAffinityFunction(false, 8)); + + return ccfg; + } + + /** */ + public static <K, V> CacheConfiguration<K, V> getCacheV3TxConfig(String name) { + return TcHelperDb.<K, V>getCacheV3Config(name).setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); + } + @NotNull public static <K, V> CacheConfiguration<K, V> getCacheV2Config(String name) { CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(name); 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 618b681..7022b45 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 @@ -43,6 +43,7 @@ import org.apache.ignite.ci.util.ExceptionUtil; import org.apache.ignite.ci.web.BackgroundUpdater; import org.apache.ignite.ci.web.TcUpdatePool; import org.apache.ignite.ci.web.model.Visa; +import org.apache.ignite.ci.web.model.hist.VisasHistoryStorage; import org.apache.ignite.ci.web.rest.exception.ServiceStartingException; /** @@ -76,6 +77,7 @@ public class IgniteTcBotModule extends AbstractModule { bind(IssueDetector.class).in(new SingletonScope()); bind(ObserverTask.class).in(new SingletonScope()); bind(BuildObserver.class).in(new SingletonScope()); + bind(VisasHistoryStorage.class).in(new SingletonScope()); bind(ITcHelper.class).to(TcHelper.class).in(new SingletonScope()); bind(IJiraIntegration.class).to(Jira.class).in(new SingletonScope()); 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 b4686f7..98287d2 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 @@ -56,6 +56,8 @@ public class BuildObserver { timer.schedule(observerTask, 0, PERIOD); this.observerTask = observerTask; + + this.observerTask.init(); } /** @@ -66,16 +68,9 @@ public class BuildObserver { } /** */ - public ObserverTask getObserverTask() { - return observerTask; - } - - /** */ public boolean stopObservation(ContributionKey key) { try { - observerTask.removeBuildInfo(key); - - return true; + return observerTask.removeBuildInfo(key); } catch (Exception e) { logger.error("Observation stop: " + e.getMessage(), e); diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/observer/BuildsInfo.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/observer/BuildsInfo.java index e02ad5b..976cf3c 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/observer/BuildsInfo.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/observer/BuildsInfo.java @@ -96,7 +96,7 @@ public class BuildsInfo { /** * @param teamcity Teamcity. */ - public String getState(IAnalyticsEnabledTeamcity teamcity) { + public String getStatus(IAnalyticsEnabledTeamcity teamcity) { boolean isFinished = true; for (Integer id : builds) { @@ -116,14 +116,14 @@ public class BuildsInfo { * @param teamcity Teamcity. */ public boolean isFinished(IAnalyticsEnabledTeamcity teamcity) { - return FINISHED_STATUS.equals(getState(teamcity)); + return FINISHED_STATUS.equals(getStatus(teamcity)); } /** * @param teamcity Teamcity. */ public boolean isCancelled(IAnalyticsEnabledTeamcity teamcity) { - return CANCELLED_STATUS.equals(getState(teamcity)); + return CANCELLED_STATUS.equals(getStatus(teamcity)); } /** 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 68335c8..1d9ed43 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,35 +17,26 @@ package org.apache.ignite.ci.observer; -import com.google.common.base.Preconditions; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; import java.util.TimerTask; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReentrantLock; -import java.util.stream.Collectors; import javax.inject.Inject; -import org.apache.ignite.Ignite; -import org.apache.ignite.IgniteCache; import org.apache.ignite.ci.IAnalyticsEnabledTeamcity; import org.apache.ignite.ci.ITcHelper; -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.jira.IJiraIntegration; -import org.apache.ignite.ci.teamcity.ignited.IStringCompactor; import org.apache.ignite.ci.user.ICredentialsProv; -import org.apache.ignite.ci.web.model.CompactContributionKey; import org.apache.ignite.ci.web.model.ContributionKey; import org.apache.ignite.ci.web.model.Visa; import org.apache.ignite.ci.web.model.VisaRequest; import org.apache.ignite.ci.web.model.hist.VisasHistoryStorage; -import org.apache.ignite.internal.util.typedef.X; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,26 +48,20 @@ public class ObserverTask extends TimerTask { /** Logger. */ private static final Logger logger = LoggerFactory.getLogger(ObserverTask.class); - /** */ - public static final String BUILDS_CACHE_NAME = "compactBuildsInfosCache"; - /** Helper. */ @Inject private ITcHelper tcHelper; /** Helper. */ @Inject private IJiraIntegration jiraIntegration; - /** Ignite. */ - @Inject private Ignite ignite; - /** */ @Inject private VisasHistoryStorage visasHistStorage; /** */ - @Inject private IStringCompactor strCompactor; + private ReentrantLock observationLock = new ReentrantLock(); /** */ - private ReentrantLock observationLock = new ReentrantLock(); + private Map<ContributionKey, BuildsInfo> infos = new ConcurrentHashMap<>(); /** */ @@ -84,61 +69,48 @@ public class ObserverTask extends TimerTask { } /** */ - private IgniteCache<CompactContributionKey, CompactBuildsInfo> compactInfos() { - return ignite.getOrCreateCache(TcHelperDb.getCacheV2TxConfig(BUILDS_CACHE_NAME)); + public void init() { + visasHistStorage.getLastVisas().stream() + .filter(req -> req.isObserving()) + .forEach(req -> infos.put(req.getInfo().getContributionKey(), req.getInfo())); } /** */ @Nullable public BuildsInfo getInfo(ContributionKey key) { - CompactBuildsInfo compactBuildsInfo = compactInfos().get(new CompactContributionKey(key, strCompactor)); - - return Objects.isNull(compactBuildsInfo) ? null : compactBuildsInfo.toBuildInfo(strCompactor); + return infos.get(key); } /** */ public Collection<BuildsInfo> getInfos() { - List<BuildsInfo> buildsInfos = new ArrayList<>(); - - compactInfos().forEach(entry -> buildsInfos.add(entry.getValue().toBuildInfo(strCompactor))); - - return buildsInfos; + return infos.values(); } /** */ public void addInfo(BuildsInfo info) { - visasHistStorage.put(new VisaRequest(info)); + visasHistStorage.updateLastVisaRequest(info.getContributionKey(), req -> req.setObservingStatus(false)); + + visasHistStorage.put(new VisaRequest(info).setObservingStatus(true)); - compactInfos().put(new CompactContributionKey(info.getContributionKey(), strCompactor), - new CompactBuildsInfo(info, strCompactor)); + infos.put(info.getContributionKey(), info); } /** */ - public void removeBuildInfo(ContributionKey key) { + public boolean removeBuildInfo(ContributionKey key) { observationLock.lock(); try { - removeBuildInfo(new CompactContributionKey(key, strCompactor)); - } - finally { - observationLock.unlock(); - } - } + if (!infos.containsKey(key)) + return false; - /** */ - private void removeBuildInfo(CompactContributionKey key) { - try { - boolean rmv = compactInfos().remove(key); + infos.remove(key); - Preconditions.checkState(rmv, "Key not found: " + key.toContributionKey(strCompactor).toString()); - } - catch (Exception e) { - logger.error("Cache remove: " + e.getMessage(), e); + visasHistStorage.updateLastVisaRequest(key, req -> req.setObservingStatus(false)); - throw new RuntimeException("Observer queue: " + - getInfos().stream().map(bi -> bi.getContributionKey().toString()) - .collect(Collectors.joining(", ")) + - " Error: " + X.getFullStackTrace(e)); + return true; + } + finally { + observationLock.unlock(); } } @@ -168,19 +140,17 @@ public class ObserverTask extends TimerTask { int notFinishedBuilds = 0; Set<String> ticketsNotified = new HashSet<>(); - Map<CompactContributionKey, Boolean> rmv = new HashMap<>(); + List<ContributionKey> rmv = new ArrayList<>(); - for (IgniteCache.Entry<CompactContributionKey, CompactBuildsInfo> entry : compactInfos()) { - CompactBuildsInfo compactInfo = entry.getValue(); - - BuildsInfo info = compactInfo.toBuildInfo(strCompactor); + for (ContributionKey key : infos.keySet()) { + BuildsInfo info = infos.get(key); IAnalyticsEnabledTeamcity teamcity = tcHelper.server(info.srvId, tcHelper.getServerAuthorizerCreds()); checkedBuilds += info.buildsCount(); if (info.isCancelled(teamcity)) { - rmv.put(entry.getKey(), false); + rmv.add(key); logger.error("JIRA will not be commented." + " [ticket: " + info.ticket + ", branch:" + info.branchForTc + "] : " + @@ -195,40 +165,33 @@ public class ObserverTask extends TimerTask { continue; } - Visa visa = visasHistStorage.getVisaRequest(info.getContributionKey(), info.date).getResult(); - - if (Objects.isNull(visa)) - continue; + Visa visa = visasHistStorage.getLastVisaRequest(info.getContributionKey()).getResult(); if (!visa.isSuccess()) { ICredentialsProv creds = tcHelper.getServerAuthorizerCreds(); - visa = jiraIntegration.notifyJira(info.srvId, creds, info.buildTypeId, + Visa updatedVisa = jiraIntegration.notifyJira(info.srvId, creds, info.buildTypeId, info.branchForTc, info.ticket); - visasHistStorage.updateVisaRequestResult(info.getContributionKey(), info.date, visa); + visasHistStorage.updateLastVisaRequest(info.getContributionKey(), (req -> req.setResult(updatedVisa))); - if (visa.isSuccess()) + if (updatedVisa.isSuccess()) ticketsNotified.add(info.ticket); + + visa = updatedVisa; } if (visa.isSuccess()) - rmv.put(entry.getKey(), false); + rmv.add(key); } - rmv.entrySet().forEach(entry -> { - try { - removeBuildInfo(entry.getKey()); + rmv.forEach(key -> { + infos.remove(key); - entry.setValue(true); - } - catch (Exception e) { - logger.error(e.getMessage(), e); - } + visasHistStorage.updateLastVisaRequest(key, req -> req.setObservingStatus(false)); }); - return "Checked " + checkedBuilds + " not finished " + notFinishedBuilds + " notified: " + ticketsNotified + - " Rmv problems: " + rmv.values().stream().filter(v -> !v).count(); + return "Checked " + checkedBuilds + " not finished " + notFinishedBuilds + " notified: " + ticketsNotified; } finally { observationLock.unlock(); diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/runners/RemoteClientTmpHelper.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/runners/RemoteClientTmpHelper.java index f3f3802..3fd622a 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/runners/RemoteClientTmpHelper.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/runners/RemoteClientTmpHelper.java @@ -25,8 +25,6 @@ import javax.cache.Cache; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; import org.apache.ignite.Ignition; -import org.apache.ignite.ci.observer.CompactBuildsInfo; -import org.apache.ignite.ci.observer.ObserverTask; import org.apache.ignite.ci.teamcity.ignited.BuildRefCompacted; import org.apache.ignite.ci.teamcity.ignited.BuildRefDao; import org.apache.ignite.ci.teamcity.ignited.ITeamcityIgnited; @@ -88,29 +86,6 @@ public class RemoteClientTmpHelper { dumpBuildRef(cache2, apache, id); dumpBuildRef(cache2, apache, id1); } - - IgniteCache<CompactBuildsInfo, Object> cache = ignite.cache(ObserverTask.BUILDS_CACHE_NAME); - - CompactBuildsInfo cbi = new CompactBuildsInfo(); - - cbi.userName(62541); - cbi.srvId(245001); - cbi.buildTypeId(113); - cbi.branchForTc(2008); - cbi.ticket(263594); - cbi.date(1542263949429L); - - cbi.addBuild(2322291, 2322298, 2322296, 2322294, 2322292, 2322300); - - boolean rmv = cache.remove(cbi); - - try { - Preconditions.checkState(rmv, "can't remove " + cbi); - } - finally { - ignite.close(); - } - } public static void dumpBuildRef(IgniteCache<Long, BuildRefCompacted> cache, int apache, int id) throws IOException { 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 d220d39..8edf836 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 @@ -39,7 +39,6 @@ import org.apache.ignite.ci.github.pure.IGitHubConnection; import org.apache.ignite.ci.github.pure.IGitHubConnectionProvider; 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.observer.BuildsInfo; import org.apache.ignite.ci.tcbot.chain.PrChainsProcessor; import org.apache.ignite.ci.tcmodel.result.Build; @@ -101,7 +100,7 @@ public class TcBotTriggerAndSignOffService { @Inject PrChainsProcessor prChainsProcessor; - + /** */ public void startObserver() { buildObserverProvider.get(); @@ -113,8 +112,6 @@ public class TcBotTriggerAndSignOffService { IAnalyticsEnabledTeamcity teamcity = tcHelper.server(srvId, prov); - ObserverTask observerTask = buildObserverProvider.get().getObserverTask(); - for (VisaRequest visaRequest : visasHistoryStorage.getVisas()) { VisaStatus visaStatus = new VisaStatus(); @@ -122,16 +119,14 @@ public class TcBotTriggerAndSignOffService { Visa visa = visaRequest.getResult(); + boolean isObserving = visaRequest.isObserving(); + visaStatus.date = THREAD_FORMATTER.get().format(info.date); visaStatus.branchName = info.branchForTc; visaStatus.userName = info.userName; visaStatus.ticket = info.ticket; - String buildsStatus = visaStatus.status = info.getState(teamcity); - - BuildsInfo observInfo = observerTask.getInfo(info.getContributionKey()); - - boolean isObserving = Objects.nonNull(observInfo) && observInfo.date.equals(info.date); + String buildsStatus = visaStatus.status = info.getStatus(teamcity); if (FINISHED_STATUS.equals(buildsStatus)) { if (visa.isSuccess()) { @@ -299,6 +294,13 @@ public class TcBotTriggerAndSignOffService { if (!Strings.isNullOrEmpty(ticketFullName)) { BuildsInfo buildsInfo = new BuildsInfo(srvId, prov, ticketFullName, branchForTc); + VisaRequest lastVisaReq = visasHistoryStorage.getLastVisaRequest(buildsInfo.getContributionKey()); + + if (Objects.nonNull(lastVisaReq) && lastVisaReq.isObserving()) + return new SimpleResult("Jira wasn't commented." + + " \"Re-run possible blockers & Comment JIRA\" was triggered for current branch." + + " Wait for the end or cancel exsiting observing."); + Visa visa = jiraIntegration.notifyJira(srvId, prov, suiteId, branchForTc, ticketFullName); visasHistoryStorage.put(new VisaRequest(buildsInfo) diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/CompactVisaRequest.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/CompactVisaRequest.java index 993672c..5ce9a71 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/CompactVisaRequest.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/CompactVisaRequest.java @@ -31,15 +31,29 @@ public class CompactVisaRequest { public final CompactBuildsInfo compactInfo; /** */ + public final boolean isObserving; + + /** */ + public CompactVisaRequest(CompactVisa compactVisa, CompactBuildsInfo compactInfo, boolean isObserving) { + this.compactVisa = compactVisa; + this.isObserving = isObserving; + this.compactInfo = compactInfo; + } + + /** */ public CompactVisaRequest(VisaRequest visaReq, IStringCompactor strCompactor) { compactInfo = new CompactBuildsInfo(visaReq.getInfo(), strCompactor); compactVisa = new CompactVisa(visaReq.getResult(), strCompactor); + + isObserving = visaReq.isObserving(); } /** */ public VisaRequest toVisaRequest(IStringCompactor strCompactor) { - return new VisaRequest(compactInfo.toBuildInfo(strCompactor)).setResult(compactVisa.toVisa(strCompactor)); + return new VisaRequest(compactInfo.toBuildInfo(strCompactor)) + .setResult(compactVisa.toVisa(strCompactor)) + .setObservingStatus(isObserving); } } diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/ContributionKey.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/ContributionKey.java index 570f2c9..89e14d2 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/ContributionKey.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/ContributionKey.java @@ -17,6 +17,7 @@ package org.apache.ignite.ci.web.model; +import java.util.Objects; import org.apache.ignite.ci.teamcity.ignited.IStringCompactor; /** @@ -45,4 +46,23 @@ public class ContributionKey { @Override public String toString() { return "{srv: " + this.srvId + " branch: " + this.branchForTc + '}'; } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (!(o instanceof ContributionKey)) + return false; + + ContributionKey key = (ContributionKey)o; + + return Objects.equals(srvId, key.srvId) && + Objects.equals(branchForTc, key.branchForTc); + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return Objects.hash(srvId, branchForTc); + } } diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/VisaRequest.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/VisaRequest.java index c281a65..7483928 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/VisaRequest.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/VisaRequest.java @@ -31,6 +31,9 @@ public class VisaRequest { private Visa visa; /** */ + private boolean isObserving; + + /** */ public VisaRequest(BuildsInfo info) { this.info = info; this.visa = Visa.emptyVisa(); @@ -52,4 +55,16 @@ public class VisaRequest { return this; } + + /** */ + public VisaRequest setObservingStatus(boolean status) { + isObserving = status; + + return this; + } + + /** */ + public boolean isObserving() { + return isObserving; + } } diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/hist/VisasHistoryStorage.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/hist/VisasHistoryStorage.java index 28299f7..623d42d 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/hist/VisasHistoryStorage.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/hist/VisasHistoryStorage.java @@ -20,11 +20,9 @@ package org.apache.ignite.ci.web.model.hist; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Date; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Objects; +import java.util.function.Consumer; import java.util.stream.Collectors; import javax.cache.Cache; import javax.inject.Inject; @@ -34,7 +32,6 @@ import org.apache.ignite.ci.teamcity.ignited.IStringCompactor; import org.apache.ignite.ci.web.model.CompactContributionKey; import org.apache.ignite.ci.web.model.CompactVisaRequest; import org.apache.ignite.ci.web.model.ContributionKey; -import org.apache.ignite.ci.web.model.Visa; import org.apache.ignite.ci.web.model.VisaRequest; /** @@ -42,7 +39,7 @@ import org.apache.ignite.ci.web.model.VisaRequest; */ public class VisasHistoryStorage { /** */ - private static final String VISAS_CACHE_NAME = "compactVisasHistoryCache"; + public static final String VISAS_CACHE_NAME = "compactVisasHistoryCacheV2"; /** */ @Inject @@ -58,8 +55,8 @@ public class VisasHistoryStorage { } /** */ - private Cache<CompactContributionKey, Map<Date, CompactVisaRequest>> visas() { - return ignite.getOrCreateCache(TcHelperDb.getCacheV2TxConfig(VISAS_CACHE_NAME)); + public Cache<CompactContributionKey, List<CompactVisaRequest>> visas() { + return ignite.getOrCreateCache(TcHelperDb.getCacheV3TxConfig(VISAS_CACHE_NAME)); } /** */ @@ -70,45 +67,86 @@ public class VisasHistoryStorage { visaReq.getInfo().srvId, visaReq.getInfo().branchForTc), strCompactor); - Map<Date, CompactVisaRequest> contributionVisas = visas().get(key); + visas().invoke(key, (entry, arguments) -> { + List<CompactVisaRequest> contributionVisas = entry.getValue(); - if (contributionVisas == null) - contributionVisas = new HashMap<>(); + if (contributionVisas == null) + contributionVisas = new ArrayList<>(); - contributionVisas.put(compactVisaReq.compactInfo.date(), compactVisaReq); + contributionVisas.add(compactVisaReq); - visas().put(key, contributionVisas); + entry.setValue(contributionVisas); + + return contributionVisas; + }); } /** */ - public VisaRequest getVisaRequest(ContributionKey key, Date date) { - Map<Date, CompactVisaRequest> reqs = visas().get(new CompactContributionKey(key, strCompactor)); + public List<VisaRequest> getVisaRequests(ContributionKey key) { + List<CompactVisaRequest> reqs = visas().get(new CompactContributionKey(key, strCompactor)); if (Objects.isNull(reqs)) return null; - return reqs.get(date).toVisaRequest(strCompactor); + return reqs.stream() + .map(compactVisaReq -> compactVisaReq.toVisaRequest(strCompactor)) + .collect(Collectors.toList()); } /** */ - public boolean updateVisaRequestResult(ContributionKey key, Date date, Visa visa) { - VisaRequest req = getVisaRequest(key, date); + public VisaRequest getLastVisaRequest(ContributionKey key) { + List<VisaRequest> reqs = getVisaRequests(key); + + if (Objects.isNull(reqs)) + return null; + + return reqs.get(reqs.size() - 1); + } - if (req == null) + /** */ + public boolean updateLastVisaRequest(ContributionKey key, Consumer<VisaRequest> updater) { + CompactContributionKey compactKey = new CompactContributionKey(key, strCompactor); + + if (!visas().containsKey(compactKey)) return false; - req.setResult(visa); + visas().invoke(compactKey, (entry, arguments) -> { + List<CompactVisaRequest> compactReqs = entry.getValue(); + + int lastIdx = compactReqs.size() - 1; + + VisaRequest req = compactReqs.get(lastIdx).toVisaRequest(strCompactor); + + updater.accept(req); - put(req); + compactReqs.set(lastIdx, new CompactVisaRequest(req, strCompactor)); + + entry.setValue(compactReqs); + + return compactReqs; + }); return true; } /** */ + public Collection<VisaRequest> getLastVisas() { + List<VisaRequest> res = new ArrayList<>(); + + visas().forEach(entry -> { + int lastIdx = entry.getValue().size() - 1; + + res.add(entry.getValue().get(lastIdx).toVisaRequest(strCompactor)); + }); + + return Collections.unmodifiableCollection(res); + } + + /** */ public Collection<VisaRequest> getVisas() { List<VisaRequest> res = new ArrayList<>(); - visas().forEach(entry -> res.addAll(entry.getValue().values().stream() + visas().forEach(entry -> res.addAll(entry.getValue().stream() .map(v -> v.toVisaRequest(strCompactor)) .collect(Collectors.toList())));