package org.netmelody.cieye.spies.jenkins; import java.util.Collection; import java.util.List; import java.util.Map; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.message.BasicNameValuePair; import org.netmelody.cieye.core.domain.Feature; import org.netmelody.cieye.core.domain.TargetDetail; import org.netmelody.cieye.core.domain.TargetDigest; import org.netmelody.cieye.core.domain.TargetDigestGroup; import org.netmelody.cieye.core.domain.TargetId; import org.netmelody.cieye.core.logging.LogKeeper; import org.netmelody.cieye.core.logging.Logbook; import org.netmelody.cieye.core.observation.CiSpy; import org.netmelody.cieye.core.observation.Contact; import org.netmelody.cieye.core.observation.KnownOffendersDirectory; import org.netmelody.cieye.spies.jenkins.jsondomain.Job; import org.netmelody.cieye.spies.jenkins.jsondomain.View; import com.google.common.base.Predicate; import static com.google.common.collect.Iterables.find; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Maps.newHashMap; public final class JenkinsSpy implements CiSpy { private static final Logbook LOG = LogKeeper.logbookFor(JenkinsSpy.class); private final JenkinsCommunicator communicator; private final JobLaboratory laboratory; private final Map<TargetId, Job> recognisedJobs = newHashMap(); public JenkinsSpy(String endpoint, KnownOffendersDirectory detective, Contact contact) { this.communicator = new JenkinsCommunicator(endpoint, contact); this.laboratory = new JobLaboratory(communicator, detective); } @Override public TargetDigestGroup targetsConstituting(Feature feature) { final Collection<Job> jobs = jobsFor(feature); final List<TargetDigest> digests = newArrayList(); for (Job job : jobs) { final TargetDigest targetDigest = new TargetDigest(job.url, job.url, job.name, job.status()); digests.add(targetDigest); recognisedJobs.put(targetDigest.id(), job); } return new TargetDigestGroup(digests); } @Override public TargetDetail statusOf(final TargetId target) { Job job = recognisedJobs.get(target); if (null == job) { return null; } return laboratory.analyseJob(job); } @Override public boolean takeNoteOf(TargetId target, String note) { if (!recognisedJobs.containsKey(target)) { return false; } final Job job = this.recognisedJobs.get(target); final String buildUrl = this.laboratory.lastBadBuildUrlFor(job); if (buildUrl.isEmpty()) { return true; } communicator.doJenkinsPost(buildUrl + "submitDescription?" + URLEncodedUtils.format(newArrayList(new BasicNameValuePair("description", note)), "UTF-8")); return true; } private Collection<Job> jobsFor(final Feature feature) { if (!communicator.canSpeakFor(feature)) { return newArrayList(); } final String name = feature.name().isEmpty() ? "All" : feature.name(); final View viewDigest = find(communicator.views(), withName(name), null); if (null == viewDigest) { LOG.error("No view named <" + name + "> found"); return newArrayList(); } return communicator.jobsFor(viewDigest); } private Predicate<View> withName(final String featureName) { return new Predicate<View>() { @Override public boolean apply(View viewDigest) { return viewDigest.name.trim().equals(featureName.trim()); } }; } }