/**
*
* 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.Date;
import java.util.List;
import fr.norad.visuwall.providers.common.Maven;
import fr.norad.visuwall.providers.common.MavenIdNotFoundException;
import fr.norad.visuwall.providers.hudson.domain.HudsonBuild;
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 org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
public class Hudson {
private static final Logger LOG = LoggerFactory.getLogger(Hudson.class);
@VisibleForTesting
HudsonFinder hudsonFinder;
@VisibleForTesting
HudsonUrlBuilder hudsonUrlBuilder;
@VisibleForTesting
Maven maven = new Maven();
private String url;
public Hudson(String hudsonUrl) {
this.url = hudsonUrl;
hudsonUrlBuilder = new HudsonUrlBuilder(hudsonUrl);
hudsonFinder = new HudsonFinder(hudsonUrlBuilder);
if (LOG.isInfoEnabled()) {
LOG.info("Initialize hudson with url " + hudsonUrl);
}
}
public Hudson(String hudsonUrl, String login, String password) {
this.url = hudsonUrl;
hudsonUrlBuilder = new HudsonUrlBuilder(hudsonUrl);
hudsonFinder = new HudsonFinder(hudsonUrlBuilder, login, password);
}
/**
* @return List of all available projects on Hudson
*/
public List<HudsonJob> findAllProjects() {
List<HudsonJob> projects = new ArrayList<HudsonJob>();
for (String jobName : hudsonFinder.findJobNames()) {
try {
HudsonJob hudsonProject = findJob(jobName);
projects.add(hudsonProject);
} catch (HudsonJobNotFoundException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Can't add project with name [" + jobName + "]. cause:" + e.getMessage());
}
}
}
return projects;
}
public List<String> findAllProjectNames() {
List<String> projectNames = new ArrayList<String>();
for (String jobName : hudsonFinder.findJobNames()) {
projectNames.add(jobName);
}
return projectNames;
}
/**
* @param jobName
* @param buildNumber
* @return HudsonBuild found in Hudson with its project name and build number
* @throws HudsonBuildNotFoundException
* @throws HudsonJobNotFoundException
*/
public HudsonBuild findBuild(String jobName, int buildNumber) throws HudsonBuildNotFoundException,
HudsonJobNotFoundException {
checkJobName(jobName);
return hudsonFinder.find(jobName, buildNumber);
}
/**
* @param jobName
* @return HudsonJob found with its name
* @throws HudsonJobNotFoundException
*/
public HudsonJob findJob(String jobName) throws HudsonJobNotFoundException {
checkJobName(jobName);
return hudsonFinder.findJob(jobName);
}
/**
* Return the description of the project identify by its projectName
*
* @param string
* @return
* @throws HudsonJobNotFoundException
*/
public String getDescription(String jobName) throws HudsonJobNotFoundException {
checkJobName(jobName);
return hudsonFinder.getDescription(jobName);
}
/**
* @param jobName
* @return Date which we think the project will finish to build
* @throws HudsonJobNotFoundException
*/
public Date getEstimatedFinishTime(String jobName) throws HudsonJobNotFoundException {
checkJobName(jobName);
try {
HudsonJob hudsonJob = hudsonFinder.findJob(jobName);
HudsonBuild currentBuild = hudsonFinder.getCurrentBuild(jobName);
if (currentBuild == null) {
if (LOG.isDebugEnabled()) {
LOG.debug(jobName + " has no current build");
}
return new Date();
}
long averageBuildDurationTime = computeBuildDurationTime(hudsonJob);
Date startTime = currentBuild.getStartTime();
if (startTime == null) {
if (LOG.isDebugEnabled()) {
LOG.debug(currentBuild + " has no start time");
}
return new Date();
}
long time = startTime.getTime();
DateTime dateTime = new DateTime(time);
DateTime estimatedFinishTime = dateTime.plus(averageBuildDurationTime);
return estimatedFinishTime.toDate();
} catch (HudsonBuildNotFoundException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Can't find estimated finish time of job: " + jobName, e);
}
}
return new Date();
}
public int getLastBuildNumber(String projectName) throws HudsonJobNotFoundException, HudsonBuildNotFoundException {
checkJobName(projectName);
return hudsonFinder.getLastBuildNumber(projectName);
}
public List<String> findJobNames() {
List<String> jobNames = hudsonFinder.findJobNames();
return jobNames;
}
public List<String> findViews() {
return hudsonFinder.findViews();
}
public List<String> findJobNameByView(String viewName) throws HudsonViewNotFoundException {
Preconditions.checkNotNull(viewName, "viewName is mandatory");
List<String> jobNames = hudsonFinder.findJobNamesByView(viewName);
return jobNames;
}
public String findMavenId(String jobName) throws MavenIdNotFoundException {
String pomUrl = hudsonUrlBuilder.getPomUrl(jobName);
return maven.findMavenIdFrom(pomUrl);
}
public List<Integer> getBuildNumbers(String jobName) throws HudsonJobNotFoundException {
checkJobName(jobName);
try {
return hudsonFinder.getBuildNumbers(jobName);
} catch (HudsonJobNotFoundException e) {
throw new HudsonJobNotFoundException("Can't find build numbers of jobName '" + jobName + "'", e);
}
}
private long computeBuildDurationTime(HudsonJob hudsonJob) throws HudsonJobNotFoundException {
long averageTime;
if (isNeverSuccessful(hudsonJob.getName())) {
averageTime = maxDuration(hudsonJob);
} else {
averageTime = computeAverageBuildDuration(hudsonJob);
}
if (LOG.isDebugEnabled()) {
LOG.debug("Average build time of " + hudsonJob.getName() + " is " + averageTime + " ms");
}
return averageTime;
}
private long maxDuration(HudsonJob hudsonProject) throws HudsonJobNotFoundException {
long max = 0;
List<Integer> buildNumbers = hudsonFinder.getBuildNumbers(hudsonProject.getName());
for (int buildNumber : buildNumbers) {
try {
HudsonBuild build = findBuild(hudsonProject.getName(), buildNumber);
max = Math.max(max, build.getDuration());
} catch (HudsonBuildNotFoundException e) {
if (LOG.isDebugEnabled()) {
LOG.debug(e.getMessage());
}
}
}
return max;
}
private boolean isNeverSuccessful(String jobName) throws HudsonJobNotFoundException {
List<Integer> buildNumbers = hudsonFinder.getBuildNumbers(jobName);
for (int buildNumber : buildNumbers) {
try {
HudsonBuild build = findBuild(jobName, buildNumber);
if (build.isSuccessful()) {
return false;
}
} catch (HudsonBuildNotFoundException e) {
if (LOG.isDebugEnabled()) {
LOG.debug(e.getMessage());
}
}
}
return true;
}
private long computeAverageBuildDuration(HudsonJob hudsonJob) throws HudsonJobNotFoundException {
String projectName = hudsonJob.getName();
float sumBuildDurationTime = 0;
List<Integer> buildNumbers = hudsonFinder.getBuildNumbers(projectName);
for (int buildNumber : buildNumbers) {
try {
HudsonBuild build = findBuild(projectName, buildNumber);
if (build.isSuccessful()) {
sumBuildDurationTime += build.getDuration();
}
} catch (HudsonBuildNotFoundException e) {
if (LOG.isDebugEnabled()) {
LOG.debug(e.getMessage());
}
}
}
return (long) (sumBuildDurationTime / buildNumbers.size());
}
private void checkJobName(String jobName) {
Preconditions.checkNotNull(jobName, "jobName is mandatory");
}
public HudsonTestResult findUnitTestResult(String jobName, int lastBuildNumber) throws HudsonJobNotFoundException,
HudsonBuildNotFoundException {
return hudsonFinder.findUnitTestResult(jobName, lastBuildNumber);
}
public HudsonTestResult findIntegrationTestResult(String jobName, int lastBuildNumber)
throws HudsonJobNotFoundException, HudsonBuildNotFoundException {
return hudsonFinder.findIntegrationTestResult(jobName, lastBuildNumber);
}
public String getUrl() {
return url;
}
}