You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@continuum.apache.org by ct...@apache.org on 2011/08/26 16:32:02 UTC

svn commit: r1162127 - in /continuum/trunk: continuum-api/src/main/java/org/apache/continuum/builder/distributed/manager/ continuum-buildagent/continuum-buildagent-core/src/main/java/org/apache/continuum/buildagent/ continuum-core/src/main/java/org/apa...

Author: ctan
Date: Fri Aug 26 14:32:02 2011
New Revision: 1162127

URL: http://svn.apache.org/viewvc?rev=1162127&view=rev
Log:
[CONTINUUM-2656] cancel all current builds of project when clicking cancel button on project build

Modified:
    continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/manager/DistributedBuildManager.java
    continuum/trunk/continuum-buildagent/continuum-buildagent-core/src/main/java/org/apache/continuum/buildagent/ContinuumBuildAgentServiceImpl.java
    continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/manager/DefaultDistributedBuildManager.java
    continuum/trunk/continuum-core/src/test/java/org/apache/continuum/builder/distributed/manager/DefaultDistributedBuildManagerTest.java
    continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/CancelBuildAction.java

Modified: continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/manager/DistributedBuildManager.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/manager/DistributedBuildManager.java?rev=1162127&r1=1162126&r2=1162127&view=diff
==============================================================================
--- continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/manager/DistributedBuildManager.java (original)
+++ continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/manager/DistributedBuildManager.java Fri Aug 26 14:32:02 2011
@@ -118,4 +118,10 @@ public interface DistributedBuildManager
     List<ProjectRunSummary> getCurrentRuns();
 
     void removeCurrentRun( int projectId, int buildDefinitionId );
+
+    void cancelBuild( int projectId )
+        throws ContinuumException;
+
+    void cancelGroupBuild( int projectGroupId )
+        throws ContinuumException;
 }

Modified: continuum/trunk/continuum-buildagent/continuum-buildagent-core/src/main/java/org/apache/continuum/buildagent/ContinuumBuildAgentServiceImpl.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-buildagent/continuum-buildagent-core/src/main/java/org/apache/continuum/buildagent/ContinuumBuildAgentServiceImpl.java?rev=1162127&r1=1162126&r2=1162127&view=diff
==============================================================================
--- continuum/trunk/continuum-buildagent/continuum-buildagent-core/src/main/java/org/apache/continuum/buildagent/ContinuumBuildAgentServiceImpl.java (original)
+++ continuum/trunk/continuum-buildagent/continuum-buildagent-core/src/main/java/org/apache/continuum/buildagent/ContinuumBuildAgentServiceImpl.java Fri Aug 26 14:32:02 2011
@@ -1067,7 +1067,7 @@ public class ContinuumBuildAgentServiceI
                  return;
             }
         }
-        
+
         try
         {
             purgeManager.executeDirectoryPurge( directoryType, daysOlder, retentionCount, deleteAll );

Modified: continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/manager/DefaultDistributedBuildManager.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/manager/DefaultDistributedBuildManager.java?rev=1162127&r1=1162126&r2=1162127&view=diff
==============================================================================
--- continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/manager/DefaultDistributedBuildManager.java (original)
+++ continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/manager/DefaultDistributedBuildManager.java Fri Aug 26 14:32:02 2011
@@ -23,6 +23,7 @@ import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -37,6 +38,7 @@ import org.apache.continuum.configuratio
 import org.apache.continuum.dao.BuildDefinitionDao;
 import org.apache.continuum.dao.BuildResultDao;
 import org.apache.continuum.dao.ProjectDao;
+import org.apache.continuum.dao.ProjectScmRootDao;
 import org.apache.continuum.distributed.transport.slave.SlaveBuildAgentTransportClient;
 import org.apache.continuum.distributed.transport.slave.SlaveBuildAgentTransportService;
 import org.apache.continuum.model.project.ProjectRunSummary;
@@ -109,6 +111,11 @@ public class DefaultDistributedBuildMana
     /**
      * @plexus.requirement
      */
+    private ProjectScmRootDao projectScmRootDao;
+
+    /**
+     * @plexus.requirement
+     */
     private DistributedBuildUtil distributedBuildUtil;
 
     private PlexusContainer container;
@@ -730,6 +737,140 @@ public class DefaultDistributedBuildMana
         }
     }
 
+    public void cancelGroupBuild( int projectGroupId )
+        throws ContinuumException
+    {
+        log.debug( "Cancelling all builds of project group {}", projectGroupId );
+
+        List<ProjectRunSummary> runsToDelete = new ArrayList<ProjectRunSummary>();
+
+        synchronized( currentRuns )
+        {
+            for ( ProjectRunSummary run : currentRuns )
+            {
+                if ( run.getProjectGroupId() == projectGroupId )
+                {
+                    cancelCurrentRun( run, runsToDelete );
+                }
+            }
+
+            if ( runsToDelete.size() > 0 )
+            {
+                currentRuns.removeAll( runsToDelete );
+            }
+        }
+    }
+
+    public void cancelBuild( int projectId )
+        throws ContinuumException
+    {
+        log.debug( "Cancelling all builds of project {}", projectId );
+
+        List<ProjectRunSummary> runsToDelete = new ArrayList<ProjectRunSummary>();
+
+        synchronized( currentRuns )
+        {
+            for ( ProjectRunSummary run : currentRuns )
+            {
+                if ( run.getProjectId() == projectId )
+                {
+                    cancelCurrentRun( run, runsToDelete );
+                }
+            }
+
+            if ( runsToDelete.size() > 0 )
+            {
+                currentRuns.removeAll( runsToDelete );
+            }
+        }
+    }
+
+    private void cancelCurrentRun( ProjectRunSummary run, List<ProjectRunSummary> runsToDelete )
+        throws ContinuumException
+    {
+        int projectId = run.getProjectId();
+        int buildDefinitionId = run.getBuildDefinitionId();
+        String buildAgentUrl = run.getBuildAgentUrl();
+
+        // try to remove from any queue first
+        removeFromPrepareBuildQueue( buildAgentUrl, run.getProjectGroupId(), run.getProjectScmRootId() );
+        removeFromBuildQueue( buildAgentUrl, projectId, buildDefinitionId );
+
+        if ( isProjectCurrentlyPreparingBuild( projectId, buildDefinitionId ) )
+        {
+            log.debug( "Unable to cancel build of projectId={}, buildDefinitionId={} in build agent{}. Project is currently doing scm update." );
+            return;
+        }
+        else if ( isProjectCurrentlyBuilding( projectId, buildDefinitionId ) )
+        {
+            log.debug( "Cancel build of projectId={}, buildDefinitionId={} in build agent {}", 
+                       new Object[] { projectId, buildDefinitionId, buildAgentUrl } );
+            cancelDistributedBuild( buildAgentUrl );
+            runsToDelete.add( run );
+        }
+        else
+        {
+            try
+            {
+                ProjectScmRoot scmRoot = projectScmRootDao.getProjectScmRoot( run.getProjectScmRootId() );
+
+                if ( scmRoot != null && scmRoot.getState() == ContinuumProjectState.UPDATING )
+                {
+                    // no longer updating, but state was not updated.
+                    scmRoot.setState( ContinuumProjectState.ERROR );
+                    scmRoot.setError( "Problem encountered while returning scm update result to master by build agent '" + buildAgentUrl + "'. \n" +
+                                      "Make sure build agent is configured properly. Check the logs for more information." );
+                    projectScmRootDao.updateProjectScmRoot( scmRoot );
+
+                    log.debug( "projectId={}, buildDefinitionId={} is not updating anymore. Problem encountered while return scm update result by build agent {}. Stopping the build.",
+                               new Object[] { projectId, buildDefinitionId, buildAgentUrl } );
+                    runsToDelete.add( run );
+                }
+                else if ( scmRoot != null && scmRoot.getState() == ContinuumProjectState.ERROR )
+                {
+                    log.debug( "projectId={}, buildDefinitionId={} is not updating anymore. Problem encountered while return scm update result by build agent {}. Stopping the build.",
+                               new Object[] { projectId, buildDefinitionId, buildAgentUrl } );
+                    runsToDelete.add( run );
+                }
+                else
+                {
+                    Project project = projectDao.getProject( projectId );
+                    BuildDefinition buildDefinition = buildDefinitionDao.getBuildDefinition( buildDefinitionId );
+    
+                    // no longer building, but state was not updated
+                    BuildResult buildResult = new BuildResult();
+                    buildResult.setBuildDefinition( buildDefinition );
+                    buildResult.setBuildUrl( run.getBuildAgentUrl() );
+                    buildResult.setTrigger( run.getTrigger() );
+                    buildResult.setUsername( run.getTriggeredBy() );
+                    buildResult.setState( ContinuumProjectState.ERROR );
+                    buildResult.setSuccess( false );
+                    buildResult.setStartTime( new Date().getTime() );
+                    buildResult.setEndTime( new Date().getTime() );
+                    buildResult.setExitCode( 1 );
+                    buildResult.setError( "Problem encountered while returning build result to master by build agent '" + buildAgentUrl + "'. \n" +
+                                          "Make sure build agent is configured properly. Check the logs for more information." );
+                    buildResultDao.addBuildResult( project, buildResult );
+    
+                    project.setState( ContinuumProjectState.ERROR );
+                    project.setLatestBuildId( buildResult.getId() );
+                    projectDao.updateProject( project );
+    
+                    log.debug( "projectId={}, buildDefinitionId={} is not building anymore. Problem encountered while return build result by build agent {}. Stopping the build.",
+                               new Object[] { projectId, buildDefinitionId, buildAgentUrl } );
+    
+                    // create a build result
+                    runsToDelete.add( run );
+                }
+            }
+            catch ( Exception e )
+            {
+                log.error( "Unable to end build for projectId={}, buildDefinitionId={} : {}",
+                           new Object[] { projectId, buildDefinitionId, e.getMessage() } );
+            }
+        }
+    }
+
     public Map<String, Object> getBuildResult( int projectId )
         throws ContinuumException
     {
@@ -1918,4 +2059,13 @@ public class DefaultDistributedBuildMana
         this.container = container;
     }
 
+    public void setCurrentRuns( List<ProjectRunSummary> currentRuns )
+    {
+        this.currentRuns = currentRuns;
+    }
+
+    public void setProjectScmRootDao( ProjectScmRootDao projectScmRootDao )
+    {
+        this.projectScmRootDao = projectScmRootDao;
+    }
 }

Modified: continuum/trunk/continuum-core/src/test/java/org/apache/continuum/builder/distributed/manager/DefaultDistributedBuildManagerTest.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-core/src/test/java/org/apache/continuum/builder/distributed/manager/DefaultDistributedBuildManagerTest.java?rev=1162127&r1=1162126&r2=1162127&view=diff
==============================================================================
--- continuum/trunk/continuum-core/src/test/java/org/apache/continuum/builder/distributed/manager/DefaultDistributedBuildManagerTest.java (original)
+++ continuum/trunk/continuum-core/src/test/java/org/apache/continuum/builder/distributed/manager/DefaultDistributedBuildManagerTest.java Fri Aug 26 14:32:02 2011
@@ -34,7 +34,9 @@ import org.apache.continuum.configuratio
 import org.apache.continuum.dao.BuildDefinitionDao;
 import org.apache.continuum.dao.BuildResultDao;
 import org.apache.continuum.dao.ProjectDao;
+import org.apache.continuum.dao.ProjectScmRootDao;
 import org.apache.continuum.distributed.transport.slave.SlaveBuildAgentTransportService;
+import org.apache.continuum.model.project.ProjectRunSummary;
 import org.apache.continuum.model.project.ProjectScmRoot;
 import org.apache.continuum.taskqueue.BuildProjectTask;
 import org.apache.continuum.taskqueue.OverallDistributedBuildQueue;
@@ -42,9 +44,11 @@ import org.apache.continuum.taskqueue.Pr
 import org.apache.continuum.utils.build.BuildTrigger;
 import org.apache.maven.continuum.configuration.ConfigurationService;
 import org.apache.maven.continuum.model.project.BuildDefinition;
+import org.apache.maven.continuum.model.project.BuildResult;
 import org.apache.maven.continuum.model.project.Project;
 import org.apache.maven.continuum.model.project.ProjectGroup;
 import org.apache.maven.continuum.model.system.Profile;
+import org.apache.maven.continuum.project.ContinuumProjectState;
 import org.codehaus.plexus.spring.PlexusInSpringTestCase;
 import org.codehaus.plexus.taskqueue.Task;
 import org.codehaus.plexus.taskqueue.TaskQueue;
@@ -78,6 +82,8 @@ public class DefaultDistributedBuildMana
 
     private ProjectDao projectDao;
 
+    private ProjectScmRootDao projectScmRootDao;
+
     private ConfigurationService configurationService;
 
     private List<BuildAgentConfiguration> buildAgents;
@@ -123,6 +129,10 @@ public class DefaultDistributedBuildMana
         distributedBuildManager.setProjectDao( projectDao );
         distributedBuildManagerStub.setProjectDao( projectDao );
 
+        projectScmRootDao = context.mock( ProjectScmRootDao.class );
+        distributedBuildManager.setProjectScmRootDao( projectScmRootDao );
+        distributedBuildManagerStub.setProjectScmRootDao( projectScmRootDao );
+
         distributedBuildManagerStub.setContainer( getContainer() );
 
         configurationService = context.mock( ConfigurationService.class );
@@ -370,6 +380,117 @@ public class DefaultDistributedBuildMana
         context.assertIsSatisfied();
     }
 
+    public void testCancelBuildStuckUpdate()
+        throws Exception
+    {
+        distributedBuildManagerStub.setCurrentRuns( getCurrentRuns() );
+        
+        recordOfStuckScm();
+
+        distributedBuildManagerStub.cancelBuild( 1 );
+    }
+
+    public void testCancelBuildStuckBuild()
+        throws Exception
+    {
+        distributedBuildManagerStub.setCurrentRuns( getCurrentRuns() );
+
+        recordOfStuckBuild();
+
+        distributedBuildManagerStub.cancelBuild( 1 );
+    }
+
+    private void recordOfStuckBuild()
+        throws Exception
+    {
+        context.checking( new Expectations()
+        {
+            {
+                exactly( 4 ).of( configurationService ).getBuildAgents();
+                will( returnValue( buildAgents ) );
+
+                exactly( 2 ).of( projectScmRootDao ).getProjectScmRoot( 1 );
+                will( returnValue( getScmRoot( ContinuumProjectState.OK ) ) );
+
+                Project proj1 = getProject( 1, ContinuumProjectState.BUILDING );
+                one( projectDao ).getProject( 1 );
+                will( returnValue( proj1 ) );
+
+                one( buildDefinitionDao ).getBuildDefinition( 1 );
+                will( returnValue( new BuildDefinition() ) );
+
+                one( buildResultDao ).addBuildResult( with( any( Project.class ) ), with( any( BuildResult.class ) ) );
+                one( projectDao ).updateProject( proj1 );
+
+                one( projectDao ).getProject( 2 );
+                will( returnValue( getProject( 2, ContinuumProjectState.OK ) ) );
+            }
+        });
+    }
+
+    private void recordOfStuckScm()
+        throws Exception
+    {
+        context.checking( new Expectations()
+        {
+            {
+                exactly( 4 ).of( configurationService ).getBuildAgents();
+                will( returnValue( buildAgents ) );
+
+                ProjectScmRoot scmRootUpdating = getScmRoot( ContinuumProjectState.UPDATING );
+                one( projectScmRootDao ).getProjectScmRoot( 1 );
+                will( returnValue( scmRootUpdating ) );
+
+                one( projectScmRootDao ).updateProjectScmRoot( scmRootUpdating );
+
+                one( projectScmRootDao ).getProjectScmRoot( 1 );
+                will( returnValue( getScmRoot( ContinuumProjectState.ERROR ) ) );
+            }
+        });
+    }
+    
+    private List<ProjectRunSummary> getCurrentRuns()
+    {
+        List<ProjectRunSummary> runs = new ArrayList<ProjectRunSummary>();
+
+        ProjectRunSummary run1 = new ProjectRunSummary();
+        run1.setProjectId( 1 );
+        run1.setBuildDefinitionId( 1 );
+        run1.setProjectGroupId( 1 );
+        run1.setProjectScmRootId( 1 );
+        run1.setTrigger( 1 );
+        run1.setTriggeredBy( "user" );
+        run1.setBuildAgentUrl( "http://localhost:8181/continuum-buildagent/xmlrpc" );
+        runs.add( run1 );
+
+        ProjectRunSummary run2 = new ProjectRunSummary();
+        run2.setProjectId( 2 );
+        run2.setBuildDefinitionId( 2 );
+        run2.setProjectGroupId( 1 );
+        run2.setProjectScmRootId( 1 );
+        run2.setTrigger( 1 );
+        run2.setTriggeredBy( "user" );
+        run2.setBuildAgentUrl( "http://localhost:8181/continuum-buildagent/xmlrpc" );
+        runs.add( run2 );
+
+        return runs;
+    }
+
+    private ProjectScmRoot getScmRoot( int state )
+    {
+        ProjectScmRoot scmRoot = new ProjectScmRoot();
+        scmRoot.setState( state );
+        return scmRoot;
+    }
+
+    private Project getProject( int projectId, int state )
+    {
+        Project project = new Project();
+        project.setId( projectId );
+        project.setState( state );
+        return project;
+    }
+
     private Map<String, OverallDistributedBuildQueue> getMockOverallDistributedBuildQueues( int size )
     {
         Map<String, OverallDistributedBuildQueue> overallDistributedBuildQueues =

Modified: continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/CancelBuildAction.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/CancelBuildAction.java?rev=1162127&r1=1162126&r2=1162127&view=diff
==============================================================================
--- continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/CancelBuildAction.java (original)
+++ continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/CancelBuildAction.java Fri Aug 26 14:32:02 2011
@@ -64,9 +64,16 @@ public class CancelBuildAction
         {
             checkBuildProjectInGroupAuthorization( getProjectGroupName() );
 
-            BuildsManager buildsManager = getContinuum().getBuildsManager();
+            if ( getContinuum().getConfiguration().isDistributedBuildEnabled() )
+            {
+                getContinuum().getDistributedBuildManager().cancelBuild( projectId );
+            }
+            else
+            {
+                BuildsManager buildsManager = getContinuum().getBuildsManager();
 
-            buildsManager.cancelBuild( projectId );
+                buildsManager.cancelBuild( projectId );
+            }
 
             AuditLog event = new AuditLog( "Project id=" + projectId, AuditLogConstants.CANCEL_BUILD );
             event.setCategory( AuditLogConstants.PROJECT );
@@ -99,29 +106,44 @@ public class CancelBuildAction
             projectsId = ArrayUtils.add( projectsId, projectId );
         }
 
-        BuildsManager parallelBuildsManager = getContinuum().getBuildsManager();
-        parallelBuildsManager.removeProjectsFromBuildQueue( projectsId );
-
-        try
+        if ( getContinuum().getConfiguration().isDistributedBuildEnabled() )
         {
-            // now we must check if the current build is one of this
-            int index = ArrayUtils.indexOf( projectsId, getCurrentProjectIdBuilding() );
-            if ( index > 0 )
-            {
-                int projId = projectsId[index];
-                getContinuum().getBuildsManager().cancelBuild( projId );
-                
-                AuditLog event = new AuditLog( "Project id=" + projId, AuditLogConstants.CANCEL_BUILD );
+            for ( int i = 0; i < projectsId.length; i++ )
+            {
+                getContinuum().getDistributedBuildManager().cancelBuild( projectsId[i] );
+
+                AuditLog event = new AuditLog( "Project id=" + projectsId[i], AuditLogConstants.CANCEL_BUILD );
                 event.setCategory( AuditLogConstants.PROJECT );
                 event.setCurrentUser( getPrincipal() );
                 event.log();
             }
-
         }
-        catch ( BuildManagerException e )
+        else
         {
-            logger.error( e.getMessage() );
-            throw new ContinuumException( e.getMessage(), e );
+            BuildsManager parallelBuildsManager = getContinuum().getBuildsManager();
+            parallelBuildsManager.removeProjectsFromBuildQueue( projectsId );
+    
+            try
+            {
+                // now we must check if the current build is one of this
+                int index = ArrayUtils.indexOf( projectsId, getCurrentProjectIdBuilding() );
+                if ( index > 0 )
+                {
+                    int projId = projectsId[index];
+                    getContinuum().getBuildsManager().cancelBuild( projId );
+                    
+                    AuditLog event = new AuditLog( "Project id=" + projId, AuditLogConstants.CANCEL_BUILD );
+                    event.setCategory( AuditLogConstants.PROJECT );
+                    event.setCurrentUser( getPrincipal() );
+                    event.log();
+                }
+    
+            }
+            catch ( BuildManagerException e )
+            {
+                logger.error( e.getMessage() );
+                throw new ContinuumException( e.getMessage(), e );
+            }
         }
 
         return SUCCESS;
@@ -139,38 +161,52 @@ public class CancelBuildAction
             return REQUIRES_AUTHORIZATION;
         }
 
-        BuildsManager buildsManager = getContinuum().getBuildsManager();
+        if ( getContinuum().getConfiguration().isDistributedBuildEnabled() )
+        {
+            getContinuum().getDistributedBuildManager().cancelGroupBuild( projectGroupId );
 
-        List<ProjectScmRoot> scmRoots = getContinuum().getProjectScmRootByProjectGroup( projectGroupId );
+            AuditLog event = new AuditLog( "Project Group id=" + projectGroupId, AuditLogConstants.CANCEL_BUILD );
+            event.setCategory( AuditLogConstants.PROJECT_GROUP );
+            event.setCurrentUser( getPrincipal() );
+            event.log();
 
-        if ( scmRoots != null )
+            return SUCCESS;
+        }
+        else
         {
-            for ( ProjectScmRoot scmRoot : scmRoots )
+            BuildsManager buildsManager = getContinuum().getBuildsManager();
+
+            List<ProjectScmRoot> scmRoots = getContinuum().getProjectScmRootByProjectGroup( projectGroupId );
+
+            if ( scmRoots != null )
             {
-                try
-                {
-                    buildsManager.removeProjectGroupFromPrepareBuildQueue( projectGroupId,
-                                                                           scmRoot.getScmRootAddress() );
-                    //taskQueueManager.removeFromPrepareBuildQueue( projectGroupId, scmRoot.getScmRootAddress() );
-                }
-                catch ( BuildManagerException e )
+                for ( ProjectScmRoot scmRoot : scmRoots )
                 {
-                    throw new ContinuumException( "Unable to cancel group build", e );
+                    try
+                    {
+                        buildsManager.removeProjectGroupFromPrepareBuildQueue( projectGroupId,
+                                                                               scmRoot.getScmRootAddress() );
+                        //taskQueueManager.removeFromPrepareBuildQueue( projectGroupId, scmRoot.getScmRootAddress() );
+                    }
+                    catch ( BuildManagerException e )
+                    {
+                        throw new ContinuumException( "Unable to cancel group build", e );
+                    }
                 }
             }
+            Collection<Project> projects = getContinuum().getProjectsInGroup( projectGroupId );
+    
+            List<String> projectIds = new ArrayList<String>();
+    
+            for ( Project project : projects )
+            {
+                projectIds.add( Integer.toString( project.getId() ) );
+            }
+    
+            setSelectedProjects( projectIds );
+    
+            return cancelBuilds();
         }
-        Collection<Project> projects = getContinuum().getProjectsInGroup( projectGroupId );
-
-        List<String> projectIds = new ArrayList<String>();
-
-        for ( Project project : projects )
-        {
-            projectIds.add( Integer.toString( project.getId() ) );
-        }
-
-        setSelectedProjects( projectIds );
-
-        return cancelBuilds();
     }
 
     public void setProjectId( int projectId )