View Javadoc

1   package org.apache.continuum.web.action.admin;
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.commons.lang.StringEscapeUtils;
23  import org.apache.continuum.configuration.BuildAgentConfiguration;
24  import org.apache.continuum.configuration.BuildAgentGroupConfiguration;
25  import org.apache.continuum.web.util.AuditLog;
26  import org.apache.continuum.web.util.AuditLogConstants;
27  import org.apache.maven.continuum.ContinuumException;
28  import org.apache.maven.continuum.configuration.ConfigurationService;
29  import org.apache.maven.continuum.model.system.Installation;
30  import org.apache.maven.continuum.model.system.Profile;
31  import org.apache.maven.continuum.security.ContinuumRoleConstants;
32  import org.apache.maven.continuum.web.action.ContinuumConfirmAction;
33  import org.apache.struts2.ServletActionContext;
34  import org.codehaus.plexus.redback.rbac.Resource;
35  import org.codehaus.plexus.util.StringUtils;
36  import org.codehaus.redback.integration.interceptor.SecureAction;
37  import org.codehaus.redback.integration.interceptor.SecureActionBundle;
38  import org.codehaus.redback.integration.interceptor.SecureActionException;
39  import org.slf4j.Logger;
40  import org.slf4j.LoggerFactory;
41  
42  import java.util.ArrayList;
43  import java.util.Collections;
44  import java.util.List;
45  
46  /**
47   * @author Maria Catherine Tan
48   * @plexus.component role="com.opensymphony.xwork2.Action" role-hint="buildAgent"
49   */
50  public class BuildAgentAction
51      extends ContinuumConfirmAction
52      implements SecureAction
53  {
54      private static final Logger logger = LoggerFactory.getLogger( BuildAgentAction.class );
55  
56      private List<BuildAgentConfiguration> buildAgents;
57  
58      private BuildAgentConfiguration buildAgent;
59  
60      private BuildAgentGroupConfiguration buildAgentGroup;
61  
62      private List<BuildAgentGroupConfiguration> buildAgentGroups;
63  
64      private List<BuildAgentConfiguration> selectedbuildAgents;
65  
66      private List<String> selectedBuildAgentIds;
67  
68      private List<Installation> installations;
69  
70      private boolean confirmed;
71  
72      private String message;
73  
74      private String type;
75  
76      private String typeGroup;
77  
78      public void prepare()
79          throws Exception
80      {
81          super.prepare();
82          this.setBuildAgents( getContinuum().getConfiguration().getBuildAgents() );
83      }
84  
85      public String input()
86          throws Exception
87      {
88          if ( buildAgent != null && !StringUtils.isBlank( buildAgent.getUrl() ) )
89          {
90              String escapedBuildAgentUrl = StringEscapeUtils.escapeXml( buildAgent.getUrl() );
91              buildAgent.setUrl( escapedBuildAgentUrl );
92  
93              List<BuildAgentConfiguration> agents = getContinuum().getConfiguration().getBuildAgents();
94  
95              for ( BuildAgentConfiguration agent : agents )
96              {
97                  if ( agent.getUrl().equals( escapedBuildAgentUrl ) )
98                  {
99                      buildAgent = agent;
100                     type = "edit";
101                 }
102             }
103         }
104         else
105         {
106             type = "new";
107         }
108 
109         return INPUT;
110     }
111 
112     public String list()
113         throws Exception
114     {
115         String errorMessage = ServletActionContext.getRequest().getParameter( "errorMessage" );
116 
117         if ( errorMessage != null )
118         {
119             addActionError( errorMessage );
120         }
121 
122         this.buildAgents = getContinuum().getConfiguration().getBuildAgents();
123         this.buildAgentGroups = getContinuum().getConfiguration().getBuildAgentGroups();
124 
125         return SUCCESS;
126     }
127 
128     public String view()
129         throws Exception
130     {
131         ConfigurationService configuration = getContinuum().getConfiguration();
132 
133         if ( buildAgent != null )
134         {
135             String escapedBuildAgentUrl = StringEscapeUtils.escapeXml( buildAgent.getUrl() );
136             buildAgent.setUrl( escapedBuildAgentUrl );
137 
138             for ( BuildAgentConfiguration agent : configuration.getBuildAgents() )
139             {
140                 if ( agent.getUrl().equals( escapedBuildAgentUrl ) )
141                 {
142                     buildAgent = agent;
143     
144                     try
145                     {
146                         installations = getContinuum().getDistributedBuildManager().getAvailableInstallations( escapedBuildAgentUrl );
147                     }
148                     catch ( ContinuumException e )
149                     {
150                         logger.error( "Unable to retrieve installations of build agent '" + agent.getUrl() + "'", e );
151                     }
152     
153                     break;
154                 }
155             }
156         }
157 
158         return SUCCESS;
159     }
160 
161     public String save()
162         throws Exception
163     {
164         boolean found = false;
165 
166         ConfigurationService configuration = getContinuum().getConfiguration();
167 
168         // escape xml to prevent xss attacks
169         buildAgent.setDescription( StringEscapeUtils.escapeXml( StringEscapeUtils.unescapeXml( buildAgent.getDescription() ) ) );
170 
171         if ( configuration.getBuildAgents() != null )
172         {
173             for ( BuildAgentConfiguration agent : configuration.getBuildAgents() )
174             {
175                 if ( agent.getUrl().equals( buildAgent.getUrl() ) )
176                 {
177                     agent.setDescription( buildAgent.getDescription() );
178                     agent.setEnabled( buildAgent.isEnabled() );
179 
180                     configuration.updateBuildAgent( agent );
181                     configuration.store();
182                     found = true;
183                 }
184             }
185         }
186 
187         AuditLog event = new AuditLog( "Build Agent URL=" + buildAgent.getUrl(), AuditLogConstants.MODIFY_BUILD_AGENT );
188         event.setCategory( AuditLogConstants.BUILD_AGENT );
189         event.setCurrentUser( getPrincipal() );
190 
191         if ( !found )
192         {
193             configuration.addBuildAgent( buildAgent );
194             configuration.store();
195             event.setAction( AuditLogConstants.ADD_BUILD_AGENT );
196         }
197         else
198         {
199             if ( type.equals( "new" ) )
200             {
201                 addActionError( getResourceBundle().getString( "buildAgent.error.duplicate" ) );
202                 return INPUT;
203             }
204         }
205 
206         getContinuum().getDistributedBuildManager().reload();
207         event.log();
208 
209         return SUCCESS;
210     }
211 
212     public String delete()
213         throws Exception
214     {
215         buildAgent.setUrl( StringEscapeUtils.escapeXml( StringEscapeUtils.unescapeXml( buildAgent.getUrl() ) ) );
216 
217         if ( !confirmed )
218         {
219             return CONFIRM;
220         }
221 
222         if ( getContinuum().getDistributedBuildManager().isBuildAgentBusy( buildAgent.getUrl() ) )
223         {
224             message = getText( "buildAgent.error.delete.busy" );
225             return ERROR;
226         }
227 
228         ConfigurationService configuration = getContinuum().getConfiguration();
229 
230         if ( configuration.getBuildAgentGroups() != null )
231         {   
232             for ( BuildAgentGroupConfiguration buildAgentGroup : configuration.getBuildAgentGroups() )
233             {
234                 if ( configuration.containsBuildAgentUrl( buildAgent.getUrl(), buildAgentGroup ) )
235                 {
236                     message = getText( "buildAgent.error.remove.in.use" );
237                     return ERROR;
238                 }
239             }
240         }
241 
242         if ( configuration.getBuildAgents() != null )
243         {
244             for ( BuildAgentConfiguration agent : configuration.getBuildAgents() )
245             {
246                 if ( buildAgent.getUrl().equals( agent.getUrl() ) )
247                 {
248                     getContinuum().getDistributedBuildManager().removeDistributedBuildQueueOfAgent( buildAgent.getUrl() );
249                     configuration.removeBuildAgent( agent );
250                     configuration.store();
251 
252                     AuditLog event = new AuditLog( "Build Agent URL=" + agent.getUrl(), AuditLogConstants.REMOVE_BUILD_AGENT );
253                     event.setCategory( AuditLogConstants.BUILD_AGENT );
254                     event.setCurrentUser( getPrincipal() );
255                     event.log();
256 
257                     getContinuum().getDistributedBuildManager().reload();
258 
259                     return SUCCESS;
260                 }
261             }
262         }
263 
264         message = getText( "buildAgent.error.notfound" );
265         return ERROR;
266     }
267 
268     public String deleteGroup()
269         throws Exception
270     {
271         buildAgentGroup.setName( StringEscapeUtils.escapeXml( buildAgentGroup.getName() ) );
272 
273         if ( !confirmed )
274         {
275             return CONFIRM;
276         }
277 
278         List<Profile> profiles = getContinuum().getProfileService().getAllProfiles();
279         for ( Profile profile : profiles )
280         {
281             if ( buildAgentGroup.getName().equals( profile.getBuildAgentGroup() ) )
282             {
283                 message = getText( "buildAgentGroup.error.remove.in.use" );
284                 return ERROR;
285             }
286         }
287 
288         ConfigurationService configuration = getContinuum().getConfiguration();
289 
290         for ( BuildAgentGroupConfiguration group : configuration.getBuildAgentGroups() )
291         {
292             if ( buildAgentGroup.getName().equals( group.getName() ) )
293             {
294                 configuration.removeBuildAgentGroup( group );
295 
296                 AuditLog event = new AuditLog( "Build Agent Group=" + group.getName(), AuditLogConstants.REMOVE_BUILD_AGENT_GROUP );
297                 event.setCategory( AuditLogConstants.BUILD_AGENT );
298                 event.setCurrentUser( getPrincipal() );
299                 event.log();
300 
301                 return SUCCESS;
302             }
303         }
304 
305         message = getText( "buildAgentGroup.error.doesnotexist" );
306         return ERROR;
307     }
308 
309     public String saveGroup()
310         throws Exception
311     {
312         boolean found = false;
313 
314         ConfigurationService configuration = getContinuum().getConfiguration();
315         selectedbuildAgents = getBuildAgentsFromSelectedBuildAgents();
316 
317         if ( buildAgentGroup.getName() != null )
318         {
319             if ( buildAgentGroup.getName().equals( "" ) )
320             {
321                 addActionError( getResourceBundle().getString( "buildAgentGroup.error.name.required" ) );
322                 return INPUT;
323             }
324             else if ( buildAgentGroup.getName().trim().equals( "" ) )
325             {
326                 addActionError( getText( "buildAgentGroup.error.name.cannot.be.spaces" ) );
327                 return INPUT;
328             }
329         }
330 
331         if ( configuration.getBuildAgentGroups() != null )
332         {
333             for ( BuildAgentGroupConfiguration group : configuration.getBuildAgentGroups() )
334             {
335                 if ( buildAgentGroup.getName().equals( group.getName() ) )
336                 {
337                     group.setName( buildAgentGroup.getName() );
338                     configuration.updateBuildAgentGroup( group );
339                     found = true;
340                     break;
341                 }
342             }
343         }
344 
345         AuditLog event = new AuditLog( "Build Agent Group=" + buildAgentGroup.getName(), AuditLogConstants.MODIFY_BUILD_AGENT_GROUP );
346         event.setCategory( AuditLogConstants.BUILD_AGENT );
347         event.setCurrentUser( getPrincipal() );
348 
349         if ( !found )
350         {
351             buildAgentGroup.setBuildAgents( selectedbuildAgents );
352             configuration.addBuildAgentGroup( buildAgentGroup );
353             event.setAction( AuditLogConstants.ADD_BUILD_AGENT_GROUP );
354         }
355         else
356         // found
357         {
358             if ( typeGroup.equals( "new" ) )
359             {
360                 addActionError( getResourceBundle().getString( "buildAgentGroup.error.duplicate" ) );
361                 return INPUT;
362             }
363             else if ( typeGroup.equals( "edit" ) )
364             {
365                 buildAgentGroup.setBuildAgents( selectedbuildAgents );
366                 configuration.updateBuildAgentGroup( buildAgentGroup );
367             }
368         }
369 
370         getContinuum().getDistributedBuildManager().reload();
371         event.log();
372 
373         return SUCCESS;
374     }
375 
376     public String inputGroup()
377         throws Exception
378     {
379         ConfigurationService configuration = getContinuum().getConfiguration();
380 
381         if ( buildAgentGroup != null && !StringUtils.isBlank( buildAgentGroup.getName() ) )
382         {
383             String escapedBuildAgentGroupName = StringEscapeUtils.escapeXml( buildAgentGroup.getName() );
384             buildAgentGroup.setName( escapedBuildAgentGroupName );
385 
386             List<BuildAgentGroupConfiguration> agentGroups = configuration.getBuildAgentGroups();
387 
388             for ( BuildAgentGroupConfiguration group : agentGroups )
389             {
390                 if ( group.getName().equals( escapedBuildAgentGroupName ) )
391                 {
392                     buildAgentGroup = group;
393                     typeGroup = "edit";
394 
395                     this.buildAgentGroup = configuration.getBuildAgentGroup( escapedBuildAgentGroupName );
396                     this.buildAgents = configuration.getBuildAgents();
397 
398                     this.selectedBuildAgentIds = new ArrayList<String>();
399                     if ( this.buildAgentGroup.getBuildAgents() != null )
400                     {
401                         for ( BuildAgentConfiguration buildAgentConfiguration : buildAgentGroup.getBuildAgents() )
402                         {
403                             this.selectedBuildAgentIds.add( buildAgentConfiguration.getUrl() );
404                         }
405 
406                     }
407 
408                     List<BuildAgentConfiguration> unusedBuildAgents = new ArrayList<BuildAgentConfiguration>();
409 
410                     for ( BuildAgentConfiguration agent : getBuildAgents() )
411                     {
412                         if ( !this.selectedBuildAgentIds.contains( agent.getUrl() ) )
413                         {
414                             unusedBuildAgents.add( agent );
415                         }
416                     }
417                     this.setBuildAgents( unusedBuildAgents );
418 
419                     break;
420                 }
421             }
422         }
423         else
424         {
425             typeGroup = "new";
426         }
427         return INPUT;
428     }
429 
430     public SecureActionBundle getSecureActionBundle()
431         throws SecureActionException
432     {
433         SecureActionBundle bundle = new SecureActionBundle();
434         bundle.setRequiresAuthentication( true );
435         bundle.addRequiredAuthorization( ContinuumRoleConstants.CONTINUUM_MANAGE_DISTRIBUTED_BUILDS, Resource.GLOBAL );
436 
437         return bundle;
438     }
439 
440     private List<BuildAgentConfiguration> getBuildAgentsFromSelectedBuildAgents()
441     {
442         if ( this.selectedBuildAgentIds == null )
443         {
444             return Collections.EMPTY_LIST;
445         }
446 
447         List<BuildAgentConfiguration> selectedbuildAgents = new ArrayList<BuildAgentConfiguration>();
448         for ( String ids : selectedBuildAgentIds )
449         {
450             BuildAgentConfiguration buildAgent = getContinuum().getConfiguration().getBuildAgent( ids );
451             if ( buildAgent != null )
452             {
453                 selectedbuildAgents.add( buildAgent );
454             }
455         }
456         return selectedbuildAgents;
457     }
458 
459     public List<BuildAgentConfiguration> getBuildAgents()
460     {
461         return buildAgents;
462     }
463 
464     public void setBuildAgents( List<BuildAgentConfiguration> buildAgents )
465     {
466         this.buildAgents = buildAgents;
467     }
468 
469     public BuildAgentConfiguration getBuildAgent()
470     {
471         return buildAgent;
472     }
473 
474     public void setBuildAgent( BuildAgentConfiguration buildAgent )
475     {
476         this.buildAgent = buildAgent;
477     }
478 
479     public List<Installation> getInstallations()
480     {
481         return installations;
482     }
483 
484     public void setInstallations( List<Installation> installations )
485     {
486         this.installations = installations;
487     }
488 
489     public boolean isConfirmed()
490     {
491         return confirmed;
492     }
493 
494     public void setConfirmed( boolean confirmed )
495     {
496         this.confirmed = confirmed;
497     }
498 
499     public String getMessage()
500     {
501         return this.message;
502     }
503 
504     public void setMessage( String message )
505     {
506         this.message = message;
507     }
508 
509     public String getType()
510     {
511         return type;
512     }
513 
514     public void setType( String type )
515     {
516         this.type = type;
517     }
518 
519     public List<BuildAgentGroupConfiguration> getBuildAgentGroups()
520     {
521         return buildAgentGroups;
522     }
523 
524     public void setBuildAgentGroups( List<BuildAgentGroupConfiguration> buildAgentGroups )
525     {
526         this.buildAgentGroups = buildAgentGroups;
527     }
528 
529     public BuildAgentGroupConfiguration getBuildAgentGroup()
530     {
531         return buildAgentGroup;
532     }
533 
534     public void setBuildAgentGroup( BuildAgentGroupConfiguration buildAgentGroup )
535     {
536         this.buildAgentGroup = buildAgentGroup;
537     }
538 
539     public String getTypeGroup()
540     {
541         return typeGroup;
542     }
543 
544     public void setTypeGroup( String typeGroup )
545     {
546         this.typeGroup = typeGroup;
547     }
548 
549     public List<BuildAgentConfiguration> getSelectedbuildAgents()
550     {
551         return selectedbuildAgents;
552     }
553 
554     public void setSelectedbuildAgents( List<BuildAgentConfiguration> selectedbuildAgents )
555     {
556         this.selectedbuildAgents = selectedbuildAgents;
557     }
558 
559     public List<String> getSelectedBuildAgentIds()
560     {
561         return selectedBuildAgentIds == null ? Collections.EMPTY_LIST : selectedBuildAgentIds;
562     }
563 
564     public void setSelectedBuildAgentIds( List<String> selectedBuildAgentIds )
565     {
566         this.selectedBuildAgentIds = selectedBuildAgentIds;
567     }
568 }