/**
*
* Copyright (C) norad.fr
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package fr.norad.visuwall.providers.hudson;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import fr.norad.visuwall.providers.common.GenericSoftwareClient;
import fr.norad.visuwall.providers.common.ResourceNotFoundException;
import fr.norad.visuwall.providers.hudson.domain.HudsonBuild;
import fr.norad.visuwall.providers.hudson.domain.HudsonCommiter;
import fr.norad.visuwall.providers.hudson.domain.HudsonJob;
import fr.norad.visuwall.providers.hudson.domain.HudsonTestResult;
import fr.norad.visuwall.providers.hudson.exception.HudsonBuildNotFoundException;
import fr.norad.visuwall.providers.hudson.exception.HudsonJobNotFoundException;
import fr.norad.visuwall.providers.hudson.exception.HudsonViewNotFoundException;
import fr.norad.visuwall.providers.hudson.helper.HudsonXmlHelper;
import fr.norad.visuwall.providers.hudson.resource.Build;
import fr.norad.visuwall.providers.hudson.resource.Color;
import fr.norad.visuwall.providers.hudson.resource.ExternalJob;
import fr.norad.visuwall.providers.hudson.resource.FreeStyleBuild;
import fr.norad.visuwall.providers.hudson.resource.FreeStyleProject;
import fr.norad.visuwall.providers.hudson.resource.Hudson;
import fr.norad.visuwall.providers.hudson.resource.HudsonUser;
import fr.norad.visuwall.providers.hudson.resource.Job;
import fr.norad.visuwall.providers.hudson.resource.ListView;
import fr.norad.visuwall.providers.hudson.resource.MatrixProject;
import fr.norad.visuwall.providers.hudson.resource.MavenModuleSet;
import fr.norad.visuwall.providers.hudson.resource.MavenModuleSetBuild;
import fr.norad.visuwall.providers.hudson.resource.Project;
import fr.norad.visuwall.providers.hudson.resource.SurefireAggregatedReport;
import fr.norad.visuwall.providers.hudson.resource.View;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
class HudsonFinder {
private static final Logger LOG = LoggerFactory.getLogger(HudsonFinder.class);
private HudsonUrlBuilder hudsonUrlBuilder;
@VisibleForTesting
GenericSoftwareClient client;
@VisibleForTesting
HudsonBuildBuilder hudsonBuildBuilder;
@VisibleForTesting
TestResultBuilder testResultBuilder;
HudsonFinder(HudsonUrlBuilder hudsonUrlBuilder) {
this.client = new GenericSoftwareClient();
this.hudsonUrlBuilder = hudsonUrlBuilder;
this.hudsonBuildBuilder = new HudsonBuildBuilder();
this.testResultBuilder = new TestResultBuilder();
}
public HudsonFinder(HudsonUrlBuilder hudsonUrlBuilder, String login, String password) {
this.client = new GenericSoftwareClient(login, password);
this.hudsonUrlBuilder = hudsonUrlBuilder;
this.hudsonBuildBuilder = new HudsonBuildBuilder();
this.testResultBuilder = new TestResultBuilder();
}
HudsonBuild find(String jobName, int buildNumber) throws HudsonBuildNotFoundException {
Build setBuild = findBuildByJobNameAndBuildNumber(jobName, buildNumber);
String[] commiterNames = HudsonXmlHelper.getCommiterNames(setBuild);
Set<HudsonCommiter> commiters = findCommiters(commiterNames);
HudsonBuild hudsonBuild = hudsonBuildBuilder.createHudsonBuild(setBuild, commiters);
return hudsonBuild;
}
SurefireAggregatedReport findSurefireReport(String jobName, Build build) {
String testResultUrl = hudsonUrlBuilder.getTestResultUrl(jobName, build.getNumber());
try {
return client.resource(testResultUrl, SurefireAggregatedReport.class);
} catch (ResourceNotFoundException e) {
return null;
}
}
@VisibleForTesting
Build findBuildByJobNameAndBuildNumber(String jobName, int buildNumber) throws HudsonBuildNotFoundException {
String buildUrl = hudsonUrlBuilder.getBuildUrl(jobName, buildNumber);
if (LOG.isDebugEnabled()) {
LOG.debug(buildUrl);
}
Build setBuild = null;
try {
setBuild = client.resource(buildUrl, MavenModuleSetBuild.class);
} catch (ResourceNotFoundException e) {
try {
setBuild = client.resource(buildUrl, FreeStyleBuild.class);
} catch (ResourceNotFoundException e1) {
throw new HudsonBuildNotFoundException("Build #" + buildNumber + " not found for job " + jobName, e1);
}
}
if (setBuild == null) {
throw new HudsonBuildNotFoundException("Build #" + buildNumber + " not found for job " + jobName);
}
return setBuild;
}
List<String> findJobNames() {
List<String> jobNames = new ArrayList<String>();
String projectsUrl = hudsonUrlBuilder.getAllProjectsUrl();
try {
Hudson hudson = client.resource(projectsUrl, Hudson.class);
for (Job job : hudson.getJobs()) {
String name = job.getName();
jobNames.add(name);
}
} catch (ResourceNotFoundException e) {
if (LOG.isDebugEnabled()) {
LOG.debug(e.getMessage(), e);
}
}
return jobNames;
}
List<String> findJobNamesByView(String viewName) throws HudsonViewNotFoundException {
try {
List<String> jobNames = new ArrayList<String>();
String viewUrl = hudsonUrlBuilder.getViewUrl(viewName);
ListView view = client.resource(viewUrl, ListView.class);
for (Job job : view.getJobs()) {
jobNames.add(job.getName());
}
return jobNames;
} catch (ResourceNotFoundException e) {
throw new HudsonViewNotFoundException(e.getMessage(), e);
}
}
List<String> findViews() {
List<String> views = new ArrayList<String>();
try {
String projectsUrl = hudsonUrlBuilder.getAllProjectsUrl();
Hudson hudson = client.resource(projectsUrl, Hudson.class);
for (View view : hudson.getViews()) {
views.add(view.getName());
}
} catch (ResourceNotFoundException e) {
if (LOG.isDebugEnabled()) {
LOG.debug(e.getMessage(), e);
}
}
return views;
}
String getDescription(String jobName) throws HudsonJobNotFoundException {
Project moduleSet = findJobByName(jobName);
return moduleSet.getDescription();
}
HudsonJob findJob(String projectName) throws HudsonJobNotFoundException {
Project moduleSet = findJobByName(projectName);
return createHudsonProjectFrom(moduleSet);
}
int getLastBuildNumber(String projectName) throws HudsonJobNotFoundException, HudsonBuildNotFoundException {
Project job = findJobByName(projectName);
Build lastBuild = job.getLastBuild();
if (lastBuild == null) {
throw new HudsonBuildNotFoundException("Project " + projectName + " has no last build");
}
return lastBuild.getNumber();
}
Set<HudsonCommiter> findCommiters(String[] commiterNames) {
Set<HudsonCommiter> commiters = new TreeSet<HudsonCommiter>();
for (String commiterName : commiterNames) {
try {
String url = hudsonUrlBuilder.getUserUrl(commiterName);
HudsonUser hudsonUser = client.resource(url, HudsonUser.class);
HudsonCommiter commiter = new HudsonCommiter(hudsonUser.getId());
commiter.setName(commiterName);
commiter.setEmail(hudsonUser.getEmail());
commiters.add(commiter);
} catch (ResourceNotFoundException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Can't find user " + commiterName, e);
}
}
}
return commiters;
}
String getStateOf(String jobName, int buildNumber) throws HudsonBuildNotFoundException {
Build build = findBuildByJobNameAndBuildNumber(jobName, buildNumber);
return build.getResult();
}
private Project findJobByName(String jobName) throws HudsonJobNotFoundException {
String jobUrl = hudsonUrlBuilder.getJobUrl(jobName);
Project project = findProjectByName(jobName, jobUrl);
if (project == null) {
throw new HudsonJobNotFoundException("Can't find job with name '" + jobName + "'");
}
return project;
}
private Project findProjectByName(String jobName, String jobUrl) throws HudsonJobNotFoundException {
Project project = null;
try {
project = client.resource(jobUrl, MavenModuleSet.class);
} catch (ResourceNotFoundException e) {
try {
project = client.resource(jobUrl, FreeStyleProject.class);
} catch (ResourceNotFoundException e1) {
try {
project = client.resource(jobUrl, MatrixProject.class);
} catch (ResourceNotFoundException e2) {
try {
project = client.resource(jobUrl, ExternalJob.class);
} catch (ResourceNotFoundException e3) {
throw new HudsonJobNotFoundException("Can't find job with name '" + jobName + "'", e3);
}
}
}
}
return project;
}
private HudsonJob createHudsonProjectFrom(Project project) {
String name = project.getName();
String description = project.getDescription();
String color = project.getColor();
boolean disabled = Color.DISABLED.value().equals(color) || Color.GREY.value().equals(color);
HudsonJob hudsonJob = new HudsonJob();
hudsonJob.setName(name);
hudsonJob.setDescription(description);
hudsonJob.setDisabled(disabled);
return hudsonJob;
}
List<Integer> getBuildNumbers(String jobName) throws HudsonJobNotFoundException {
Project modelJob = findJobByName(jobName);
List<Build> builds = modelJob.getBuilds();
List<Integer> buildNumbers = new ArrayList<Integer>();
for (Build build : builds) {
int buildNumber = build.getNumber();
buildNumbers.add(buildNumber);
}
Collections.sort(buildNumbers);
return buildNumbers;
}
HudsonBuild getCompletedBuild(String jobName) throws HudsonBuildNotFoundException, HudsonJobNotFoundException {
Project modelJob = findJobByName(jobName);
boolean isBuilding = getIsBuilding(modelJob);
Build lastCompletedHudsonRun;
if (isBuilding) {
lastCompletedHudsonRun = modelJob.getLastCompletedBuild();
} else {
lastCompletedHudsonRun = modelJob.getLastBuild();
}
int lastCompleteBuildNumber = -1;
if (lastCompletedHudsonRun != null) {
lastCompleteBuildNumber = lastCompletedHudsonRun.getNumber();
}
HudsonBuild lastCompletedHudsonBuild = null;
if (lastCompleteBuildNumber != -1) {
lastCompletedHudsonBuild = find(jobName, lastCompleteBuildNumber);
}
return lastCompletedHudsonBuild;
}
HudsonBuild getCurrentBuild(String jobName) throws HudsonJobNotFoundException, HudsonBuildNotFoundException {
Project modelJob = findJobByName(jobName);
Build currentHudsonRun = modelJob.getLastBuild();
int currentBuildNumber = -1;
if (currentHudsonRun != null) {
currentBuildNumber = currentHudsonRun.getNumber();
}
HudsonBuild currentHudsonBuild = null;
if (currentBuildNumber != -1) {
currentHudsonBuild = find(jobName, currentBuildNumber);
}
return currentHudsonBuild;
}
private boolean getIsBuilding(Project modelJob) {
String color = modelJob.getColor();
return color.endsWith("_anime");
}
public HudsonTestResult findUnitTestResult(String jobName, int buildNumber) throws HudsonBuildNotFoundException {
Build build = findBuildByJobNameAndBuildNumber(jobName, buildNumber);
SurefireAggregatedReport surefireReport = findSurefireReport(jobName, build);
if (surefireReport != null) {
return testResultBuilder.buildUnitTestResult(surefireReport);
}
return new HudsonTestResult();
}
public HudsonTestResult findIntegrationTestResult(String jobName, int buildNumber)
throws HudsonBuildNotFoundException {
Build build = findBuildByJobNameAndBuildNumber(jobName, buildNumber);
SurefireAggregatedReport surefireReport = findSurefireReport(jobName, build);
if (surefireReport != null) {
return testResultBuilder.buildIntegrationTestResult(surefireReport);
}
return new HudsonTestResult();
}
}