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/10/11 18:59:22 UTC
[ignite-teamcity-bot] 02/02: IGNITE-9848: Compressed fat build
development
This is an automated email from the ASF dual-hosted git repository.
dpavlov pushed a commit to branch ignite-9848-load-all-builds
in repository https://gitbox.apache.org/repos/asf/ignite-teamcity-bot.git
commit 4e2b0c46b5a2b2683c11fec49283dd274fe48c59
Author: Dmitriy Pavlov <dp...@apache.org>
AuthorDate: Thu Oct 11 21:59:01 2018 +0300
IGNITE-9848: Compressed fat build development
---
.../apache/ignite/ci/analysis/MultBuildRunCtx.java | 3 -
.../org/apache/ignite/ci/jobs/CheckQueueJob.java | 2 +-
.../apache/ignite/ci/tcmodel/conf/BuildType.java | 21 +++++
.../org/apache/ignite/ci/tcmodel/result/Build.java | 58 +++++++++---
.../ci/teamcity/ignited/BuildRefCompacted.java | 8 +-
.../ci/teamcity/ignited/FatBuildCompacted.java | 67 +++++++++++++
.../ignite/ci/teamcity/ignited/FatBuildDao.java | 105 +++++++++++++++++++++
.../ci/teamcity/ignited/IStringCompactor.java | 8 +-
.../ci/teamcity/ignited/ITeamcityIgnited.java | 9 ++
.../ci/teamcity/ignited/IgniteStringCompactor.java | 3 +-
.../ci/teamcity/ignited/TeamcityIgnitedImpl.java | 12 +--
.../org/apache/ignite/ci/util/ObjectInterner.java | 8 +-
.../java/org/apache/ignite/ci/util/XmlUtil.java | 36 ++++---
.../ignited/IgnitedTcInMemoryIntegrationTest.java | 59 +++++++++++-
14 files changed, 354 insertions(+), 45 deletions(-)
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/analysis/MultBuildRunCtx.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/analysis/MultBuildRunCtx.java
index 6a338a8..29ecc76 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/analysis/MultBuildRunCtx.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/analysis/MultBuildRunCtx.java
@@ -75,9 +75,6 @@ public class MultBuildRunCtx implements ISuiteResults {
builds.add(ctx);
}
- /** Thread dump short file name */
- @Nullable private Integer threadDumpFileIdx;
-
/** Currently running builds */
@Nullable private CompletableFuture<Long> runningBuildCount;
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 f1cdf72..e5733d7 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
@@ -165,7 +165,7 @@ public class CheckQueueJob implements Runnable {
int running = 0;
for (Agent agent : agents) {
- if (agent.getBuild() != null) // || !STATE_RUNNING.equals(agent.getBuild().status)
+ if (agent.getBuild() != null) // || !STATE_RUNNING.equals(agent.getFatBuild().status)
++running;
}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/conf/BuildType.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/conf/BuildType.java
index a7998a6..234b441 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/conf/BuildType.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/conf/BuildType.java
@@ -48,4 +48,25 @@ public class BuildType {
public String getProjectId() {
return projectId;
}
+
+ /**
+ * @param id New id.
+ */
+ public void id(String id) {
+ this.id = id;
+ }
+
+ /**
+ * @param name Name.
+ */
+ public void name(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @param projectId Project id.
+ */
+ public void projectId(String projectId) {
+ this.projectId = projectId;
+ }
}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/result/Build.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/result/Build.java
index 443610c..fc43474 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/result/Build.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/result/Build.java
@@ -28,13 +28,17 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
import org.apache.ignite.ci.analysis.IVersionedEntity;
import org.apache.ignite.ci.tcmodel.changes.ChangesList;
import org.apache.ignite.ci.tcmodel.changes.ChangesListRef;
import org.apache.ignite.ci.tcmodel.conf.BuildType;
import org.apache.ignite.ci.tcmodel.hist.BuildRef;
+import org.apache.ignite.ci.util.ExceptionUtil;
import org.jetbrains.annotations.NotNull;
+import static org.apache.ignite.ci.util.ExceptionUtil.propagateException;
+
/**
* Build from history with test and problems references
*/
@@ -42,11 +46,16 @@ import org.jetbrains.annotations.NotNull;
@XmlAccessorType(XmlAccessType.FIELD)
public class Build extends BuildRef implements IVersionedEntity {
public static final int LATEST_VERSION = 2;
- @XmlElement(name = "buildType") BuildType buildType;
+
+ /** Format local. */
+ @XmlTransient private static ThreadLocal<SimpleDateFormat> fmtLoc
+ = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMdd'T'HHmmssZ"));
+
+ @XmlElement(name = "buildType") private BuildType buildType;
@XmlElement public String queuedDate;
- @XmlElement public String startDate;
- @XmlElement public String finishDate;
+ @XmlElement private String startDate;
+ @XmlElement private String finishDate;
@XmlElement(name = "build")
@XmlElementWrapper(name = "snapshot-dependencies")
@@ -69,6 +78,7 @@ public class Build extends BuildRef implements IVersionedEntity {
/** Information about build triggering. */
@XmlElement(name = "triggered") private Triggered triggered;
+ @XmlTransient
@SuppressWarnings("FieldCanBeLocal") public Integer _version = LATEST_VERSION;
@NotNull public static Build createFakeStub() {
@@ -83,28 +93,43 @@ public class Build extends BuildRef implements IVersionedEntity {
return buildType == null ? null : buildType.getName();
}
- public String getFinishDateDdMmYyyy() {
- Date parse = getFinishDate();
- return new SimpleDateFormat("dd.MM.yyyy").format(parse);
- }
-
+ /**
+ *
+ */
public Date getFinishDate() {
return getDate(finishDate);
}
+ /**
+ *
+ */
public Date getStartDate() {
return getDate(startDate);
}
+ /**
+ * @param ts Timestamp.
+ */
+ public void setStartDateTs(long ts) {
+ startDate = ts < 0 ? null : fmtLoc.get().format(new Date(ts));
+ }
+
+ /**
+ * @param ts Timestamp.
+ */
+ public void setFinishDateTs(long ts) {
+ finishDate = ts < 0 ? null : fmtLoc.get().format(new Date(ts));
+ }
+
+ /**
+ * @param date Date as string.
+ */
private Date getDate(String date) {
try {
- if (date == null)
- return null;
- SimpleDateFormat f = new SimpleDateFormat("yyyyMMdd'T'HHmmssZ");
- return f.parse(date);
+ return date == null ? null : fmtLoc.get().parse(date);
}
catch (ParseException e) {
- throw new IllegalStateException(e);
+ throw propagateException(e);
}
}
@@ -137,4 +162,11 @@ public class Build extends BuildRef implements IVersionedEntity {
public void setTriggered(Triggered triggered) {
this.triggered = triggered;
}
+
+ /**
+ * @param type Type.
+ */
+ public void setBuildType(BuildType type) {
+ buildType = type;
+ }
}
\ No newline at end of file
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefCompacted.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefCompacted.java
index 77eec6d..3becbe4 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefCompacted.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefCompacted.java
@@ -61,13 +61,17 @@ public class BuildRefCompacted {
public BuildRef toBuildRef(IStringCompactor compactor) {
BuildRef res = new BuildRef();
+ fillBuildRefFields(compactor, res);
+
+ return res;
+ }
+
+ protected void fillBuildRefFields(IStringCompactor compactor, BuildRef res) {
res.setId(id < 0 ? null : id);
res.buildTypeId = compactor.getStringFromId(buildTypeId);
res.branchName = compactor.getStringFromId(branchName);
res.status = compactor.getStringFromId(status);
res.state = compactor.getStringFromId(state);
-
- return res;
}
/** {@inheritDoc} */
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/FatBuildCompacted.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/FatBuildCompacted.java
index 10fd975..7254abe 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/FatBuildCompacted.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/FatBuildCompacted.java
@@ -18,6 +18,9 @@ package org.apache.ignite.ci.teamcity.ignited;
import org.apache.ignite.ci.analysis.IVersionedEntity;
import org.apache.ignite.ci.db.Persisted;
+import org.apache.ignite.ci.tcmodel.conf.BuildType;
+import org.apache.ignite.ci.tcmodel.hist.BuildRef;
+import org.apache.ignite.ci.tcmodel.result.Build;
/**
*
@@ -30,6 +33,15 @@ public class FatBuildCompacted extends BuildRefCompacted implements IVersionedEn
/** Entity fields version. */
private short _ver;
+ /** Start date. The number of milliseconds since January 1, 1970, 00:00:00 GMT */
+ private long startDate;
+
+ /** Finish date. The number of milliseconds since January 1, 1970, 00:00:00 GMT */
+ private long finishDate;
+
+ private int projectId = -1;
+ private int name = -1;
+
/** {@inheritDoc} */
@Override public int version() {
return _ver;
@@ -39,4 +51,59 @@ public class FatBuildCompacted extends BuildRefCompacted implements IVersionedEn
@Override public int latestVersion() {
return LATEST_VERSION;
}
+
+ /**
+ * Default constructor.
+ */
+ public FatBuildCompacted() {
+ }
+
+ /**
+ * @param compactor Compactor.
+ * @param ref Reference.
+ */
+ public FatBuildCompacted(IStringCompactor compactor, Build ref) {
+ super(compactor, ref);
+
+ startDate = ref.getStartDate() == null ? -1L : ref.getStartDate().getTime();
+ finishDate = ref.getFinishDate() == null ? -1L : ref.getFinishDate().getTime();
+
+ BuildType type = ref.getBuildType();
+ if (type != null) {
+ projectId = compactor.getStringId(type.getProjectId());
+ name = compactor.getStringId(type.getName());
+ }
+ }
+
+ /**
+ * @param compactor Compacter.
+ */
+ public Build toBuild(IStringCompactor compactor) {
+ Build res = new Build();
+
+ fillBuildRefFields(compactor, res);
+
+ fillBuildFields(compactor, res);
+
+ return res;
+ }
+
+ /**
+ * @param compactor Compactor.
+ * @param res Response.
+ */
+ private void fillBuildFields(IStringCompactor compactor, Build res) {
+ if (startDate > 0)
+ res.setStartDateTs(startDate);
+
+ if (finishDate > 0)
+ res.setFinishDateTs(finishDate);
+
+ BuildType type = new BuildType();
+ type.id(res.buildTypeId());
+ type.name(compactor.getStringFromId(name));
+ type.projectId(compactor.getStringFromId(projectId));
+ res.setBuildType(type);
+ }
+
}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/FatBuildDao.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/FatBuildDao.java
new file mode 100644
index 0000000..e0706d1
--- /dev/null
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/FatBuildDao.java
@@ -0,0 +1,105 @@
+/*
+ * 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.stream.Collectors;
+import javax.inject.Inject;
+import javax.inject.Provider;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.ci.db.TcHelperDb;
+import org.apache.ignite.ci.tcmodel.hist.BuildRef;
+import org.apache.ignite.ci.tcmodel.result.Build;
+import org.apache.ignite.configuration.CacheConfiguration;
+
+/**
+ *
+ */
+public class FatBuildDao {
+ /** Cache name */
+ public static final String TEAMCITY_FAT_BUILD_CACHE_NAME = "teamcityFatBuild";
+
+ /** Ignite provider. */
+ @Inject private Provider<Ignite> igniteProvider;
+
+ /** Builds cache. */
+ private IgniteCache<Long, FatBuildCompacted> buildsCache;
+
+ /** Compactor. */
+ @Inject private IStringCompactor compactor;
+
+ /**
+ *
+ */
+ public void init() {
+ buildsCache = igniteProvider.get().getOrCreateCache(TcHelperDb.getCacheV2Config(TEAMCITY_FAT_BUILD_CACHE_NAME));
+ }
+
+ /**
+ * @param srvIdMaskHigh Server id mask high.
+ * @param ghData Gh data.
+ */
+ public int saveChunk(long srvIdMaskHigh, List<Build> ghData) {
+ Set<Long> ids = ghData.stream().map(BuildRef::getId)
+ .filter(Objects::nonNull)
+ .map(buildId -> buildIdToCacheKey(srvIdMaskHigh, buildId))
+ .collect(Collectors.toSet());
+
+ Map<Long, FatBuildCompacted> existingEntries = buildsCache.getAll(ids);
+ Map<Long, FatBuildCompacted> entriesToPut = new TreeMap<>();
+
+ List<FatBuildCompacted> collect = ghData.stream()
+ .map(ref -> new FatBuildCompacted(compactor, ref))
+ .collect(Collectors.toList());
+
+ for (FatBuildCompacted next : collect) {
+ long cacheKey = buildIdToCacheKey(srvIdMaskHigh, next.id());
+ FatBuildCompacted 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;
+ }
+
+ /**
+ * @param srvIdMaskHigh Server id mask high.
+ * @param buildId Build id.
+ */
+ private long buildIdToCacheKey(long srvIdMaskHigh, int buildId) {
+ return (long)buildId | srvIdMaskHigh << 32;
+ }
+
+ /**
+ * @param srvIdMaskHigh Server id mask high.
+ * @param buildId Build id.
+ */
+ public FatBuildCompacted getFatBuild(int srvIdMaskHigh, int buildId) {
+ return buildsCache.get(buildIdToCacheKey(srvIdMaskHigh, buildId));
+ }
+}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/IStringCompactor.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/IStringCompactor.java
index 59c2986..0ab6d96 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/IStringCompactor.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/IStringCompactor.java
@@ -16,6 +16,9 @@
*/
package org.apache.ignite.ci.teamcity.ignited;
+/**
+ *
+ */
public interface IStringCompactor {
/**
* @param val Value.
@@ -27,5 +30,8 @@ public interface IStringCompactor {
*/
public String getStringFromId(int id);
- public Integer getStringIdIfPresent(String id);
+ /**
+ * @param val Id.
+ */
+ public Integer getStringIdIfPresent(String val);
}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java
index 470d5d1..cfba852 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java
@@ -48,4 +48,13 @@ public interface ITeamcityIgnited {
* @param queueAtTop Put at the top of the build queue.
*/
public Build triggerBuild(String buildTypeId, String branchName, boolean cleanRebuild, boolean queueAtTop);
+
+
+ /**
+ * @param srvId Server id.
+ * @return integer representation of server ID.
+ */
+ public static int serverIdToInt(String srvId) {
+ return Math.abs(srvId.hashCode());
+ }
}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/IgniteStringCompactor.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/IgniteStringCompactor.java
index 5cd2a0b..906b0d5 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/IgniteStringCompactor.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/IgniteStringCompactor.java
@@ -34,6 +34,7 @@ import org.apache.ignite.cache.query.SqlQuery;
import org.apache.ignite.cache.query.annotations.QuerySqlField;
import org.apache.ignite.ci.di.AutoProfiling;
import org.apache.ignite.ci.util.ExceptionUtil;
+import org.apache.ignite.ci.util.ObjectInterner;
import org.apache.ignite.configuration.CacheConfiguration;
import org.jetbrains.annotations.NotNull;
@@ -147,7 +148,7 @@ public class IgniteStringCompactor implements IStringCompactor {
qryCursor.close();
- return next.getValue().val;
+ return ObjectInterner.internString(next.getValue().val);
}
/** {@inheritDoc} */
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
index 746ef38..d8b295d 100644
--- 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
@@ -36,10 +36,10 @@ public class TeamcityIgnitedImpl implements ITeamcityIgnited {
/** Pure HTTP Connection API. */
private ITeamcityConn conn;
-
/** Scheduler. */
@Inject private IScheduler scheduler;
+ /** Build reference DAO. */
@Inject private BuildRefDao buildRefDao;
/** Server ID mask for cache Entries. */
@@ -50,7 +50,7 @@ public class TeamcityIgnitedImpl implements ITeamcityIgnited {
this.srvId = srvId;
this.conn = conn;
- srvIdMaskHigh = Math.abs(srvId.hashCode());
+ srvIdMaskHigh = ITeamcityIgnited.serverIdToInt(srvId);
buildRefDao.init(); //todo init somehow in auto
}
@@ -81,7 +81,7 @@ public class TeamcityIgnitedImpl implements ITeamcityIgnited {
Build build = conn.triggerBuild(buildTypeId, branchName, cleanRebuild, queueAtTop);
//todo may add additional parameter: load builds into DB in sync/async fashion
- runAсtualizeBuilds(srvId, false, build.getId());
+ runActializeBuildRefs(srvId, false, build.getId());
return build;
}
@@ -90,7 +90,7 @@ public class TeamcityIgnitedImpl implements ITeamcityIgnited {
*
*/
private void actualizeRecentBuilds() {
- runAсtualizeBuilds(srvId, false, null);
+ runActializeBuildRefs(srvId, false, null);
// schedule full resync later
scheduler.invokeLater(this::sheduleResync, 60, TimeUnit.SECONDS);
@@ -108,7 +108,7 @@ public class TeamcityIgnitedImpl implements ITeamcityIgnited {
*
*/
private void fullReindex() {
- runAсtualizeBuilds(srvId, true, null);
+ runActializeBuildRefs(srvId, true, null);
}
/**
@@ -118,7 +118,7 @@ public class TeamcityIgnitedImpl implements ITeamcityIgnited {
*/
@MonitoredTask(name = "Actualize BuildRefs, full resync", nameExtArgIndex = 1)
@AutoProfiling
- protected String runAсtualizeBuilds(String srvId, boolean fullReindex,
+ protected String runActializeBuildRefs(String srvId, boolean fullReindex,
@Nullable Integer buildIdCanFinish) {
AtomicReference<String> outLinkNext = new AtomicReference<>();
List<BuildRef> tcDataFirstPage = conn.getBuildRefs(null, outLinkNext);
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/util/ObjectInterner.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/util/ObjectInterner.java
index b58fe96..9834d5c 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/util/ObjectInterner.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/util/ObjectInterner.java
@@ -32,6 +32,7 @@ import java.util.concurrent.atomic.AtomicInteger;
* Class with util method for custom strings deduplication (intern analogue).
*/
public class ObjectInterner {
+ /** String cache. */
private static final LoadingCache<String, String> stringCache
= CacheBuilder
.<String, String>newBuilder()
@@ -39,13 +40,16 @@ public class ObjectInterner {
.initialCapacity(67537)
.build(
new CacheLoader<String, String>() {
- @Override public String load(String key) throws Exception {
+ @Override public String load(String key) {
return key;
}
}
);
- private static String internString(String str) {
+ /**
+ * @param str String.
+ */
+ public static String internString(String str) {
if (str == null)
return null;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/util/XmlUtil.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/util/XmlUtil.java
index 5eb1510..e1e058a 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/util/XmlUtil.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/util/XmlUtil.java
@@ -18,9 +18,11 @@
package org.apache.ignite.ci.util;
import java.io.Reader;
+import java.io.StringWriter;
import java.util.concurrent.ConcurrentHashMap;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
/**
@@ -31,24 +33,34 @@ public class XmlUtil {
private static ConcurrentHashMap<Class, JAXBContext> cachedCtx = new ConcurrentHashMap<>();
public static <T> T load(Class<T> tCls, Reader reader) throws JAXBException {
- final JAXBContext ctx = cachedCtx.computeIfAbsent(tCls, c -> {
- try {
- return JAXBContext.newInstance(tCls);
- }
- catch (JAXBException e) {
- throw new RuntimeException(e);
- }
- });
- Unmarshaller unmarshaller = ctx.createUnmarshaller();
+ Unmarshaller unmarshaller = getContext(tCls).createUnmarshaller();
T unmarshal = (T)unmarshaller.unmarshal(reader);
- int interned = ObjectInterner.internFields(unmarshal);
- // if (interned > 0)
- // System.out.println("Strings saved: " + interned);
+ ObjectInterner.internFields(unmarshal);
return unmarshal;
}
+ public static String save(Object obj) throws JAXBException {
+ Marshaller marshaller = getContext(obj.getClass()).createMarshaller();
+ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+ StringWriter writer = new StringWriter();
+ marshaller.marshal(obj, writer);
+
+ return writer.toString();
+ }
+
+ private static <T> JAXBContext getContext(Class<T> tCls) {
+ return cachedCtx.computeIfAbsent(tCls, c -> {
+ try {
+ return JAXBContext.newInstance(tCls);
+ }
+ catch (JAXBException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
/**
* @param t Text to process.
*/
diff --git a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/ignited/IgnitedTcInMemoryIntegrationTest.java b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/ignited/IgnitedTcInMemoryIntegrationTest.java
index 0cd34d5..7a7809e 100644
--- a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/ignited/IgnitedTcInMemoryIntegrationTest.java
+++ b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/ignited/IgnitedTcInMemoryIntegrationTest.java
@@ -20,15 +20,24 @@ import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Collections;
import java.util.List;
+import javax.xml.bind.JAXBException;
import org.apache.ignite.Ignite;
import org.apache.ignite.Ignition;
import org.apache.ignite.ci.di.scheduler.DirectExecNoWaitSheduler;
import org.apache.ignite.ci.di.scheduler.IScheduler;
+import org.apache.ignite.ci.tcmodel.conf.BuildType;
import org.apache.ignite.ci.tcmodel.hist.BuildRef;
+import org.apache.ignite.ci.tcmodel.result.Build;
import org.apache.ignite.ci.teamcity.pure.ITeamcityHttpConnection;
import org.apache.ignite.ci.user.ICredentialsProv;
+import org.apache.ignite.ci.util.XmlUtil;
import org.jetbrains.annotations.NotNull;
import org.junit.AfterClass;
import org.junit.BeforeClass;
@@ -54,16 +63,15 @@ public class IgnitedTcInMemoryIntegrationTest {
*
*/
@BeforeClass
- public static void startIgnite(){
+ public static void startIgnite() {
ignite = Ignition.start();
}
-
/**
*
*/
@AfterClass
- public static void stopIgnite(){
+ public static void stopIgnite() {
ignite.close();
}
@@ -72,7 +80,7 @@ public class IgnitedTcInMemoryIntegrationTest {
ITeamcityHttpConnection http = Mockito.mock(ITeamcityHttpConnection.class);
when(http.sendGet(anyString(), anyString())).thenAnswer(
- (invocationOnMock)->{
+ (invocationOnMock) -> {
String url = invocationOnMock.getArgument(1);
if (url.contains("/app/rest/latest/builds?locator=defaultFilter:false,count:1000,start:1000"))
@@ -132,4 +140,47 @@ public class IgnitedTcInMemoryIntegrationTest {
return mock;
}
+
+ @Test
+ public void testFatBuild() throws JAXBException, IOException {
+ InputStream stream = getClass().getResourceAsStream("/build.xml");
+ Build refBuild = XmlUtil.load(Build.class, new InputStreamReader(stream));
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ @Override protected void configure() {
+ bind(Ignite.class).toInstance(ignite);
+ bind(IStringCompactor.class).to(IgniteStringCompactor.class);
+ }
+ });
+
+ FatBuildDao instance = injector.getInstance(FatBuildDao.class);
+ instance.init();
+
+ int srvIdMaskHigh = ITeamcityIgnited.serverIdToInt(APACHE);
+ int i = instance.saveChunk(srvIdMaskHigh, Collections.singletonList(refBuild));
+ assertEquals(1, i);
+
+ FatBuildCompacted fatBuild = instance.getFatBuild(srvIdMaskHigh, 2039380);
+
+ Build actBuild = fatBuild.toBuild(injector.getInstance(IStringCompactor.class));
+
+ String save = XmlUtil.save(actBuild);
+
+ System.out.println(save);
+
+ FileWriter writer = new FileWriter("src/test/resources/build2.xml");
+ writer.write(save);
+ writer.close();
+
+ assertEquals(refBuild.getId(), actBuild.getId());
+ assertEquals(refBuild.status(), actBuild.status());
+ assertEquals(refBuild.state(), actBuild.state());
+ assertEquals(refBuild.buildTypeId(), actBuild.buildTypeId());
+ assertEquals(refBuild.getStartDate(), actBuild.getStartDate());
+ assertEquals(refBuild.getFinishDate(), actBuild.getFinishDate());
+ BuildType refBt = refBuild.getBuildType();
+ BuildType actBt = actBuild.getBuildType();
+ assertEquals(refBt.getName(), actBt.getName());
+ assertEquals(refBt.getProjectId(), actBt.getProjectId());
+ assertEquals(refBt.getId(), actBt.getId());
+ }
}