View Javadoc

1   package org.apache.continuum.builder.distributed.work;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.continuum.builder.distributed.manager.DistributedBuildManager;
23  import org.apache.continuum.dao.BuildDefinitionDao;
24  import org.apache.continuum.dao.BuildResultDao;
25  import org.apache.continuum.dao.ProjectDao;
26  import org.apache.continuum.dao.ProjectScmRootDao;
27  import org.apache.continuum.model.project.ProjectRunSummary;
28  import org.apache.continuum.model.project.ProjectScmRoot;
29  import org.apache.maven.continuum.configuration.ConfigurationService;
30  import org.apache.maven.continuum.model.project.BuildDefinition;
31  import org.apache.maven.continuum.model.project.BuildResult;
32  import org.apache.maven.continuum.model.project.Project;
33  import org.apache.maven.continuum.project.ContinuumProjectState;
34  import org.slf4j.Logger;
35  import org.slf4j.LoggerFactory;
36  
37  import java.util.ArrayList;
38  import java.util.Date;
39  import java.util.List;
40  
41  /**
42   * @plexus.component role="org.apache.continuum.builder.distributed.work.ContinuumWorker"
43   */
44  public class DefaultContinuumWorker
45      implements ContinuumWorker
46  {
47      private static final Logger log = LoggerFactory.getLogger( DefaultContinuumWorker.class );
48  
49      /**
50       * @plexus.requirement
51       */
52      private ProjectDao projectDao;
53  
54      /**
55       * @plexus.requirement
56       */
57      private ProjectScmRootDao projectScmRootDao;
58  
59      /**
60       * @plexus.requirement
61       */
62      private BuildDefinitionDao buildDefinitionDao;
63  
64      /**
65       * @plexus.requirement
66       */
67      private BuildResultDao buildResultDao;
68  
69      /**
70       * @plexus.requirement
71       */
72      private DistributedBuildManager distributedBuildManager;
73  
74      /**
75       * @plexus.requirement
76       */
77      private ConfigurationService configurationService;
78  
79      public synchronized void work()
80      {
81          if ( !configurationService.isDistributedBuildEnabled() )
82          {
83              return;
84          }
85  
86          log.debug( "Start continuum worker..." );
87  
88          List<ProjectRunSummary> currentRuns = new ArrayList<ProjectRunSummary>(
89              distributedBuildManager.getCurrentRuns() );
90          List<ProjectRunSummary> runsToDelete = new ArrayList<ProjectRunSummary>();
91  
92          synchronized ( currentRuns )
93          {
94              for ( ProjectRunSummary currentRun : currentRuns )
95              {
96                  try
97                  {
98                      // check for scm update
99                      ProjectScmRoot scmRoot = projectScmRootDao.getProjectScmRoot( currentRun.getProjectScmRootId() );
100 
101                     if ( scmRoot != null && scmRoot.getState() == ContinuumProjectState.UPDATING )
102                     {
103                         // check if it's still updating
104                         if ( !distributedBuildManager.isProjectCurrentlyPreparingBuild( currentRun.getProjectId(),
105                                                                                         currentRun.getBuildDefinitionId() ) )
106                         {
107                             // no longer updating, but state was not updated.
108                             scmRoot.setState( ContinuumProjectState.ERROR );
109                             scmRoot.setError(
110                                 "Problem encountered while returning scm update result to master by build agent '" +
111                                     currentRun.getBuildAgentUrl() + "'. \n" +
112                                     "Make sure build agent is configured properly. Check the logs for more information." );
113                             projectScmRootDao.updateProjectScmRoot( scmRoot );
114 
115                             log.debug(
116                                 "projectId={}, buildDefinitionId={} is not updating anymore. Problem encountered while return scm update result by build agent {}. Stopping the build.",
117                                 new Object[]{currentRun.getProjectId(), currentRun.getBuildDefinitionId(),
118                                     currentRun.getBuildAgentUrl()} );
119                             runsToDelete.add( currentRun );
120                         }
121                     }
122                     else if ( scmRoot != null && scmRoot.getState() == ContinuumProjectState.ERROR )
123                     {
124                         log.debug(
125                             "projectId={}, buildDefinitionId={} is not updating anymore. Problem encountered while return scm update result by build agent {}. Stopping the build.",
126                             new Object[]{currentRun.getProjectId(), currentRun.getBuildDefinitionId(),
127                                 currentRun.getBuildAgentUrl()} );
128                         runsToDelete.add( currentRun );
129                     }
130                     else
131                     {
132                         Project project = projectDao.getProject( currentRun.getProjectId() );
133 
134                         if ( project != null && project.getState() == ContinuumProjectState.BUILDING )
135                         {
136                             // check if it's still building
137                             if ( !distributedBuildManager.isProjectCurrentlyBuilding( currentRun.getProjectId(),
138                                                                                       currentRun.getBuildDefinitionId() ) )
139                             {
140                                 BuildDefinition buildDefinition = buildDefinitionDao.getBuildDefinition(
141                                     currentRun.getBuildDefinitionId() );
142 
143                                 // no longer building, but state was not updated
144                                 BuildResult buildResult = new BuildResult();
145                                 buildResult.setBuildDefinition( buildDefinition );
146                                 buildResult.setBuildUrl( currentRun.getBuildAgentUrl() );
147                                 buildResult.setTrigger( currentRun.getTrigger() );
148                                 buildResult.setUsername( currentRun.getTriggeredBy() );
149                                 buildResult.setState( ContinuumProjectState.ERROR );
150                                 buildResult.setSuccess( false );
151                                 buildResult.setStartTime( new Date().getTime() );
152                                 buildResult.setEndTime( new Date().getTime() );
153                                 buildResult.setExitCode( 1 );
154                                 buildResult.setError(
155                                     "Problem encountered while returning build result to master by build agent '" +
156                                         currentRun.getBuildAgentUrl() + "'. \n" +
157                                         "Make sure build agent is configured properly. Check the logs for more information." );
158                                 buildResultDao.addBuildResult( project, buildResult );
159 
160                                 project.setState( ContinuumProjectState.ERROR );
161                                 project.setLatestBuildId( buildResult.getId() );
162                                 projectDao.updateProject( project );
163 
164                                 log.debug(
165                                     "projectId={}, buildDefinitionId={} is not building anymore. Problem encountered while return build result by build agent {}. Stopping the build.",
166                                     new Object[]{currentRun.getProjectId(), currentRun.getBuildDefinitionId(),
167                                         currentRun.getBuildAgentUrl()} );
168 
169                                 // create a build result
170                                 runsToDelete.add( currentRun );
171                             }
172                         }
173                     }
174                 }
175                 catch ( Exception e )
176                 {
177                     log.error(
178                         "Unable to check if projectId={}, buildDefinitionId={} is still updating or building: {}",
179                         new Object[]{currentRun.getProjectId(), currentRun.getBuildDefinitionId(), e.getMessage()} );
180                 }
181             }
182 
183             if ( runsToDelete.size() > 0 )
184             {
185                 distributedBuildManager.getCurrentRuns().removeAll( runsToDelete );
186             }
187         }
188 
189         log.debug( "End continuum worker..." );
190     }
191 
192     // for testing
193     public void setProjectDao( ProjectDao projectDao )
194     {
195         this.projectDao = projectDao;
196     }
197 
198     public void setProjectScmRootDao( ProjectScmRootDao projectScmRootDao )
199     {
200         this.projectScmRootDao = projectScmRootDao;
201     }
202 
203     public void setBuildDefinitionDao( BuildDefinitionDao buildDefinitionDao )
204     {
205         this.buildDefinitionDao = buildDefinitionDao;
206     }
207 
208     public void setBuildResultDao( BuildResultDao buildResultDao )
209     {
210         this.buildResultDao = buildResultDao;
211     }
212 
213     public void setConfigurationService( ConfigurationService configurationService )
214     {
215         this.configurationService = configurationService;
216     }
217 
218     public void setDistributedBuildManager( DistributedBuildManager distributedBuildManager )
219     {
220         this.distributedBuildManager = distributedBuildManager;
221     }
222 }