package io.trygvis.esper.testing.jenkins; import fj.*; import fj.data.*; import io.trygvis.esper.testing.jenkins.JenkinsJobXml.*; import io.trygvis.esper.testing.util.*; import org.apache.abdera.*; import org.apache.abdera.model.*; import org.apache.abdera.parser.*; import org.codehaus.httpcache4j.cache.*; import org.jdom2.Document; import org.jdom2.Element; import org.joda.time.DateTime; import org.slf4j.*; import java.io.*; import java.net.*; import java.util.*; import java.util.List; import static fj.P.p; import static fj.data.Option.*; import static io.trygvis.esper.testing.util.HttpClient.inputStreamOnly; import static java.lang.System.currentTimeMillis; import static org.apache.commons.lang.StringUtils.*; public class JenkinsClient { private static final Logger logger = LoggerFactory.getLogger(JenkinsClient.class); private final XmlHttpClient xmlHttpClient; private final HttpClient> jenkinsEntryXmlClient; private final Parser parser; public JenkinsClient(HTTPCache http, Abdera abdera) { this.xmlHttpClient = new XmlHttpClient(http); this.parser = abdera.getParser(); jenkinsEntryXmlClient = new HttpClient<>(http, inputStreamOnly(new F>>() { public Option> f(InputStream inputStream) { long start = currentTimeMillis(); Feed feed = (Feed) parser.parse(inputStream).getRoot().complete(); long end = currentTimeMillis(); logger.info("Parsed document in " + (end - start) + "ms."); List list = new ArrayList<>(); for (Entry entry : feed.getEntries()) { try { list.add(new JenkinsEntryXml(entry.getIdElement().getText(), new DateTime(entry.getPublished().getTime()), entry.getAlternateLinkResolvedHref().toURI())); } catch (URISyntaxException ignore) { } } long end2 = currentTimeMillis(); logger.info("Converted document to JenkinsEntryXml in " + (end2 - end) + "ms."); return some(list); } })); } public static URI apiXml(URI url) { String u = url.toASCIIString(); if(u.endsWith("/")) { u = u.substring(0, u.length() - 1); } return URI.create(u + "/api/xml"); } public Option, byte[]>> fetchRss(URI url) { return jenkinsEntryXmlClient.fetch(url); } public Option> fetchJobs(URI url) { Option> d = xmlHttpClient.fetch(url); if (d.isNone()) { return none(); } Element root = d.some()._1().getRootElement(); List jobs = new ArrayList<>(); for (Element job : root.getChildren("job")) { String name = trimToNull(job.getChildText("name")); String u = trimToNull(job.getChildText("url")); String color = trimToNull(job.getChildText("color")); if (name == null || u == null || color == null) { continue; } jobs.add(new JenkinsXml.JobXml(name, u, color)); } return some(p(new JenkinsXml( Option.fromNull(root.getChildText("nodeName")), Option.fromNull(root.getChildText("nodeDescription")), Option.fromNull(root.getChildText("description")), jobs), d.some()._2())); } public Option> fetchJob(URI url) { Option> d = xmlHttpClient.fetch(url); if (d.isNone()) { return Option.none(); } Element root = d.some()._1().getRootElement(); String name = root.getName(); switch (name) { case "freeStyleProject": return some(p(JenkinsJobXml.parse(url, JenkinsJobType.FREE_STYLE, root), d.some()._2())); case "mavenModuleSet": return some(p(JenkinsJobXml.parse(url, JenkinsJobType.MAVEN_MODULE_SET, root), d.some()._2())); case "mavenModule": return some(p(JenkinsJobXml.parse(url, JenkinsJobType.MAVEN_MODULE, root), d.some()._2())); case "matrixProject": return some(p(JenkinsJobXml.parse(url, JenkinsJobType.MATRIX, root), d.some()._2())); case "matrixConfiguration": return some(p(JenkinsJobXml.parse(url, JenkinsJobType.MATRIX_CONFIGURATION, root), d.some()._2())); default: logger.warn("Unknown project type: " + name); return Option.none(); } } public Option> fetchBuild(URI url) { final Option> d = xmlHttpClient.fetch(url); if (d.isNone()) { return Option.none(); } Element root = d.some()._1().getRootElement(); String name = root.getName(); switch (name) { // I don't know the different between a "matrix build" and "matrix run" case "matrixBuild": case "matrixRun": case "mavenModuleSetBuild": case "mavenBuild": case "freeStyleBuild": return JenkinsBuildXml.parse(root).map(new F>() { public P2 f(JenkinsBuildXml x) { return p(x, d.some()._2()); } }); default: logger.warn("Unknown build type: " + name); return Option.none(); } } } class JenkinsEntryXml { public final String id; public final DateTime timestamp; public final URI url; JenkinsEntryXml(String id, DateTime timestamp, URI url) { this.id = id; this.timestamp = timestamp; this.url = url; } } class JenkinsXml { public final Option nodeName; public final Option nodeDescription; public final Option description; public final List jobs; JenkinsXml(Option nodeName, Option nodeDescription, Option description, List jobs) { this.nodeName = nodeName; this.nodeDescription = nodeDescription; this.description = description; this.jobs = jobs; } public static class JobXml { public final String name; public final String url; public final String color; JobXml(String name, String url, String color) { this.name = name; this.url = url; this.color = color; } } }