From 041bab815c5c554169835993735b8e5c35d436ed Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Tue, 27 Nov 2012 16:24:01 +0100 Subject: o Switching the gitorious code to the actor structure. --- .gitignore | 2 + config.properties.template | 2 + src/main/java/io/trygvis/esper/testing/Config.java | 48 ++++-- src/main/java/io/trygvis/esper/testing/Daos.java | 18 ++- .../java/io/trygvis/esper/testing/HttpClient.java | 4 +- .../esper/testing/gitorious/GitoriousClient.java | 2 +- .../esper/testing/gitorious/GitoriousImporter.java | 174 --------------------- .../esper/testing/gitorious/GitoriousProject.java | 78 --------- .../gitorious/GitoriousProjectDiscovery.java | 172 ++++++++++++++++++++ .../testing/gitorious/GitoriousProjectDto.java | 70 +++++++++ .../testing/gitorious/GitoriousRepositoryDao.java | 29 +++- .../trygvis/esper/testing/nexus/NexusImporter.java | 2 +- .../esper/testing/object/ObjectManager.java | 2 +- .../trygvis/esper/testing/object/ObjectUtil.java | 78 +++++++-- src/main/resources/logback-test.xml | 2 +- 15 files changed, 386 insertions(+), 297 deletions(-) mode change 100644 => 100755 src/main/java/io/trygvis/esper/testing/Daos.java delete mode 100755 src/main/java/io/trygvis/esper/testing/gitorious/GitoriousImporter.java delete mode 100644 src/main/java/io/trygvis/esper/testing/gitorious/GitoriousProject.java create mode 100755 src/main/java/io/trygvis/esper/testing/gitorious/GitoriousProjectDiscovery.java create mode 100755 src/main/java/io/trygvis/esper/testing/gitorious/GitoriousProjectDto.java mode change 100644 => 100755 src/main/java/io/trygvis/esper/testing/gitorious/GitoriousRepositoryDao.java mode change 100644 => 100755 src/main/java/io/trygvis/esper/testing/object/ObjectManager.java mode change 100644 => 100755 src/main/java/io/trygvis/esper/testing/object/ObjectUtil.java diff --git a/.gitignore b/.gitignore index 5eb57e8..c396f47 100755 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ target *.iml config.properties + +*tmp* diff --git a/config.properties.template b/config.properties.template index 90869ce..b552f5e 100755 --- a/config.properties.template +++ b/config.properties.template @@ -1,5 +1,7 @@ gitorious.url= gitorious.sessionValue= +gitorious.projectListUpdateDelay=1 +gitorious.projectListUpdateInterval=60 nexus.updateInterval=3600 diff --git a/src/main/java/io/trygvis/esper/testing/Config.java b/src/main/java/io/trygvis/esper/testing/Config.java index ca0e6ff..31b39dc 100755 --- a/src/main/java/io/trygvis/esper/testing/Config.java +++ b/src/main/java/io/trygvis/esper/testing/Config.java @@ -1,7 +1,5 @@ package io.trygvis.esper.testing; -import ch.qos.logback.classic.*; -import ch.qos.logback.core.util.*; import com.jolbox.bonecp.*; import fj.data.*; import static fj.data.Option.*; @@ -14,8 +12,31 @@ import java.util.*; import java.util.concurrent.atomic.*; public class Config { - public final String gitoriousUrl; - public final Option gitoriousSessionValue; + public static class GitoriousConfig { + public final String url; + public final Option sessionValue; + + public final long projectListUpdateDelay; + + public final long projectListUpdateInterval; + + public GitoriousConfig(String url, Option sessionValue, long projectListUpdateDelay, long projectListUpdateInterval) { + this.url = url; + this.sessionValue = sessionValue; + this.projectListUpdateDelay = projectListUpdateDelay; + this.projectListUpdateInterval = projectListUpdateInterval; + } + + public static GitoriousConfig fromProperties(Properties properties) { + String key = "gitorious.sessionValue"; + return new GitoriousConfig(trimToNull(properties.getProperty("gitorious.url")), + getProperty(properties, key), + getProperty(properties, "gitorious.projectListUpdateDelay").bind(parseLong).valueE("Missing/bad value for 'gitorious.projectListUpdateDelay'"), + getProperty(properties, "gitorious.projectListUpdateInterval").bind(parseLong).valueE("Missing/bad value for 'gitorious.projectListUpdateInterval'")); + } + } + + public final GitoriousConfig gitorious; public final long nexusUpdateInterval; @@ -23,9 +44,8 @@ public class Config { public final String databaseUsername; public final String databasePassword; - public Config(String gitoriousUrl, Option gitoriousSessionValue, long nexusUpdateInterval, String databaseUrl, String databaseUsername, String databasePassword) { - this.gitoriousUrl = gitoriousUrl; - this.gitoriousSessionValue = gitoriousSessionValue; + public Config(GitoriousConfig gitorious, long nexusUpdateInterval, String databaseUrl, String databaseUsername, String databasePassword) { + this.gitorious = gitorious; this.nexusUpdateInterval = nexusUpdateInterval; this.databaseUrl = databaseUrl; this.databaseUsername = databaseUsername; @@ -40,17 +60,17 @@ public class Config { properties.load(inputStream); } - return new Config(trimToNull(properties.getProperty("gitorious.url")), - fromNull(trimToNull(properties.getProperty("gitorious.sessionValue"))), - fromNull(trimToNull(properties.getProperty("nexus.updateInterval"))).bind(parseInt).some() * 1000, + return new Config(GitoriousConfig.fromProperties(properties), + getProperty(properties, "nexus.updateInterval").bind(parseInt).valueE("Missing required property: nexus.updateInterval") * 1000, trimToNull(properties.getProperty("database.url")), trimToNull(properties.getProperty("database.username")), trimToNull(properties.getProperty("database.password"))); } private static void initLogging() { - LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); - StatusPrinter.print(lc); + LoggerFactory.getILoggerFactory(); +// LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); +// StatusPrinter.print(lc); } public BoneCPDataSource createBoneCp() throws SQLException { @@ -78,4 +98,8 @@ public class Config { } }); } + + private static Option getProperty(Properties properties, String key) { + return fromNull(trimToNull(properties.getProperty(key))); + } } diff --git a/src/main/java/io/trygvis/esper/testing/Daos.java b/src/main/java/io/trygvis/esper/testing/Daos.java old mode 100644 new mode 100755 index 1d5322f..0a7a5da --- a/src/main/java/io/trygvis/esper/testing/Daos.java +++ b/src/main/java/io/trygvis/esper/testing/Daos.java @@ -7,6 +7,22 @@ import java.io.*; import java.sql.*; public class Daos implements Closeable { + + public enum OrderDirection { + ASC, DESC, NONE; + + public String toSql(String expression) { + switch (this) { + case ASC: + return expression + "expression"; + case DESC: + return expression + "expression DESC"; + default: + return "1"; + } + } + } + private final Connection connection; public final GitoriousEventDao gitoriousEventDao; public final GitoriousProjectDao gitoriousProjectDao; @@ -20,8 +36,6 @@ public class Daos implements Closeable { gitoriousEventDao = new GitoriousEventDao(connection); gitoriousProjectDao = new GitoriousProjectDao(connection); gitoriousRepositoryDao = new GitoriousRepositoryDao(connection); - - System.out.println("Opened connection " + seq); } public void close() throws IOException { diff --git a/src/main/java/io/trygvis/esper/testing/HttpClient.java b/src/main/java/io/trygvis/esper/testing/HttpClient.java index 79be578..ff2effd 100755 --- a/src/main/java/io/trygvis/esper/testing/HttpClient.java +++ b/src/main/java/io/trygvis/esper/testing/HttpClient.java @@ -22,8 +22,8 @@ public class HttpClient { ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(params, schemeRegistry); ResponseResolver responseResolver = new HTTPClientResponseResolver(new DefaultHttpClient(cm, new BasicHttpParams())); - if (config.gitoriousSessionValue.isSome()) { - responseResolver = new GitoriousResponseResolver(config.gitoriousSessionValue.some(), responseResolver); + if (config.gitorious.sessionValue.isSome()) { + responseResolver = new GitoriousResponseResolver(config.gitorious.sessionValue.some(), responseResolver); } responseResolver = new TimingResponseResolver(responseResolver); diff --git a/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousClient.java b/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousClient.java index f44635f..986d4c1 100755 --- a/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousClient.java +++ b/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousClient.java @@ -83,7 +83,7 @@ public class GitoriousClient { return URI.create(baseUrl + "/" + projectSlug + "/" + repositoryName + ".atom"); } - public Iterable fetchGitoriousEvents(GitoriousRepository repository, Option lastUpdate) throws SQLException, ParseException { + public Iterable fetchGitoriousEvents(GitoriousRepositoryDto repository, Option lastUpdate) throws SQLException, ParseException { System.out.println("Fetching " + repository.atomFeed); long start = currentTimeMillis(); diff --git a/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousImporter.java b/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousImporter.java deleted file mode 100755 index a0efda5..0000000 --- a/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousImporter.java +++ /dev/null @@ -1,174 +0,0 @@ -package io.trygvis.esper.testing.gitorious; - -import com.jolbox.bonecp.*; -import fj.data.*; -import static fj.data.Option.*; -import io.trygvis.esper.testing.*; -import static java.lang.System.*; -import org.apache.abdera.parser.*; - -import java.io.*; -import java.net.*; -import java.sql.*; -import java.util.Date; -import java.util.List; -import java.util.Set; -import java.util.concurrent.*; - -public class GitoriousImporter { - private final BoneCPDataSource boneCp; - private final GitoriousClient gitoriousClient; - - public static void main(String[] args) throws Exception { - Config config = Config.loadFromDisk(); - new GitoriousImporter(config); - } - - public GitoriousImporter(final Config config) throws Exception { - boneCp = config.createBoneCp(); - - gitoriousClient = new GitoriousClient(HttpClient.createHttpClient(config), config.gitoriousUrl); - - final ScheduledThreadPoolExecutor service = new ScheduledThreadPoolExecutor(2); - - boolean projectsUpdateEnabled = true; - int projectsUpdateDelay = 0 * 1000; - int projectsUpdateInterval = 60 * 1000; - - boolean repositoriesUpdateEnabled = false; - int repositoriesUpdateDelay = 0; - int repositoriesUpdateInterval = 60 * 1000; - - if (projectsUpdateEnabled) { - service.scheduleAtFixedRate(new Runnable() { - public void run() { - try { - discoverProjects(); - } catch (Exception e) { - e.printStackTrace(System.out); - } - } - }, projectsUpdateDelay, projectsUpdateInterval, TimeUnit.MILLISECONDS); - } - - if (repositoriesUpdateEnabled) { - service.scheduleAtFixedRate(new Runnable() { - public void run() { - try { - updateRepositories(); - } catch (Exception e) { - e.printStackTrace(System.out); - } - } - }, repositoriesUpdateDelay, repositoriesUpdateInterval, TimeUnit.MILLISECONDS); - } - } - - private void discoverProjects() throws Exception { - Set projects = gitoriousClient.findProjects(); - - long start = currentTimeMillis(); - try (Daos daos = Daos.lookup(boneCp)) { - GitoriousRepositoryDao repoDao = daos.gitoriousRepositoryDao; - GitoriousProjectDao projectDao = daos.gitoriousProjectDao; - - System.out.println("Processing " + projects.size() + " projects."); - for (GitoriousProjectXml project : projects) { - if (projectDao.countProjects(project.slug) == 0) { - System.out.println("New project: " + project.slug + ", has " + project.repositories.size() + " repositories."); - projectDao.insertProject(project.slug); - for (GitoriousRepositoryXml repository : project.repositories) { - URI atomFeed = gitoriousClient.atomFeed(repository.projectSlug, repository.name); - repoDao.insertRepository(repository.projectSlug, repository.name, atomFeed); - } - } else { - for (GitoriousRepositoryXml repository : project.repositories) { - if (repoDao.countRepositories(repository.projectSlug, repository.name) == 0) { - System.out.println("New repository for project " + repository.projectSlug + ": " + repository.name); - URI atomFeed = gitoriousClient.atomFeed(repository.projectSlug, repository.name); - repoDao.insertRepository(repository.projectSlug, repository.name, atomFeed); - } - } - - for (GitoriousRepository repository : repoDao.selectForProject(project.slug)) { - boolean found = false; - for (GitoriousRepositoryXml repo : project.repositories) { - if (repo.projectSlug.equals(repository.projectSlug) && repo.name.equals(repository.name)) { - found = true; - break; - } - } - - if (found) { - continue; - } - - System.out.println("Gone repository for project " + repository.projectSlug + ": " + repository.name); - repoDao.delete(repository); - } - } - } - - for (String project : projectDao.selectSlugs()) { - boolean found = false; - for (GitoriousProjectXml p : projects) { - if (p.slug.equals(project)) { - found = true; - break; - } - } - - if (found) { - continue; - } - - System.out.println("Gone project: " + project); - repoDao.deleteForProject(project); - projectDao.delete(project); - } - - daos.commit(); - } - long end = currentTimeMillis(); - System.out.println("Processed in " + (end - start) + " ms"); - } - - private void updateRepositories() throws SQLException, IOException { - try (Daos daos = Daos.lookup(boneCp)) { - List list = daos.gitoriousRepositoryDao.select(); - System.out.println("Updating " + list.size() + " feeds."); - for (GitoriousRepository repository : list) { - updateFeed(daos, repository); - daos.commit(); - } - } - } - - private void updateFeed(Daos daos, GitoriousRepository repository) throws SQLException { - GitoriousRepositoryDao repositoryDao = daos.gitoriousRepositoryDao; - GitoriousEventDao eventDao = daos.gitoriousEventDao; - - Option lastUpdate = repository.lastSuccessfulUpdate; - - Iterable events; - try { - events = gitoriousClient.fetchGitoriousEvents(repository, lastUpdate); - } catch (ParseException e) { - repositoryDao.updateTimestamp(repository.projectSlug, repository.name, new Timestamp(currentTimeMillis()), Option.none()); - System.out.println("Error parsing " + repository.atomFeed); - e.printStackTrace(System.out); - return; - } - - for (GitoriousEvent event : events) { - if (eventDao.countEntryId(event.entryId) == 0) { - System.out.println("New entry in " + repository.atomFeed + ": " + event.entryId); - eventDao.insertEvent(event); - } else { - System.out.println("Already imported entry: " + event.entryId); - } - } - - repositoryDao.updateTimestamp(repository.projectSlug, repository.name, new Timestamp(currentTimeMillis()), some(new Date())); - } -} diff --git a/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousProject.java b/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousProject.java deleted file mode 100644 index 068866e..0000000 --- a/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousProject.java +++ /dev/null @@ -1,78 +0,0 @@ -package io.trygvis.esper.testing.gitorious; - -import fj.data.*; - -import java.net.*; -import java.util.*; - -public class GitoriousProject implements Comparable { - public final String slug; - - public GitoriousProject(String slug) { - this.slug = slug; - } - - public int compareTo(GitoriousProject other) { - return slug.compareTo(other.slug); - } - - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof GitoriousProject)) return false; - - GitoriousProject that = (GitoriousProject) o; - - if (!slug.equals(that.slug)) return false; - - return true; - } - - public int hashCode() { - int result = slug.hashCode(); - return result; - } -} - -class GitoriousRepository implements Comparable { - public final String projectSlug; - public final String name; - public final URI atomFeed; - public final Option lastUpdate; - public final Option lastSuccessfulUpdate; - - GitoriousRepository(String projectSlug, String name, URI atomFeed, Option lastUpdate, Option lastSuccessfulUpdate) { - this.projectSlug = projectSlug; - this.name = name; - this.atomFeed = atomFeed; - this.lastUpdate = lastUpdate; - this.lastSuccessfulUpdate = lastSuccessfulUpdate; - } - - public int compareTo(GitoriousRepository o) { - int a = projectSlug.compareTo(o.projectSlug); - - if (a != 0) { - return a; - } - - return name.compareTo(o.name); - } - - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof GitoriousRepository)) return false; - - GitoriousRepository that = (GitoriousRepository) o; - - if (!name.equals(that.name)) return false; - if (!projectSlug.equals(that.projectSlug)) return false; - - return true; - } - - public int hashCode() { - int result = projectSlug.hashCode(); - result = 31 * result + name.hashCode(); - return result; - } -} diff --git a/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousProjectDiscovery.java b/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousProjectDiscovery.java new file mode 100755 index 0000000..a236e45 --- /dev/null +++ b/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousProjectDiscovery.java @@ -0,0 +1,172 @@ +package io.trygvis.esper.testing.gitorious; + +import com.jolbox.bonecp.*; +import fj.data.Option; +import static fj.data.Option.*; +import io.trygvis.esper.testing.*; +import io.trygvis.esper.testing.object.ActorRef; +import io.trygvis.esper.testing.object.ObjectFactory; +import io.trygvis.esper.testing.object.ObjectManager; +import io.trygvis.esper.testing.object.ObjectUtil; +import io.trygvis.esper.testing.object.TransactionalActor; + +import static java.lang.System.*; +import org.apache.abdera.parser.*; + +import java.net.*; +import java.sql.*; +import java.util.*; +import java.util.Date; +import java.util.concurrent.*; + +public class GitoriousProjectDiscovery { + private final BoneCPDataSource boneCp; + private final GitoriousClient gitoriousClient; + + public static void main(String[] args) throws Exception { + Config config = Config.loadFromDisk(); + new GitoriousProjectDiscovery(config); + } + + public GitoriousProjectDiscovery(final Config config) throws Exception { + boneCp = config.createBoneCp(); + + gitoriousClient = new GitoriousClient(HttpClient.createHttpClient(config), config.gitorious.url); + + final ScheduledThreadPoolExecutor service = new ScheduledThreadPoolExecutor(1); + + Set repositories = Collections.emptySet(); + try (Connection c = boneCp.getConnection()) { + repositories = new HashSet<>(new Daos(c).gitoriousRepositoryDao.select(Daos.OrderDirection.ASC)); + } catch (SQLException e) { + // ignore + } + + final ObjectManager> repositoryManager = new ObjectManager<>("", repositories, new ObjectFactory>() { + public ActorRef create(GitoriousRepositoryDto repository) { + return ObjectUtil.scheduledActorWithFixedDelay(service, 0, 60, TimeUnit.SECONDS, boneCp, new GitoriousRepository(gitoriousClient, repository)); + } + }); + + ObjectUtil.scheduledActorWithFixedDelay(service, config.gitorious.projectListUpdateDelay, config.gitorious.projectListUpdateInterval, TimeUnit.MILLISECONDS, boneCp, new TransactionalActor() { + @Override + public void act(Connection c) throws Exception { + Daos daos = new Daos(c); + discoverProjects(daos); + repositoryManager.update(daos.gitoriousRepositoryDao.select(Daos.OrderDirection.NONE)); + } + }); + } + + private void discoverProjects(Daos daos) throws Exception { + Set projects = gitoriousClient.findProjects(); + + long start = currentTimeMillis(); + GitoriousRepositoryDao repoDao = daos.gitoriousRepositoryDao; + GitoriousProjectDao projectDao = daos.gitoriousProjectDao; + + System.out.println("Processing " + projects.size() + " projects."); + for (GitoriousProjectXml project : projects) { + if (projectDao.countProjects(project.slug) == 0) { + System.out.println("New project: " + project.slug + ", has " + project.repositories.size() + " repositories."); + projectDao.insertProject(project.slug); + for (GitoriousRepositoryXml repository : project.repositories) { + URI atomFeed = gitoriousClient.atomFeed(repository.projectSlug, repository.name); + repoDao.insertRepository(repository.projectSlug, repository.name, atomFeed); + } + } else { + for (GitoriousRepositoryXml repository : project.repositories) { + if (repoDao.countRepositories(repository.projectSlug, repository.name) == 0) { + System.out.println("New repository for project " + repository.projectSlug + ": " + repository.name); + URI atomFeed = gitoriousClient.atomFeed(repository.projectSlug, repository.name); + repoDao.insertRepository(repository.projectSlug, repository.name, atomFeed); + } + } + + for (GitoriousRepositoryDto repository : repoDao.selectForProject(project.slug)) { + boolean found = false; + for (GitoriousRepositoryXml repo : project.repositories) { + if (repo.projectSlug.equals(repository.projectSlug) && repo.name.equals(repository.name)) { + found = true; + break; + } + } + + if (found) { + continue; + } + + System.out.println("Gone repository for project " + repository.projectSlug + ": " + repository.name); + repoDao.delete(repository); + } + } + } + + for (String project : projectDao.selectSlugs()) { + boolean found = false; + for (GitoriousProjectXml p : projects) { + if (p.slug.equals(project)) { + found = true; + break; + } + } + + if (found) { + continue; + } + + System.out.println("Gone project: " + project); + repoDao.deleteForProject(project); + projectDao.delete(project); + } + + daos.commit(); + + long end = currentTimeMillis(); + System.out.println("Processed in " + (end - start) + " ms"); + } +} + +class GitoriousRepository implements TransactionalActor { + private final GitoriousClient gitoriousClient; + private final GitoriousRepositoryDto repository; + + public GitoriousRepository(GitoriousClient gitoriousClient, GitoriousRepositoryDto repository) { + this.gitoriousClient = gitoriousClient; + this.repository = repository; + } + + public void act(Connection c) throws Exception { + Daos daos = new Daos(c); + updateFeed(daos, repository); + c.commit(); + } + + private void updateFeed(Daos daos, GitoriousRepositoryDto repository) throws SQLException { + GitoriousRepositoryDao repositoryDao = daos.gitoriousRepositoryDao; + GitoriousEventDao eventDao = daos.gitoriousEventDao; + + Option lastUpdate = repository.lastSuccessfulUpdate; + + Iterable events; + try { + events = gitoriousClient.fetchGitoriousEvents(repository, lastUpdate); + } catch (ParseException e) { + repositoryDao.updateTimestamp(repository.projectSlug, repository.name, new Timestamp(currentTimeMillis()), Option.none()); + System.out.println("Error parsing " + repository.atomFeed); + e.printStackTrace(System.out); + return; + } + + for (GitoriousEvent event : events) { + if (eventDao.countEntryId(event.entryId) == 0) { + System.out.println("New entry in " + repository.atomFeed + ": " + event.entryId); + eventDao.insertEvent(event); + } else { + System.out.println("Already imported entry: " + event.entryId); + } + } + + repositoryDao.updateTimestamp(repository.projectSlug, repository.name, new Timestamp(currentTimeMillis()), some(new Date())); + } +} diff --git a/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousProjectDto.java b/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousProjectDto.java new file mode 100755 index 0000000..f147ec6 --- /dev/null +++ b/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousProjectDto.java @@ -0,0 +1,70 @@ +package io.trygvis.esper.testing.gitorious; + +import fj.data.*; + +import java.net.*; +import java.util.*; + +public class GitoriousProjectDto implements Comparable { + public final String slug; + + public GitoriousProjectDto(String slug) { + this.slug = slug; + } + + public int compareTo(GitoriousProjectDto other) { + return slug.compareTo(other.slug); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof GitoriousProjectDto)) return false; + + GitoriousProjectDto that = (GitoriousProjectDto) o; + + return slug.equals(that.slug); + } + + public int hashCode() { + return slug.hashCode(); + } +} + +class GitoriousRepositoryDto implements Comparable { + public final String projectSlug; + public final String name; + public final URI atomFeed; + public final Option lastUpdate; + public final Option lastSuccessfulUpdate; + + GitoriousRepositoryDto(String projectSlug, String name, URI atomFeed, Option lastUpdate, Option lastSuccessfulUpdate) { + this.projectSlug = projectSlug; + this.name = name; + this.atomFeed = atomFeed; + this.lastUpdate = lastUpdate; + this.lastSuccessfulUpdate = lastSuccessfulUpdate; + } + + public int compareTo(GitoriousRepositoryDto o) { + int a = projectSlug.compareTo(o.projectSlug); + + if (a != 0) { + return a; + } + + return name.compareTo(o.name); + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof GitoriousRepositoryDto)) return false; + + GitoriousRepositoryDto that = (GitoriousRepositoryDto) o; + + return name.equals(that.name) && projectSlug.equals(that.projectSlug); + } + + public int hashCode() { + return 31 * projectSlug.hashCode() + name.hashCode(); + } +} diff --git a/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousRepositoryDao.java b/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousRepositoryDao.java old mode 100644 new mode 100755 index 2cf9fce..bdc0e4e --- a/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousRepositoryDao.java +++ b/src/main/java/io/trygvis/esper/testing/gitorious/GitoriousRepositoryDao.java @@ -1,6 +1,7 @@ package io.trygvis.esper.testing.gitorious; import fj.data.*; +import io.trygvis.esper.testing.*; import static io.trygvis.esper.testing.DaoUtil.dateToTimestamp; import static io.trygvis.esper.testing.DaoUtil.timestampToDate; @@ -19,12 +20,12 @@ public class GitoriousRepositoryDao { private static final String ALL_FIELDS = "project_slug, name, atom_feed, last_update, last_successful_update"; - private List executeQuery(PreparedStatement statement) throws SQLException { + private List executeQuery(PreparedStatement statement) throws SQLException { try (ResultSet rs = statement.executeQuery()) { - List list = new ArrayList<>(); + List list = new ArrayList<>(); while (rs.next()) { - list.add(new GitoriousRepository( + list.add(new GitoriousRepositoryDto( rs.getString(1), rs.getString(2), URI.create(rs.getString(3)), @@ -36,7 +37,6 @@ public class GitoriousRepositoryDao { } } - public int countRepositories(String projectSlug, String name) throws SQLException { try (PreparedStatement s = c.prepareStatement("SELECT count(*) FROM gitorious_repository WHERE project_slug=? and name=?")) { s.setString(1, projectSlug); @@ -48,15 +48,28 @@ public class GitoriousRepositoryDao { } } - public List selectForProject(String projectSlug) throws SQLException { + public List selectForProject(String projectSlug) throws SQLException { try (PreparedStatement s = c.prepareStatement("SELECT " + ALL_FIELDS + " FROM gitorious_repository WHERE project_slug=?")) { s.setString(1, projectSlug); return executeQuery(s); } } - public List select() throws SQLException { - try (PreparedStatement s = c.prepareStatement("SELECT " + ALL_FIELDS + " FROM gitorious_repository")) { + public List select(Daos.OrderDirection order) throws SQLException { + String orderBy; + + switch (order) { + case ASC: + orderBy = "ORDER BY project_slug, name"; + break; + case DESC: + orderBy = "ORDER BY project_slug DESC, name DESC"; + break; + default: + orderBy = ""; + } + + try (PreparedStatement s = c.prepareStatement("SELECT " + ALL_FIELDS + " FROM gitorious_repository " + orderBy)) { return executeQuery(s); } } @@ -70,7 +83,7 @@ public class GitoriousRepositoryDao { } } - public void delete(GitoriousRepository repository) throws SQLException { + public void delete(GitoriousRepositoryDto repository) throws SQLException { try (PreparedStatement s = c.prepareStatement("DELETE FROM gitorious_repository WHERE project_slug=? and name=?")) { s.setString(1, repository.projectSlug); s.setString(2, repository.name); diff --git a/src/main/java/io/trygvis/esper/testing/nexus/NexusImporter.java b/src/main/java/io/trygvis/esper/testing/nexus/NexusImporter.java index c6e2460..ea57c43 100755 --- a/src/main/java/io/trygvis/esper/testing/nexus/NexusImporter.java +++ b/src/main/java/io/trygvis/esper/testing/nexus/NexusImporter.java @@ -29,7 +29,7 @@ public class NexusImporter { String name = server.name; - return ObjectUtil.threadedActor(boneCp, "", config.nexusUpdateInterval, new NexusServer(client, server)); + return ObjectUtil.threadedActor(name, config.nexusUpdateInterval, boneCp, new NexusServer(client, server)); } }); diff --git a/src/main/java/io/trygvis/esper/testing/object/ObjectManager.java b/src/main/java/io/trygvis/esper/testing/object/ObjectManager.java old mode 100644 new mode 100755 index cd0dd1e..e850c61 --- a/src/main/java/io/trygvis/esper/testing/object/ObjectManager.java +++ b/src/main/java/io/trygvis/esper/testing/object/ObjectManager.java @@ -13,7 +13,7 @@ public class ObjectManager implements Closeable { this.type = type; this.objectFactory = objectFactory; - update(initialKeys); + update(new HashSet<>(initialKeys)); } public synchronized void update(Collection newKeys) { diff --git a/src/main/java/io/trygvis/esper/testing/object/ObjectUtil.java b/src/main/java/io/trygvis/esper/testing/object/ObjectUtil.java old mode 100644 new mode 100755 index 2d23822..ecfaa34 --- a/src/main/java/io/trygvis/esper/testing/object/ObjectUtil.java +++ b/src/main/java/io/trygvis/esper/testing/object/ObjectUtil.java @@ -3,24 +3,79 @@ package io.trygvis.esper.testing.object; import javax.sql.*; import java.io.*; import java.sql.*; +import java.util.concurrent.*; public class ObjectUtil { - public static ActorRef threadedActor(DataSource dataSource, String threadName, long delay, A actor) { + public static ActorRef threadedActor(String threadName, long delay, DataSource dataSource, A actor) { return new ThreadedActor<>(dataSource, threadName, actor, delay); } - static class ThreadedActor implements ActorRef, Runnable, Closeable { + public static ActorRef scheduledActorWithFixedDelay(ScheduledExecutorService scheduledExecutorService, long initialDelay, long delay, TimeUnit unit, DataSource dataSource, A actor) { + return new ScheduledActor<>(scheduledExecutorService, initialDelay, delay, unit, dataSource, actor); + } + private static class TransactionalActorWrapper implements Runnable { private final DataSource dataSource; private final A actor; + + TransactionalActorWrapper(DataSource dataSource, A actor) { + this.dataSource = dataSource; + this.actor = actor; + } + + public void run() { + try { + Connection c = dataSource.getConnection(); + try { + actor.act(c); + c.commit(); + } + catch(SQLException e) { + c.rollback(); + } finally { + c.close(); + } + } catch (Throwable e) { + System.out.println("Exception in thread " + Thread.currentThread().getName()); + e.printStackTrace(System.out); + } + } + } + + static class ScheduledActor implements ActorRef, Runnable { + private final ScheduledFuture future; + + private final TransactionalActorWrapper actor; + + ScheduledActor(ScheduledExecutorService executorService, long initialDelay, long delay, TimeUnit unit, DataSource dataSource, A actor) { + future = executorService.scheduleWithFixedDelay(this, initialDelay, delay, unit); + this.actor = new TransactionalActorWrapper<>(dataSource, actor); + } + + public A underlying() { + return actor.actor; + } + + public void close() throws IOException { + future.cancel(true); + } + + @Override + public void run() { + actor.run(); + } + } + + static class ThreadedActor implements ActorRef, Runnable, Closeable { + + private final TransactionalActorWrapper actor; private final long delay; private final Thread thread; private boolean shouldRun = true; ThreadedActor(DataSource dataSource, String threadName, A actor, long delay) { - this.dataSource = dataSource; - this.actor = actor; + this.actor = new TransactionalActorWrapper(dataSource, actor); this.delay = delay; thread = new Thread(this, threadName); thread.setDaemon(true); @@ -28,24 +83,13 @@ public class ObjectUtil { } public A underlying() { - return actor; + return actor.actor; } @SuppressWarnings("ConstantConditions") public void run() { while (shouldRun) { - try { - try (Connection c = dataSource.getConnection()) { - try { - actor.act(c); - } finally { - c.rollback(); - } - } - } catch (Exception e) { - System.out.println("Exception in thread " + Thread.currentThread().getName()); - e.printStackTrace(System.out); - } + actor.run(); try { Thread.sleep(delay); diff --git a/src/main/resources/logback-test.xml b/src/main/resources/logback-test.xml index a8416ff..b972562 100755 --- a/src/main/resources/logback-test.xml +++ b/src/main/resources/logback-test.xml @@ -1,4 +1,4 @@ - + -- cgit v1.2.3