diff options
Diffstat (limited to 'src/main')
14 files changed, 312 insertions, 86 deletions
diff --git a/src/main/java/io/trygvis/esper/testing/AbstractDto.java b/src/main/java/io/trygvis/esper/testing/AbstractDto.java new file mode 100644 index 0000000..6c2e778 --- /dev/null +++ b/src/main/java/io/trygvis/esper/testing/AbstractDto.java @@ -0,0 +1,28 @@ +package io.trygvis.esper.testing; + +import org.joda.time.*; + +import java.util.*; + +public abstract class AbstractDto { + public final UUID uuid; + public final DateTime createdDate; + + protected AbstractDto(UUID uuid, DateTime createdDate) { + this.uuid = uuid; + this.createdDate = createdDate; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof AbstractDto)) return false; + + AbstractDto that = (AbstractDto) o; + + return uuid.equals(that.uuid); + } + + public int hashCode() { + return uuid.hashCode(); + } +} diff --git a/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsBuildDto.java b/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsBuildDto.java index 28f597d..8076eaa 100644 --- a/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsBuildDto.java +++ b/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsBuildDto.java @@ -1,13 +1,12 @@ package io.trygvis.esper.testing.jenkins; +import io.trygvis.esper.testing.*; import org.joda.time.*; import java.net.*; import java.util.*; -public class JenkinsBuildDto { - public final UUID uuid; - public final DateTime created_date; +public class JenkinsBuildDto extends AbstractDto { public final UUID job; public final String entryId; public final URI url; @@ -16,9 +15,8 @@ public class JenkinsBuildDto { public final int duration; public final DateTime timestamp; - JenkinsBuildDto(UUID uuid, DateTime created_date, UUID job, String entryId, URI url, String result, int number, int duration, DateTime timestamp) { - this.uuid = uuid; - this.created_date = created_date; + JenkinsBuildDto(UUID uuid, DateTime createdDate, UUID job, String entryId, URI url, String result, int number, int duration, DateTime timestamp) { + super(uuid, createdDate); this.job = job; this.entryId = entryId; this.url = url; diff --git a/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsBuildXml.java b/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsBuildXml.java index 169a65c..cb92736 100644 --- a/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsBuildXml.java +++ b/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsBuildXml.java @@ -17,9 +17,7 @@ import fj.data.Option; import io.trygvis.esper.testing.Util; import static fj.data.List.iterableList; -import static fj.data.Option.none; -import static fj.data.Option.some; -import static fj.data.Option.somes; +import static fj.data.Option.*; import static io.trygvis.esper.testing.Util.childText; import static io.trygvis.esper.testing.Util.parseInt; import static io.trygvis.esper.testing.jenkins.JenkinsBuildXml.ChangeSetItemXml.parseChangeSetItem; @@ -109,16 +107,13 @@ public class JenkinsBuildXml { public final String msg; - /** - * Only subversion has this field - */ - public final Option<String> user; + public final Option<AuthorXml> author; - public ChangeSetItemXml(String commitId, DateTime date, String msg, Option<String> user) { + public ChangeSetItemXml(String commitId, DateTime date, String msg, Option<AuthorXml> author) { this.commitId = commitId; this.date = date; this.msg = msg; - this.user = user; + this.author = author; } private static final F<String, Option<DateTime>> parseDate = new F<String, Option<DateTime>>() { @@ -145,13 +140,37 @@ public class JenkinsBuildXml { Option<String> commitId = childText(item, "commitId"); Option<DateTime> date = childText(item, "date").bind(parseDate); Option<String> msg = childText(item, "msg"); - Option<String> user = childText(item, "user"); if (commitId.isNone() || date.isNone() || msg.isNone()) { return none(); } - return some(new ChangeSetItemXml(commitId.some(), date.some(), msg.some(), user)); + Option<AuthorXml> author = fromNull(item.getChild("author")).bind(AuthorXml.parseAuthorXml); + + return some(new ChangeSetItemXml(commitId.some(), date.some(), msg.some(), author)); + } + }; + } + + public static class AuthorXml { + public final String absoluteUrl; + public final String fullName; + + public AuthorXml(String absoluteUrl, String fullName) { + this.absoluteUrl = absoluteUrl; + this.fullName = fullName; + } + + public static final F<Element, Option<AuthorXml>> parseAuthorXml = new F<Element, Option<AuthorXml>>() { + public Option<AuthorXml> f(Element element) { + Option<String> absoluteUrl = childText(element, "absoluteUrl"); + Option<String> fullName = childText(element, "fullName"); + + if(absoluteUrl.isNone() || fullName.isNone()) { + return none(); + } + + return some(new AuthorXml(absoluteUrl.some(), fullName.some())); } }; } diff --git a/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsDao.java b/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsDao.java index bf1954e..2cfff80 100644 --- a/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsDao.java +++ b/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsDao.java @@ -1,6 +1,7 @@ package io.trygvis.esper.testing.jenkins; import fj.data.*; +import io.trygvis.esper.testing.sql.*; import org.joda.time.*; import java.net.*; @@ -9,6 +10,7 @@ import java.util.*; import java.util.List; import static fj.data.Option.*; +import static io.trygvis.esper.testing.sql.SqlOption.fromRs; import static java.lang.System.*; public class JenkinsDao { @@ -21,6 +23,8 @@ public class JenkinsDao { public static final String JENKINS_BUILD = "uuid, created_date, job, entry_id, url, result, number, duration, timestamp"; + public static final String JENKINS_USER = "uuid, created_date, server, absolute_url"; + public JenkinsDao(Connection c) { this.c = c; } @@ -60,22 +64,35 @@ public class JenkinsDao { return list; } - private JenkinsBuildDto jenkinsBuild(ResultSet rs) throws SQLException { - int i = 1; - return new JenkinsBuildDto( - UUID.fromString(rs.getString(i++)), - new DateTime(rs.getTimestamp(i++).getTime()), - UUID.fromString(rs.getString(i++)), - rs.getString(i++), - URI.create(rs.getString(i++)), - rs.getString(i++), - rs.getInt(i++), - rs.getInt(i++), - new DateTime(rs.getTimestamp(i).getTime())); - } + public static final SqlF<ResultSet, JenkinsBuildDto> jenkinsBuild = new SqlF<ResultSet, JenkinsBuildDto>() { + public JenkinsBuildDto apply(ResultSet rs) throws SQLException { + int i = 1; + return new JenkinsBuildDto( + UUID.fromString(rs.getString(i++)), + new DateTime(rs.getTimestamp(i++).getTime()), + UUID.fromString(rs.getString(i++)), + rs.getString(i++), + URI.create(rs.getString(i++)), + rs.getString(i++), + rs.getInt(i++), + rs.getInt(i++), + new DateTime(rs.getTimestamp(i).getTime())); + } + }; + + public static final SqlF<ResultSet, JenkinsUserDto> jenkinsUser = new SqlF<ResultSet, JenkinsUserDto>() { + public JenkinsUserDto apply(ResultSet rs) throws SQLException { + int i = 1; + return new JenkinsUserDto( + UUID.fromString(rs.getString(i++)), + new DateTime(rs.getTimestamp(i++).getTime()), + UUID.fromString(rs.getString(i++)), + rs.getString(i)); + } + }; public List<JenkinsServerDto> selectServers(boolean enabledOnly) throws SQLException { - String sql = "SELECT " + JENKINS_SERVER + " FROM jenkins_server "; + String sql = "SELECT " + JENKINS_SERVER + " FROM jenkins_server"; if (enabledOnly) { sql += " WHERE enabled=true"; @@ -137,17 +154,11 @@ public class JenkinsDao { } } - public Option<JenkinsBuildDto> selectBuildByEntryId(String id) throws SQLException { + public SqlOption<JenkinsBuildDto> selectBuildByEntryId(String id) throws SQLException { try (PreparedStatement s = c.prepareStatement("SELECT " + JENKINS_BUILD + " FROM jenkins_build WHERE entry_id=?")) { int i = 1; s.setString(i, id); - ResultSet rs = s.executeQuery(); - - if (!rs.next()) { - return none(); - } - - return some(jenkinsBuild(rs)); + return fromRs(s.executeQuery()).map(jenkinsBuild); } } @@ -169,4 +180,27 @@ public class JenkinsDao { return uuid; } } + + public UUID insertUser(UUID server, String absoluteUrl) throws SQLException { + try (PreparedStatement s = c.prepareStatement("INSERT INTO jenkins_user(" + JENKINS_USER + ") VALUES(?, ?, ?, ?)")) { + UUID uuid = UUID.randomUUID(); + int i = 1; + s.setString(i++, uuid.toString()); + s.setTimestamp(i++, new Timestamp(currentTimeMillis())); + s.setString(i++, server.toString()); + s.setString(i, absoluteUrl); + s.executeUpdate(); + + return uuid; + } + } + + public SqlOption<JenkinsUserDto> selectUser(UUID server, String absoluteUrl) throws SQLException { + try (PreparedStatement s = c.prepareStatement("SELECT " + JENKINS_USER + " FROM jenkins_user WHERE server=? AND absolute_url=?")) { + int i = 1; + s.setString(i++, server.toString()); + s.setString(i, absoluteUrl); + return fromRs(s.executeQuery()).map(jenkinsUser); + } + } } diff --git a/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsJobDto.java b/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsJobDto.java index 8ee731c..f4ef401 100644 --- a/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsJobDto.java +++ b/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsJobDto.java @@ -1,21 +1,19 @@ package io.trygvis.esper.testing.jenkins; import fj.data.*; +import io.trygvis.esper.testing.*; import org.joda.time.*; import java.net.*; import java.util.*; -public class JenkinsJobDto { - public final UUID uuid; - public final DateTime created_date; +public class JenkinsJobDto extends AbstractDto { public final UUID server; public final URI url; public final Option<String> displayName; - JenkinsJobDto(UUID uuid, DateTime created_date, UUID server, URI url, Option<String> displayName) { - this.uuid = uuid; - this.created_date = created_date; + JenkinsJobDto(UUID uuid, DateTime createdDate, UUID server, URI url, Option<String> displayName) { + super(uuid, createdDate); this.server = server; this.url = url; this.displayName = displayName; diff --git a/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsServerActor.java b/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsServerActor.java index ebc46ce..ad22157 100644 --- a/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsServerActor.java +++ b/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsServerActor.java @@ -2,12 +2,14 @@ package io.trygvis.esper.testing.jenkins; import fj.data.*; import io.trygvis.esper.testing.object.*; +import io.trygvis.esper.testing.sql.*; import org.slf4j.*; import java.net.*; import java.sql.*; import java.util.List; import java.util.*; +import java.util.Set; import static io.trygvis.esper.testing.jenkins.JenkinsClient.*; import static java.lang.System.*; @@ -38,8 +40,10 @@ public class JenkinsServerActor implements TransactionalActor { int i = 0; + Set<String> authorUrls = new TreeSet<>(); + for (JenkinsEntryXml entry : list) { - Option<JenkinsBuildDto> o = dao.selectBuildByEntryId(entry.id); + SqlOption<JenkinsBuildDto> o = dao.selectBuildByEntryId(entry.id); if (o.isSome()) { logger.debug("Old build: " + entry.id); @@ -62,6 +66,25 @@ public class JenkinsServerActor implements TransactionalActor { } String result = build.result.some(); + if(build.changeSet.isSome()) { + JenkinsBuildXml.ChangeSetXml changeSetXml = build.changeSet.some(); + + for (JenkinsBuildXml.ChangeSetItemXml item : changeSetXml.items) { + if(item.author.isNone()) { + continue; + } + + String url = item.author.some().absoluteUrl; + + boolean newUser = authorUrls.add(url); + + if(newUser && dao.selectUser(server.uuid, url).isNone()) { + logger.info("New user: {}", url); + dao.insertUser(server.uuid, url); + } + } + } + URI jobUrl = extrapolateJobUrlFromBuildUrl(build.url.toASCIIString()); Option<JenkinsJobDto> jobDtoOption = dao.selectJobByUrl(jobUrl); @@ -71,7 +94,7 @@ public class JenkinsServerActor implements TransactionalActor { if (jobDtoOption.isSome()) { job = jobDtoOption.some().uuid; } else { - logger.info("New job: " + jobUrl + ", fetching info"); + logger.info("New job: {}, fetching info", jobUrl); Option<JenkinsJobXml> jobXmlOption = client.fetchJob(apiXml(jobUrl)); @@ -83,7 +106,7 @@ public class JenkinsServerActor implements TransactionalActor { job = dao.insertJob(server.uuid, xml.url, xml.type, xml.displayName); - logger.info("New job: " + xml.displayName.orSome(xml.url.toASCIIString()) + ", uuid=" + job); + logger.info("New job: {}, uuid={}", xml.displayName.orSome(xml.url.toASCIIString()), job); } i++; diff --git a/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsServerDto.java b/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsServerDto.java index 225b786..6ad8e36 100644 --- a/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsServerDto.java +++ b/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsServerDto.java @@ -1,35 +1,18 @@ package io.trygvis.esper.testing.jenkins; +import io.trygvis.esper.testing.*; import org.joda.time.*; import java.net.*; import java.util.*; -public class JenkinsServerDto { - public final UUID uuid; - public final DateTime created_date; +public class JenkinsServerDto extends AbstractDto { public final URI url; public final boolean enabled; - JenkinsServerDto(UUID uuid, DateTime created_date, URI url, boolean enabled) { - this.uuid = uuid; - this.created_date = created_date; + JenkinsServerDto(UUID uuid, DateTime createdDate, URI url, boolean enabled) { + super(uuid, createdDate); this.url = url; this.enabled = enabled; } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - JenkinsServerDto that = (JenkinsServerDto) o; - - return uuid.equals(that.uuid); - } - - @Override - public int hashCode() { - return uuid.hashCode(); - } } diff --git a/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsUserDto.java b/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsUserDto.java new file mode 100644 index 0000000..d3ea996 --- /dev/null +++ b/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsUserDto.java @@ -0,0 +1,17 @@ +package io.trygvis.esper.testing.jenkins; + +import io.trygvis.esper.testing.*; +import org.joda.time.*; + +import java.util.*; + +public class JenkinsUserDto extends AbstractDto { + public final UUID server; + public final String absoluteUrl; + + public JenkinsUserDto(UUID uuid, DateTime createdDate, UUID server, String absoluteUrl) { + super(uuid, createdDate); + this.server = server; + this.absoluteUrl = absoluteUrl; + } +} diff --git a/src/main/java/io/trygvis/esper/testing/sql/SqlF.java b/src/main/java/io/trygvis/esper/testing/sql/SqlF.java new file mode 100644 index 0000000..fb05e4c --- /dev/null +++ b/src/main/java/io/trygvis/esper/testing/sql/SqlF.java @@ -0,0 +1,15 @@ +package io.trygvis.esper.testing.sql; + +import java.sql.*; + +public abstract class SqlF<A, B> { + public abstract B apply(A a) throws SQLException; + + public <C> SqlF<A, C> andThen(final SqlF<B, C> f) { + return new SqlF<A, C>() { + public C apply(A a) throws SQLException { + return f.apply(SqlF.this.apply(a)); + } + }; + } +} diff --git a/src/main/java/io/trygvis/esper/testing/sql/SqlOption.java b/src/main/java/io/trygvis/esper/testing/sql/SqlOption.java new file mode 100644 index 0000000..058435e --- /dev/null +++ b/src/main/java/io/trygvis/esper/testing/sql/SqlOption.java @@ -0,0 +1,83 @@ +package io.trygvis.esper.testing.sql; + +import java.sql.*; + +public abstract class SqlOption<A> { + public static <A> SqlOption<A> none() { + return new None<>(); + } + + public static <A> SqlOption<A> some(A a) { + return new Some<>(a); + } + + public static SqlOption<ResultSet> fromRs(ResultSet rs) throws SQLException { + if (!rs.next()) { + return none(); + } + + return some(rs); + } + + // ----------------------------------------------------------------------- + // + // ----------------------------------------------------------------------- + + public abstract <B> SqlOption<B> map(SqlF<A, B> f) throws SQLException; + + public <B> SqlOption<B> flatMap(SqlF<A, SqlOption<B>> f) throws SQLException { + SqlOption<SqlOption<B>> x = map(f); + + if (x.isNone()) { + return none(); + } + + return x.get(); + } + + public abstract A get() throws SQLException; + + public abstract boolean isSome(); + + public boolean isNone() { + return !isSome(); + } + + // ----------------------------------------------------------------------- + // + // ----------------------------------------------------------------------- + + private static class None<A> extends SqlOption<A> { + public <B> SqlOption<B> map(SqlF<A, B> f) { + return none(); + } + + public A get() throws SQLException { + throw new SQLException("get() on None"); + } + + public boolean isSome() { + return false; + } + } + + private static class Some<A> extends SqlOption<A> { + private final A a; + + private Some(A a) { + this.a = a; + } + + public <B> SqlOption<B> map(SqlF<A, B> f) throws SQLException { + return some(f.apply(a)); + } + + public A get() { + return a; + } + + public boolean isSome() { + return true; + } + } +} diff --git a/src/main/java/io/trygvis/esper/testing/web/JenkinsResource.java b/src/main/java/io/trygvis/esper/testing/web/JenkinsResource.java index 24ed367..b9e997f 100644 --- a/src/main/java/io/trygvis/esper/testing/web/JenkinsResource.java +++ b/src/main/java/io/trygvis/esper/testing/web/JenkinsResource.java @@ -60,7 +60,7 @@ public class JenkinsResource { private JenkinsServerJson getJenkinsServerJson(Daos daos, JenkinsServerDto server) throws SQLException { int count = daos.jenkinsDao.selectJobCountForServer(server.uuid); - return new JenkinsServerJson(server.uuid, server.created_date, server.url, server.enabled, count); + return new JenkinsServerJson(server.uuid, server.createdDate, server.url, server.enabled, count); } private <T> T get(DatabaseAccess.DaosCallback<Option<T>> callback) throws SQLException { diff --git a/src/main/resources/ddl-core.sql b/src/main/resources/ddl-core.sql index 8201c31..fb85585 100644 --- a/src/main/resources/ddl-core.sql +++ b/src/main/resources/ddl-core.sql @@ -1,17 +1,37 @@ BEGIN; -DROP TABLE IF EXISTS subscription_gitorious_repository; -DROP TABLE IF EXISTS subscriber; +CREATE TABLE table_poller_status ( + poller_name VARCHAR(100) NOT NULL, + last_created_date TIMESTAMP, + last_run TIMESTAMP, + duration INT, + status VARCHAR(1000), + CONSTRAINT pk_job_status PRIMARY KEY (poller_name) +); + +CREATE TABLE person ( + uuid CHAR(36) NOT NULL, + created_date TIMESTAMP NOT NULL, +--The users from the different jenkins servers this user has claimed + jenkins_users CHAR(36) [], + CONSTRAINT pk_person PRIMARY KEY (uuid) +); -CREATE TABLE subscriber ( - name VARCHAR(100) PRIMARY KEY +-- Badges received +CREATE TABLE person_badge ( + uuid CHAR(36) NOT NULL, + created_date TIMESTAMP NOT NULL, + CONSTRAINT pk_person_badge PRIMARY KEY (uuid) ); -CREATE TABLE subscription_gitorious_repository ( - subscriber_name VARCHAR(100) REFERENCES subscriber (name), - gitorious_repository_project_slug VARCHAR(100), - gitorious_repository_name VARCHAR(100), - CONSTRAINT gitorious_repository FOREIGN KEY (gitorious_repository_project_slug, gitorious_repository_name) REFERENCES gitorious_repository (project_slug, name) +-- Badges the person is working on +CREATE TABLE person_badge_progress ( + uuid CHAR(36) NOT NULL, + created_date TIMESTAMP NOT NULL, + + name VARCHAR(100) NOT NULL, + + CONSTRAINT pk_person_badge_progress PRIMARY KEY (uuid) ); COMMIT; diff --git a/src/main/resources/ddl-jenkins.sql b/src/main/resources/ddl-jenkins.sql index 01275eb..65b3e35 100644 --- a/src/main/resources/ddl-jenkins.sql +++ b/src/main/resources/ddl-jenkins.sql @@ -46,6 +46,18 @@ CREATE TABLE jenkins_build ( CONSTRAINT uq_jenkins_build__id UNIQUE (entry_id) ); +CREATE INDEX ix_jenkins_build__created_date ON jenkins_build (created_date); + +CREATE TABLE jenkins_user ( + uuid CHAR(36) NOT NULL, + created_date TIMESTAMP NOT NULL, + server CHAR(36) NOT NULL, + absolute_url VARCHAR(1000) NOT NULL, + CONSTRAINT pk_jenkins_user PRIMARY KEY (uuid), + CONSTRAINT fk_jenkins_user__server FOREIGN KEY (server) REFERENCES jenkins_server (uuid), + CONSTRAINT uq_jenkins_user__absolute_url UNIQUE (absolute_url) +); + INSERT INTO jenkins_server (uuid, created_date, url, enabled) VALUES ('782a75f6-40a4-11e2-aca6-20cf30557fa0', CURRENT_TIMESTAMP, 'https://builds.apache.org', FALSE), ('4c473c86-40ad-11e2-ae61-20cf30557fa0', CURRENT_TIMESTAMP, 'http://ci.jruby.org', FALSE), diff --git a/src/main/webapp/apps/jenkinsApp/server.html b/src/main/webapp/apps/jenkinsApp/server.html index 9213c73..9b27dfe 100644 --- a/src/main/webapp/apps/jenkinsApp/server.html +++ b/src/main/webapp/apps/jenkinsApp/server.html @@ -11,19 +11,15 @@ <tbody> <tr> <th>URL</th> - <td>{{server.url}}</td> + <td><a href="{{server.url}}">{{server.url}}</a></td> </tr> <tr> <th>Enabled</th> <td>{{server.enabled}}</td> </tr> <tr> - <th>Visit</th> - <td><a href="{{server.url}}">{{server.url}}</a></td> - </tr> - <tr> - <th>Job Count</th> - <td>{{server.jobCount}}</td> + <th>Stats</th> + <td>{{server.jobCount}} jobs, {{server.buildCount}} builds</td> </tr> </tbody> </table> |