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             buildAgent = new BuildAgentConfiguration();
108             buildAgent.setEnabled( true );
109         }
110 
111         return INPUT;
112     }
113 
114     public String list()
115         throws Exception
116     {
117         String errorMessage = ServletActionContext.getRequest().getParameter( "errorMessage" );
118 
119         if ( errorMessage != null )
120         {
121             addActionError( errorMessage );
122         }
123 
124         this.buildAgents = getContinuum().getConfiguration().getBuildAgents();
125         this.buildAgentGroups = getContinuum().getConfiguration().getBuildAgentGroups();
126 
127         return SUCCESS;
128     }
129 
130     public String view()
131         throws Exception
132     {
133         ConfigurationService configuration = getContinuum().getConfiguration();
134 
135         if ( buildAgent != null )
136         {
137             String escapedBuildAgentUrl = StringEscapeUtils.escapeXml( buildAgent.getUrl() );
138             buildAgent.setUrl( escapedBuildAgentUrl );
139 
140             for ( BuildAgentConfiguration agent : configuration.getBuildAgents() )
141             {
142                 if ( agent.getUrl().equals( escapedBuildAgentUrl ) )
143                 {
144                     buildAgent = agent;
145 
146                     try
147                     {
148                         installations = getContinuum().getDistributedBuildManager().getAvailableInstallations(
149                             escapedBuildAgentUrl );
150                     }
151                     catch ( ContinuumException e )
152                     {
153                         logger.error( "Unable to retrieve installations of build agent '" + agent.getUrl() + "'", e );
154                     }
155 
156                     break;
157                 }
158             }
159         }
160 
161         return SUCCESS;
162     }
163 
164     public String save()
165         throws Exception
166     {
167         boolean found = false;
168 
169         ConfigurationService configuration = getContinuum().getConfiguration();
170 
171         // escape xml to prevent xss attacks
172         buildAgent.setDescription(
173             StringEscapeUtils.escapeXml( StringEscapeUtils.unescapeXml( buildAgent.getDescription() ) ) );
174 
175         if ( configuration.getBuildAgents() != null )
176         {
177             for ( BuildAgentConfiguration agent : configuration.getBuildAgents() )
178             {
179                 if ( agent.getUrl().equals( buildAgent.getUrl() ) )
180                 {
181                     if ( type.equals( "new" ) )
182                     {
183                         addActionError( getResourceBundle().getString( "buildAgent.error.duplicate" ) );
184                         return INPUT;
185                     }
186                     else
187                     {
188                         agent.setDescription( buildAgent.getDescription() );
189                         agent.setEnabled( buildAgent.isEnabled() );
190                         configuration.updateBuildAgent( agent );
191                         configuration.store();
192                     }
193                     found = true;
194                 }
195             }
196         }
197 
198         // update first, so that we don't add or change it if it fails
199         try
200         {
201             getContinuum().getDistributedBuildManager().update( buildAgent );
202         }
203         catch ( ContinuumException e )
204         {
205             addActionError( e.getMessage() );
206             return INPUT;
207         }
208 
209         AuditLog event = new AuditLog( "Build Agent URL=" + buildAgent.getUrl(), AuditLogConstants.MODIFY_BUILD_AGENT );
210         event.setCategory( AuditLogConstants.BUILD_AGENT );
211         event.setCurrentUser( getPrincipal() );
212 
213         if ( !found )
214         {
215             configuration.addBuildAgent( buildAgent );
216             configuration.store();
217             event.setAction( AuditLogConstants.ADD_BUILD_AGENT );
218         }
219 
220         event.log();
221 
222         return SUCCESS;
223     }
224 
225     public String delete()
226         throws Exception
227     {
228         buildAgent.setUrl( StringEscapeUtils.escapeXml( buildAgent.getUrl() ) );
229 
230         if ( !confirmed )
231         {
232             return CONFIRM;
233         }
234 
235         if ( getContinuum().getDistributedBuildManager().isBuildAgentBusy( buildAgent.getUrl() ) )
236         {
237             message = getText( "buildAgent.error.delete.busy" );
238             return ERROR;
239         }
240 
241         ConfigurationService configuration = getContinuum().getConfiguration();
242 
243         if ( configuration.getBuildAgentGroups() != null )
244         {
245             for ( BuildAgentGroupConfiguration buildAgentGroup : configuration.getBuildAgentGroups() )
246             {
247                 if ( configuration.containsBuildAgentUrl( buildAgent.getUrl(), buildAgentGroup ) )
248                 {
249                     message = getText( "buildAgent.error.remove.in.use" );
250                     return ERROR;
251                 }
252             }
253         }
254 
255         if ( configuration.getBuildAgents() != null )
256         {
257             for ( BuildAgentConfiguration agent : configuration.getBuildAgents() )
258             {
259                 if ( buildAgent.getUrl().equals( agent.getUrl() ) )
260                 {
261                     getContinuum().getDistributedBuildManager().removeDistributedBuildQueueOfAgent(
262                         buildAgent.getUrl() );
263                     configuration.removeBuildAgent( agent );
264                     configuration.store();
265 
266                     AuditLog event =
267                         new AuditLog( "Build Agent URL=" + agent.getUrl(), AuditLogConstants.REMOVE_BUILD_AGENT );
268                     event.setCategory( AuditLogConstants.BUILD_AGENT );
269                     event.setCurrentUser( getPrincipal() );
270                     event.log();
271 
272                     getContinuum().getDistributedBuildManager().reload();
273 
274                     return SUCCESS;
275                 }
276             }
277         }
278 
279         message = getText( "buildAgent.error.notfound" );
280         return ERROR;
281     }
282 
283     public String deleteGroup()
284         throws Exception
285     {
286         buildAgentGroup.setName( StringEscapeUtils.escapeXml( buildAgentGroup.getName() ) );
287 
288         if ( !confirmed )
289         {
290             return CONFIRM;
291         }
292 
293         List<Profile> profiles = getContinuum().getProfileService().getAllProfiles();
294         for ( Profile profile : profiles )
295         {
296             if ( buildAgentGroup.getName().equals( profile.getBuildAgentGroup() ) )
297             {
298                 message = getText( "buildAgentGroup.error.remove.in.use", new String[]{ profile.getName() } );
299                 return ERROR;
300             }
301         }
302 
303         ConfigurationService configuration = getContinuum().getConfiguration();
304 
305         for ( BuildAgentGroupConfiguration group : configuration.getBuildAgentGroups() )
306         {
307             if ( buildAgentGroup.getName().equals( group.getName() ) )
308             {
309                 configuration.removeBuildAgentGroup( group );
310 
311                 AuditLog event =
312                     new AuditLog( "Build Agent Group=" + group.getName(), AuditLogConstants.REMOVE_BUILD_AGENT_GROUP );
313                 event.setCategory( AuditLogConstants.BUILD_AGENT );
314                 event.setCurrentUser( getPrincipal() );
315                 event.log();
316 
317                 return SUCCESS;
318             }
319         }
320 
321         message = getText( "buildAgentGroup.error.doesnotexist" );
322         return ERROR;
323     }
324 
325     public String saveGroup()
326         throws Exception
327     {
328         boolean found = false;
329 
330         ConfigurationService configuration = getContinuum().getConfiguration();
331         selectedbuildAgents = getBuildAgentsFromSelectedBuildAgents();
332 
333         if ( buildAgentGroup.getName() != null )
334         {
335             if ( buildAgentGroup.getName().equals( "" ) )
336             {
337                 addActionError( getResourceBundle().getString( "buildAgentGroup.error.name.required" ) );
338                 return INPUT;
339             }
340             else if ( buildAgentGroup.getName().trim().equals( "" ) )
341             {
342                 addActionError( getText( "buildAgentGroup.error.name.cannot.be.spaces" ) );
343                 return INPUT;
344             }
345         }
346 
347         if ( configuration.getBuildAgentGroups() != null )
348         {
349             for ( BuildAgentGroupConfiguration group : configuration.getBuildAgentGroups() )
350             {
351                 if ( buildAgentGroup.getName().equals( group.getName() ) )
352                 {
353                     group.setName( buildAgentGroup.getName() );
354                     configuration.updateBuildAgentGroup( group );
355                     found = true;
356                     break;
357                 }
358             }
359         }
360 
361         AuditLog event = new AuditLog( "Build Agent Group=" + buildAgentGroup.getName(),
362                                        AuditLogConstants.MODIFY_BUILD_AGENT_GROUP );
363         event.setCategory( AuditLogConstants.BUILD_AGENT );
364         event.setCurrentUser( getPrincipal() );
365 
366         if ( !found )
367         {
368             buildAgentGroup.setBuildAgents( selectedbuildAgents );
369             configuration.addBuildAgentGroup( buildAgentGroup );
370             event.setAction( AuditLogConstants.ADD_BUILD_AGENT_GROUP );
371         }
372         else
373         // found
374         {
375             if ( typeGroup.equals( "new" ) )
376             {
377                 addActionError( getResourceBundle().getString( "buildAgentGroup.error.duplicate" ) );
378                 return INPUT;
379             }
380             else if ( typeGroup.equals( "edit" ) )
381             {
382                 buildAgentGroup.setBuildAgents( selectedbuildAgents );
383                 configuration.updateBuildAgentGroup( buildAgentGroup );
384             }
385         }
386 
387         getContinuum().getDistributedBuildManager().reload();
388         event.log();
389 
390         return SUCCESS;
391     }
392 
393     public String inputGroup()
394         throws Exception
395     {
396         ConfigurationService configuration = getContinuum().getConfiguration();
397 
398         if ( buildAgentGroup != null && !StringUtils.isBlank( buildAgentGroup.getName() ) )
399         {
400             String escapedBuildAgentGroupName = StringEscapeUtils.escapeXml( buildAgentGroup.getName() );
401             buildAgentGroup.setName( escapedBuildAgentGroupName );
402 
403             List<BuildAgentGroupConfiguration> agentGroups = configuration.getBuildAgentGroups();
404 
405             for ( BuildAgentGroupConfiguration group : agentGroups )
406             {
407                 if ( group.getName().equals( escapedBuildAgentGroupName ) )
408                 {
409                     buildAgentGroup = group;
410                     typeGroup = "edit";
411 
412                     this.buildAgentGroup = configuration.getBuildAgentGroup( escapedBuildAgentGroupName );
413                     this.buildAgents = configuration.getBuildAgents();
414 
415                     this.selectedBuildAgentIds = new ArrayList<String>();
416                     if ( this.buildAgentGroup.getBuildAgents() != null )
417                     {
418                         for ( BuildAgentConfiguration buildAgentConfiguration : buildAgentGroup.getBuildAgents() )
419                         {
420                             this.selectedBuildAgentIds.add( buildAgentConfiguration.getUrl() );
421                         }
422 
423                     }
424 
425                     List<BuildAgentConfiguration> unusedBuildAgents = new ArrayList<BuildAgentConfiguration>();
426 
427                     for ( BuildAgentConfiguration agent : getBuildAgents() )
428                     {
429                         if ( !this.selectedBuildAgentIds.contains( agent.getUrl() ) )
430                         {
431                             unusedBuildAgents.add( agent );
432                         }
433                     }
434                     this.setBuildAgents( unusedBuildAgents );
435 
436                     break;
437                 }
438             }
439         }
440         else
441         {
442             typeGroup = "new";
443         }
444         return INPUT;
445     }
446 
447     public SecureActionBundle getSecureActionBundle()
448         throws SecureActionException
449     {
450         SecureActionBundle bundle = new SecureActionBundle();
451         bundle.setRequiresAuthentication( true );
452         bundle.addRequiredAuthorization( ContinuumRoleConstants.CONTINUUM_MANAGE_DISTRIBUTED_BUILDS, Resource.GLOBAL );
453 
454         return bundle;
455     }
456 
457     private List<BuildAgentConfiguration> getBuildAgentsFromSelectedBuildAgents()
458     {
459         if ( this.selectedBuildAgentIds == null )
460         {
461             return Collections.EMPTY_LIST;
462         }
463 
464         List<BuildAgentConfiguration> selectedbuildAgents = new ArrayList<BuildAgentConfiguration>();
465         for ( String ids : selectedBuildAgentIds )
466         {
467             BuildAgentConfiguration buildAgent = getContinuum().getConfiguration().getBuildAgent( ids );
468             if ( buildAgent != null )
469             {
470                 selectedbuildAgents.add( buildAgent );
471             }
472         }
473         return selectedbuildAgents;
474     }
475 
476     public List<BuildAgentConfiguration> getBuildAgents()
477     {
478         return buildAgents;
479     }
480 
481     public void setBuildAgents( List<BuildAgentConfiguration> buildAgents )
482     {
483         this.buildAgents = buildAgents;
484     }
485 
486     public BuildAgentConfiguration getBuildAgent()
487     {
488         return buildAgent;
489     }
490 
491     public void setBuildAgent( BuildAgentConfiguration buildAgent )
492     {
493         this.buildAgent = buildAgent;
494     }
495 
496     public List<Installation> getInstallations()
497     {
498         return installations;
499     }
500 
501     public void setInstallations( List<Installation> installations )
502     {
503         this.installations = installations;
504     }
505 
506     public boolean isConfirmed()
507     {
508         return confirmed;
509     }
510 
511     public void setConfirmed( boolean confirmed )
512     {
513         this.confirmed = confirmed;
514     }
515 
516     public String getMessage()
517     {
518         return this.message;
519     }
520 
521     public void setMessage( String message )
522     {
523         this.message = message;
524     }
525 
526     public String getType()
527     {
528         return type;
529     }
530 
531     public void setType( String type )
532     {
533         this.type = type;
534     }
535 
536     public List<BuildAgentGroupConfiguration> getBuildAgentGroups()
537     {
538         return buildAgentGroups;
539     }
540 
541     public void setBuildAgentGroups( List<BuildAgentGroupConfiguration> buildAgentGroups )
542     {
543         this.buildAgentGroups = buildAgentGroups;
544     }
545 
546     public BuildAgentGroupConfiguration getBuildAgentGroup()
547     {
548         return buildAgentGroup;
549     }
550 
551     public void setBuildAgentGroup( BuildAgentGroupConfiguration buildAgentGroup )
552     {
553         this.buildAgentGroup = buildAgentGroup;
554     }
555 
556     public String getTypeGroup()
557     {
558         return typeGroup;
559     }
560 
561     public void setTypeGroup( String typeGroup )
562     {
563         this.typeGroup = typeGroup;
564     }
565 
566     public List<BuildAgentConfiguration> getSelectedbuildAgents()
567     {
568         return selectedbuildAgents;
569     }
570 
571     public void setSelectedbuildAgents( List<BuildAgentConfiguration> selectedbuildAgents )
572     {
573         this.selectedbuildAgents = selectedbuildAgents;
574     }
575 
576     public List<String> getSelectedBuildAgentIds()
577     {
578         return selectedBuildAgentIds == null ? Collections.EMPTY_LIST : selectedBuildAgentIds;
579     }
580 
581     public void setSelectedBuildAgentIds( List<String> selectedBuildAgentIds )
582     {
583         this.selectedBuildAgentIds = selectedBuildAgentIds;
584     }
585 }