/**
*
* 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.core.business.service;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import fr.norad.visuwall.api.domain.ProjectKey;
import fr.norad.visuwall.api.domain.SoftwareProjectId;
import fr.norad.visuwall.api.domain.TestResult;
import fr.norad.visuwall.api.domain.quality.QualityResult;
import fr.norad.visuwall.api.exception.BuildNotFoundException;
import fr.norad.visuwall.api.exception.MavenIdNotFoundException;
import fr.norad.visuwall.api.exception.ProjectNotFoundException;
import fr.norad.visuwall.api.plugin.capability.BasicCapability;
import fr.norad.visuwall.api.plugin.capability.BuildCapability;
import fr.norad.visuwall.api.plugin.capability.MetricCapability;
import fr.norad.visuwall.api.plugin.capability.TestCapability;
import fr.norad.visuwall.core.business.domain.CapabilitiesResult;
import fr.norad.visuwall.core.business.domain.Project;
import fr.norad.visuwall.core.business.process.capabilities.BuildCapabilityProcess;
import fr.norad.visuwall.core.business.process.capabilities.MetricCapabilityProcess;
import fr.norad.visuwall.core.persistence.entity.SoftwareAccess;
import fr.norad.visuwall.core.persistence.entity.Wall;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.stereotype.Service;
import com.google.common.base.Preconditions;
@Service
public class ProjectService {
private static final Logger LOG = LoggerFactory.getLogger(ProjectService.class);
@Autowired
TaskScheduler taskScheduler;
@Autowired
BuildCapabilityProcess buildProcess;
@Autowired
MetricCapabilityProcess metricCapabilityProcess;
public Runnable getProjectCreationRunner(final Wall wallWhereToAdd, final SoftwareAccess buildSoftwareAccess,
final SoftwareProjectId projectId) {
Preconditions.checkState(buildSoftwareAccess.getConnection() instanceof BuildCapability,
"softwareAccess needs to point to BuildCapability plugin connection");
return new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
LOG.debug("Running project creation task for project id " + projectId + " on software "
+ buildSoftwareAccess + " in wall " + wallWhereToAdd);
BuildCapability buildConnection = (BuildCapability) buildSoftwareAccess.getConnection();
Project connectedProject = new Project(projectId, buildConnection);
Runnable updateProjectRunner = getUpdateProjectRunner(wallWhereToAdd, connectedProject);
LOG.debug("Launching first project updater for " + connectedProject);
updateProjectRunner.run();
ScheduledFuture<Object> updateProjectTask = taskScheduler.scheduleAtFixedRate(updateProjectRunner,
buildSoftwareAccess.getProjectStatusDelaySecond() * 1000);
connectedProject.setUpdateProjectTask(updateProjectTask);
LOG.debug("Adding project " + connectedProject + " to wall " + wallWhereToAdd);
wallWhereToAdd.getProjects().add(connectedProject);
}
};
}
Runnable getUpdateProjectRunner(final Wall wall, final Project project) {
Preconditions.checkNotNull(wall, "wall is a mandatory parameter");
Preconditions.checkNotNull(project, "project is a mandatory parameter");
return new Runnable() {
private boolean neverRun = true;
@Override
public void run() {
LOG.debug("Running Project Updater task for project " + project);
try {
String[] buildsToUpdate = buildProcess.updateStatusAndReturnBuildsToUpdate(project);
if (neverRun || buildsToUpdate.length != 0) {
try {
if (!neverRun) {
LOG.debug("Project build change and needs a update from software " + project);
}
SoftwareProjectId projectId = project.getBuildProjectId();
// name
try {
String name = project.getBuildConnection().getName(projectId);
project.setName(name);
} catch (Exception e) {
LOG.warn("Can not found project name for project " + project, e);
}
if (neverRun) {
try {
ProjectKey projectKey = new ProjectKey();
project.setProjectKey(projectKey);
String mavenId = project.getBuildConnection().getMavenId(
project.getBuildProjectId());
projectKey.setMavenId(mavenId);
projectKey.setName(project.getName());
} catch (MavenIdNotFoundException e) {
LOG.debug("Maven project id not found for project" + project, e);
}
}
// description
try {
String description = project.getBuildConnection().getDescription(projectId);
project.setDescription(description);
} catch (Exception e) {
LOG.warn("Can not found description for project " + project, e);
}
// disabled
boolean projectDisabled = project.getBuildConnection().isProjectDisabled(projectId);
project.setDisabled(projectDisabled);
try {
List<String> buildIds = project.getBuildConnection().getBuildIds(projectId);
project.setBuildId(buildIds);
buildProcess.updateLastNotBuildingId(project);
buildProcess.updatePreviousCompletedBuild(project);
} catch (Exception e) {
LOG.warn("Can not update previous completed build for project " + project, e);
}
for (String buildId : buildsToUpdate) {
buildProcess.updateBuild(project, buildId);
}
// TODO be sure to not remove a project cause of a capability ProjectNotFoundException
} finally {
project.setLastUpdate(new Date());
}
}
updateCapabilities(project);
} catch (ProjectNotFoundException e) {
LOG.info("Project not found by build Software, and will be removed");
LOG.debug("Project not found cause", e);
wall.getProjects().deleteAndCleanProject(project.getId());
} catch (BuildNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
neverRun = false;
}
}
};
}
private void updateCapabilities(final Project project) throws BuildNotFoundException {
// update capabilities
if (project.getLastNotBuildingId() != null) {
for (SoftwareProjectId softwareProjectId : project.getCapabilities().keySet()) {
//TODO we are currently able to manage last build only
if (!project.getLastBuild().getCapabilitiesResults().containsKey(softwareProjectId)) {
try {
BasicCapability capability = project.getCapabilities().get(softwareProjectId);
LOG.info("new Software {} for project {}", capability, project);
CapabilitiesResult capabilitiesResult = new CapabilitiesResult();
project.getLastBuild().getCapabilitiesResults().put(softwareProjectId, capabilitiesResult);
if (capability instanceof MetricCapability) {
if (project.getLastNotBuildingId() != null) {
QualityResult qualityResult = ((MetricCapability) capability).analyzeQuality(
softwareProjectId, MetricCapabilityProcess.metrics);
capabilitiesResult.setQualityResult(qualityResult);
}
}
if (capability instanceof TestCapability) {
if (project.getLastNotBuildingId() != null) {
TestResult testResult = ((TestCapability) capability)
.analyzeUnitTests(softwareProjectId);
capabilitiesResult.setUnitTestResult(testResult);
}
if (project.getLastNotBuildingId() != null) {
TestResult testResult = ((TestCapability) capability)
.analyzeIntegrationTests(softwareProjectId);
capabilitiesResult.setIntegrationTestResult(testResult);
}
}
} finally {
project.setLastUpdate(new Date());
}
}
}
}
}
}