package io.trygvis.esper.testing.jenkins; import fj.*; import fj.data.*; import io.trygvis.esper.testing.*; import static io.trygvis.esper.testing.Util.*; import io.trygvis.esper.testing.jenkins.JenkinsJobXml.*; import io.trygvis.esper.testing.util.*; import static org.apache.commons.lang.StringUtils.*; import org.codehaus.httpcache4j.cache.*; import org.jdom2.*; import java.io.*; import java.net.*; import java.util.*; import java.util.List; import javax.xml.stream.*; public class JenkinsClient { private final XmlHttpClient xmlHttpClient; public JenkinsClient(HTTPCache http) { this.xmlHttpClient = new XmlHttpClient(http); } public JenkinsXml fetchJobs(URI uri) throws XMLStreamException, JDOMException, IOException { Option d = xmlHttpClient.fetch(uri); if(d.isNone()) { return new JenkinsXml(Option.none(), Option.none(), Option.none(), Collections.emptyList()); } Element root = d.some().getRootElement(); List jobs = new ArrayList<>(); for (Element job : root.getChildren("job")) { String name = trimToNull(job.getChildText("name")); String url = trimToNull(job.getChildText("url")); String color = trimToNull(job.getChildText("color")); if (name == null || url == null || color == null) { continue; } jobs.add(new JenkinsJobEntryXml(name, url, color)); } return new JenkinsXml( Option.fromNull(root.getChildText("nodeName")), Option.fromNull(root.getChildText("nodeDescription")), Option.fromNull(root.getChildText("description")), jobs); } public Option fetchJob(URI uri) throws IOException, JDOMException, XMLStreamException { Option d = xmlHttpClient.fetch(uri); if(d.isNone()) { return Option.none(); } Element root = d.some().getRootElement(); String name = root.getName(); switch (name) { case "freeStyleProject": return Option.some(JenkinsJobXml.parse(uri, JenkinsJobType.FREE_STYLE, root)); case "mavenModuleSet": return Option.some(JenkinsJobXml.parse(uri, JenkinsJobType.MAVEN, root)); default: System.out.println("Unknown project type: " + name); return Option.none(); } } } 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; } } class JenkinsJobEntryXml { public final String name; public final String url; public final String color; JenkinsJobEntryXml(String name, String url, String color) { this.name = name; this.url = url; this.color = color; } } class JenkinsJobXml { enum JenkinsJobType { MAVEN, FREE_STYLE } public final JenkinsJobType type; public final Option description; public final Option displayName; public final Option name; public final URI url; public final Option color; public final boolean buildable; public final Option lastBuild; public final Option lastCompletedBuild; public final Option lastFailedBuild; public final Option lastSuccessfulBuild; public final Option lastUnsuccessfulBuild; protected JenkinsJobXml(JenkinsJobType type, Option description, Option displayName, Option name, URI url, Option color, boolean buildable, Option lastBuild, Option lastCompletedBuild, Option lastFailedBuild, Option lastSuccessfulBuild, Option lastUnsuccessfulBuild) { this.type = type; this.description = description; this.displayName = displayName; this.name = name; this.url = url; this.color = color; this.buildable = buildable; this.lastBuild = lastBuild; this.lastCompletedBuild = lastCompletedBuild; this.lastFailedBuild = lastFailedBuild; this.lastSuccessfulBuild = lastSuccessfulBuild; this.lastUnsuccessfulBuild = lastUnsuccessfulBuild; } static class BuildXml { public final int number; public final URI url; public static F> buildXml = new F>() { public Option f(Element element) { Option number = childText(element, "number").bind(Util.parseInt); Option url = childText(element, "url").bind(Util.parseUri); if(number.isNone() || url.isNone()) { return Option.none(); } return Option.some(new BuildXml(number.some(), url.some())); } }; BuildXml(int number, URI url) { this.number = number; this.url = url; } } public static JenkinsJobXml parse(URI uri, JenkinsJobType type, Element root) { return new JenkinsJobXml(type, childText(root, "description"), childText(root, "displayName"), childText(root, "name"), childText(root, "url").bind(Util.parseUri).orSome(uri), childText(root, "color"), childText(root, "buildable").bind(Util.parseBoolean).orSome(false), child(root, "lastBuild").bind(BuildXml.buildXml), child(root, "lastCompletedBuild").bind(BuildXml.buildXml), child(root, "lastFailedBuild").bind(BuildXml.buildXml), child(root, "lastSuccessfulBuild").bind(BuildXml.buildXml), child(root, "lastUnsuccessfulBuild").bind(BuildXml.buildXml)); } }