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 com.opensymphony.xwork2.Preparable;
23  import org.apache.commons.lang.StringEscapeUtils;
24  import org.apache.continuum.model.repository.AbstractPurgeConfiguration;
25  import org.apache.continuum.model.repository.DirectoryPurgeConfiguration;
26  import org.apache.continuum.model.repository.LocalRepository;
27  import org.apache.continuum.model.repository.RepositoryPurgeConfiguration;
28  import org.apache.continuum.purge.ContinuumPurgeManager;
29  import org.apache.continuum.purge.PurgeConfigurationService;
30  import org.apache.continuum.repository.RepositoryService;
31  import org.apache.continuum.taskqueue.manager.TaskQueueManager;
32  import org.apache.continuum.web.util.AuditLog;
33  import org.apache.continuum.web.util.AuditLogConstants;
34  import org.apache.maven.continuum.configuration.ConfigurationService;
35  import org.apache.maven.continuum.model.project.Schedule;
36  import org.apache.maven.continuum.security.ContinuumRoleConstants;
37  import org.apache.maven.continuum.web.action.ContinuumConfirmAction;
38  import org.apache.struts2.ServletActionContext;
39  import org.codehaus.plexus.redback.rbac.Resource;
40  import org.codehaus.redback.integration.interceptor.SecureAction;
41  import org.codehaus.redback.integration.interceptor.SecureActionBundle;
42  import org.codehaus.redback.integration.interceptor.SecureActionException;
43  import org.slf4j.Logger;
44  import org.slf4j.LoggerFactory;
45  
46  import java.util.ArrayList;
47  import java.util.Collection;
48  import java.util.HashMap;
49  import java.util.List;
50  import java.util.Map;
51  
52  /**
53   * @author Maria Catherine Tan
54   * @version $Id: PurgeConfigurationAction.java 1372260 2012-08-13 04:29:09Z brett $
55   * @plexus.component role="com.opensymphony.xwork2.Action" role-hint="purgeConfiguration"
56   * @since 25 jul 07
57   */
58  public class PurgeConfigurationAction
59      extends ContinuumConfirmAction
60      implements Preparable, SecureAction
61  {
62      private static final Logger logger = LoggerFactory.getLogger( PurgeConfigurationAction.class );
63  
64      private static final String PURGE_TYPE_REPOSITORY = "repository";
65  
66      private static final String PURGE_TYPE_DIRECTORY = "directory";
67  
68      private static final String PURGE_DIRECTORY_RELEASES = "releases";
69  
70      private static final String PURGE_DIRECTORY_BUILDOUTPUT = "buildOutput";
71  
72      private static final int DEFAULT_RETENTION_COUNT = 2;
73  
74      private static final int DEFAULT_DAYS_OLDER = 100;
75  
76      private String purgeType;
77  
78      private String directoryType;
79  
80      private String description;
81  
82      private String message;
83  
84      private boolean deleteAll;
85  
86      private boolean deleteReleasedSnapshots;
87  
88      private boolean enabled;
89  
90      private boolean confirmed;
91  
92      private boolean defaultPurgeConfiguration;
93  
94      private int retentionCount;
95  
96      private int daysOlder;
97  
98      private int repositoryId;
99  
100     private int scheduleId;
101 
102     private int purgeConfigId;
103 
104     private AbstractPurgeConfiguration purgeConfig;
105 
106     private Map<Integer, String> repositories;
107 
108     private Map<Integer, String> schedules;
109 
110     private List<RepositoryPurgeConfiguration> repoPurgeConfigs;
111 
112     private List<DirectoryPurgeConfiguration> dirPurgeConfigs;
113 
114     private List<String> directoryTypes;
115 
116     /**
117      * @plexus.requirement
118      */
119     private PurgeConfigurationService purgeConfigService;
120 
121     /**
122      * @plexus.requirement
123      */
124     private RepositoryService repositoryService;
125 
126     @Override
127     public void prepare()
128         throws Exception
129     {
130         super.prepare();
131 
132         // build schedules
133         if ( schedules == null )
134         {
135             schedules = new HashMap<Integer, String>();
136 
137             Collection<Schedule> allSchedules = getContinuum().getSchedules();
138 
139             for ( Schedule schedule : allSchedules )
140             {
141                 schedules.put( schedule.getId(), schedule.getName() );
142             }
143         }
144 
145         // build repositories
146         if ( repositories == null )
147         {
148             repositories = new HashMap<Integer, String>();
149 
150             List<LocalRepository> allRepositories = repositoryService.getAllLocalRepositories();
151 
152             for ( LocalRepository repository : allRepositories )
153             {
154                 repositories.put( repository.getId(), repository.getName() );
155             }
156         }
157 
158         directoryTypes = new ArrayList<String>();
159         directoryTypes.add( PURGE_DIRECTORY_RELEASES );
160         directoryTypes.add( PURGE_DIRECTORY_BUILDOUTPUT );
161     }
162 
163     @Override
164     public String input()
165         throws Exception
166     {
167         if ( purgeConfigId != 0 )
168         {
169             purgeConfig = purgeConfigService.getPurgeConfiguration( purgeConfigId );
170 
171             if ( purgeConfig instanceof RepositoryPurgeConfiguration )
172             {
173                 RepositoryPurgeConfiguration repoPurge = (RepositoryPurgeConfiguration) purgeConfig;
174 
175                 this.purgeType = PURGE_TYPE_REPOSITORY;
176                 this.daysOlder = repoPurge.getDaysOlder();
177                 this.retentionCount = repoPurge.getRetentionCount();
178                 this.deleteAll = repoPurge.isDeleteAll();
179                 this.deleteReleasedSnapshots = repoPurge.isDeleteReleasedSnapshots();
180                 this.enabled = repoPurge.isEnabled();
181                 this.defaultPurgeConfiguration = repoPurge.isDefaultPurge();
182                 this.description = repoPurge.getDescription();
183 
184                 if ( repoPurge.getRepository() != null )
185                 {
186                     this.repositoryId = repoPurge.getRepository().getId();
187                 }
188 
189                 if ( repoPurge.getSchedule() != null )
190                 {
191                     this.scheduleId = repoPurge.getSchedule().getId();
192                 }
193             }
194             else if ( purgeConfig instanceof DirectoryPurgeConfiguration )
195             {
196                 DirectoryPurgeConfiguration dirPurge = (DirectoryPurgeConfiguration) purgeConfig;
197 
198                 this.purgeType = PURGE_TYPE_DIRECTORY;
199                 this.daysOlder = dirPurge.getDaysOlder();
200                 this.retentionCount = dirPurge.getRetentionCount();
201                 this.directoryType = dirPurge.getDirectoryType();
202                 this.deleteAll = dirPurge.isDeleteAll();
203                 this.enabled = dirPurge.isEnabled();
204                 this.defaultPurgeConfiguration = dirPurge.isDefaultPurge();
205                 this.description = dirPurge.getDescription();
206 
207                 if ( dirPurge.getSchedule() != null )
208                 {
209                     this.scheduleId = dirPurge.getSchedule().getId();
210                 }
211             }
212         }
213         else
214         {
215             this.retentionCount = DEFAULT_RETENTION_COUNT;
216             this.daysOlder = DEFAULT_DAYS_OLDER;
217         }
218 
219         return INPUT;
220     }
221 
222     public String list()
223         throws Exception
224     {
225         String errorMessage = ServletActionContext.getRequest().getParameter( "errorMessage" );
226 
227         if ( errorMessage != null )
228         {
229             addActionError( getText( errorMessage ) );
230         }
231 
232         repoPurgeConfigs = purgeConfigService.getAllRepositoryPurgeConfigurations();
233         dirPurgeConfigs = purgeConfigService.getAllDirectoryPurgeConfigurations();
234 
235         return SUCCESS;
236     }
237 
238     public String save()
239         throws Exception
240     {
241         if ( purgeConfigId == 0 )
242         {
243             if ( purgeType.equals( PURGE_TYPE_REPOSITORY ) )
244             {
245                 purgeConfig = new RepositoryPurgeConfiguration();
246             }
247             else
248             {
249                 purgeConfig = new DirectoryPurgeConfiguration();
250             }
251 
252             purgeConfig = setupPurgeConfiguration( purgeConfig );
253 
254             purgeConfig = purgeConfigService.addPurgeConfiguration( purgeConfig );
255         }
256         else
257         {
258             purgeConfig = purgeConfigService.getPurgeConfiguration( purgeConfigId );
259             purgeConfig = setupPurgeConfiguration( purgeConfig );
260 
261             purgeConfigService.updatePurgeConfiguration( purgeConfig );
262         }
263 
264         if ( purgeConfig.isDefaultPurge() )
265         {
266             updateDefaultPurgeConfiguration();
267         }
268 
269         if ( purgeConfig.isEnabled() && purgeConfig.getSchedule() != null )
270         {
271             getContinuum().activePurgeSchedule( purgeConfig.getSchedule() );
272         }
273 
274         return SUCCESS;
275     }
276 
277     public String remove()
278         throws Exception
279     {
280         if ( confirmed )
281         {
282             purgeConfigService.removePurgeConfiguration( purgeConfigId );
283         }
284         else
285         {
286             return CONFIRM;
287         }
288 
289         return SUCCESS;
290     }
291 
292     public String purge()
293         throws Exception
294     {
295         ContinuumPurgeManager purgeManager = getContinuum().getPurgeManager();
296         TaskQueueManager taskQueueManager = getContinuum().getTaskQueueManager();
297 
298         if ( purgeConfigId > 0 )
299         {
300             purgeConfig = purgeConfigService.getPurgeConfiguration( purgeConfigId );
301 
302             AuditLog event;
303 
304             if ( purgeConfig instanceof RepositoryPurgeConfiguration )
305             {
306                 RepositoryPurgeConfiguration repoPurge = (RepositoryPurgeConfiguration) purgeConfig;
307 
308                 // check if repository is in use
309                 if ( taskQueueManager.isRepositoryInUse( repoPurge.getRepository().getId() ) )
310                 {
311                     message = "repository.error.purge.in.use";
312                     return ERROR;
313                 }
314 
315                 purgeManager.purgeRepository( repoPurge );
316 
317                 event = new AuditLog( repoPurge.getRepository().getName(), AuditLogConstants.PURGE_LOCAL_REPOSITORY );
318                 event.setCategory( AuditLogConstants.LOCAL_REPOSITORY );
319             }
320             else
321             {
322                 DirectoryPurgeConfiguration dirPurge = (DirectoryPurgeConfiguration) purgeConfig;
323                 purgeManager.purgeDirectory( dirPurge );
324 
325                 if ( dirPurge.getDirectoryType().equals( PURGE_DIRECTORY_RELEASES ) )
326                 {
327                     event = new AuditLog( dirPurge.getLocation(), AuditLogConstants.PURGE_DIRECTORY_RELEASES );
328                 }
329                 else
330                 {
331                     event = new AuditLog( dirPurge.getLocation(), AuditLogConstants.PURGE_DIRECTORY_BUILDOUTPUT );
332                 }
333 
334                 event.setCategory( AuditLogConstants.DIRECTORY );
335             }
336 
337             event.setCurrentUser( getPrincipal() );
338             event.log();
339         }
340 
341         return SUCCESS;
342     }
343 
344     public String getPurgeType()
345     {
346         return this.purgeType;
347     }
348 
349     public void setPurgeType( String purgeType )
350     {
351         this.purgeType = purgeType;
352     }
353 
354     public String getDirectoryType()
355     {
356         return this.directoryType;
357     }
358 
359     public void setDirectoryType( String directoryType )
360     {
361         this.directoryType = directoryType;
362     }
363 
364     public String getDescription()
365     {
366         return this.description;
367     }
368 
369     public void setDescription( String description )
370     {
371         this.description = description;
372     }
373 
374     public String getMessage()
375     {
376         return this.message;
377     }
378 
379     public void setMessage( String message )
380     {
381         this.message = message;
382     }
383 
384     public boolean isDeleteAll()
385     {
386         return this.deleteAll;
387     }
388 
389     public void setDeleteAll( boolean deleteAll )
390     {
391         this.deleteAll = deleteAll;
392     }
393 
394     public boolean isDeleteReleasedSnapshots()
395     {
396         return this.deleteReleasedSnapshots;
397     }
398 
399     public void setDeleteReleasedSnapshots( boolean deleteReleasedSnapshots )
400     {
401         this.deleteReleasedSnapshots = deleteReleasedSnapshots;
402     }
403 
404     public boolean isEnabled()
405     {
406         return this.enabled;
407     }
408 
409     public void setEnabled( boolean enabled )
410     {
411         this.enabled = enabled;
412     }
413 
414     @Override
415     public boolean isConfirmed()
416     {
417         return this.confirmed;
418     }
419 
420     @Override
421     public void setConfirmed( boolean confirmed )
422     {
423         this.confirmed = confirmed;
424     }
425 
426     public boolean isDefaultPurgeConfiguration()
427     {
428         return this.defaultPurgeConfiguration;
429     }
430 
431     public void setDefaultPurgeConfiguration( boolean defaultPurgeConfiguration )
432     {
433         this.defaultPurgeConfiguration = defaultPurgeConfiguration;
434     }
435 
436     public int getRetentionCount()
437     {
438         return this.retentionCount;
439     }
440 
441     public void setRetentionCount( int retentionCount )
442     {
443         this.retentionCount = retentionCount;
444     }
445 
446     public int getDaysOlder()
447     {
448         return this.daysOlder;
449     }
450 
451     public void setDaysOlder( int daysOlder )
452     {
453         this.daysOlder = daysOlder;
454     }
455 
456     public int getRepositoryId()
457     {
458         return this.repositoryId;
459     }
460 
461     public void setRepositoryId( int repositoryId )
462     {
463         this.repositoryId = repositoryId;
464     }
465 
466     public int getScheduleId()
467     {
468         return this.scheduleId;
469     }
470 
471     public void setScheduleId( int scheduleId )
472     {
473         this.scheduleId = scheduleId;
474     }
475 
476     public int getPurgeConfigId()
477     {
478         return purgeConfigId;
479     }
480 
481     public void setPurgeConfigId( int purgeConfigId )
482     {
483         this.purgeConfigId = purgeConfigId;
484     }
485 
486     public AbstractPurgeConfiguration getPurgeConfig()
487     {
488         return this.purgeConfig;
489     }
490 
491     public void setPurgeConfig( AbstractPurgeConfiguration purgeConfig )
492     {
493         this.purgeConfig = purgeConfig;
494     }
495 
496     public Map<Integer, String> getRepositories()
497     {
498         return this.repositories;
499     }
500 
501     public void setRepositories( Map<Integer, String> repositories )
502     {
503         this.repositories = repositories;
504     }
505 
506     public Map<Integer, String> getSchedules()
507     {
508         return this.schedules;
509     }
510 
511     public void setSchedules( Map<Integer, String> schedules )
512     {
513         this.schedules = schedules;
514     }
515 
516     public List<RepositoryPurgeConfiguration> getRepoPurgeConfigs()
517     {
518         return this.repoPurgeConfigs;
519     }
520 
521     public void setRepoPurgeConfigs( List<RepositoryPurgeConfiguration> repoPurgeConfigs )
522     {
523         this.repoPurgeConfigs = repoPurgeConfigs;
524     }
525 
526     public List<DirectoryPurgeConfiguration> getDirPurgeConfigs()
527     {
528         return this.dirPurgeConfigs;
529     }
530 
531     public void setDirPurgeConfigs( List<DirectoryPurgeConfiguration> dirPurgeConfigs )
532     {
533         this.dirPurgeConfigs = dirPurgeConfigs;
534     }
535 
536     public List<String> getDirectoryTypes()
537     {
538         return this.directoryTypes;
539     }
540 
541     public void setDirectoryTypes( List<String> directoryTypes )
542     {
543         this.directoryTypes = directoryTypes;
544     }
545 
546     private AbstractPurgeConfiguration setupPurgeConfiguration( AbstractPurgeConfiguration purgeConfiguration )
547         throws Exception
548     {
549         if ( purgeConfiguration instanceof RepositoryPurgeConfiguration )
550         {
551             return buildRepoPurgeConfiguration();
552         }
553         else
554         {
555             return buildDirPurgeConfiguration();
556         }
557     }
558 
559     private RepositoryPurgeConfiguration buildRepoPurgeConfiguration()
560         throws Exception
561     {
562         RepositoryPurgeConfiguration repoPurge = (RepositoryPurgeConfiguration) purgeConfig;
563         repoPurge.setDeleteAll( this.deleteAll );
564         repoPurge.setDeleteReleasedSnapshots( this.deleteReleasedSnapshots );
565         repoPurge.setDaysOlder( this.daysOlder );
566         repoPurge.setRetentionCount( this.retentionCount );
567         repoPurge.setEnabled( this.enabled );
568         repoPurge.setDefaultPurge( this.defaultPurgeConfiguration );
569         // escape xml to prevent xss attacks
570         repoPurge.setDescription( StringEscapeUtils.escapeXml( StringEscapeUtils.unescapeXml( this.description ) ) );
571         repoPurge.setDefaultPurge( this.defaultPurgeConfiguration );
572 
573         if ( repositoryId != 0 )
574         {
575             LocalRepository repository = repositoryService.getLocalRepository( repositoryId );
576             repoPurge.setRepository( repository );
577         }
578 
579         if ( scheduleId > 0 )
580         {
581             Schedule schedule = getContinuum().getSchedule( scheduleId );
582             repoPurge.setSchedule( schedule );
583         }
584 
585         return repoPurge;
586     }
587 
588     private DirectoryPurgeConfiguration buildDirPurgeConfiguration()
589         throws Exception
590     {
591         DirectoryPurgeConfiguration dirPurge = (DirectoryPurgeConfiguration) purgeConfig;
592         dirPurge.setDeleteAll( this.deleteAll );
593         dirPurge.setEnabled( this.enabled );
594         dirPurge.setDaysOlder( this.daysOlder );
595         dirPurge.setRetentionCount( this.retentionCount );
596         // escape xml to prevent xss attacks
597         dirPurge.setDescription( StringEscapeUtils.escapeXml( StringEscapeUtils.unescapeXml( this.description ) ) );
598         dirPurge.setDirectoryType( this.directoryType );
599         dirPurge.setDefaultPurge( this.defaultPurgeConfiguration );
600 
601         if ( scheduleId > 0 )
602         {
603             Schedule schedule = getContinuum().getSchedule( scheduleId );
604             dirPurge.setSchedule( schedule );
605         }
606 
607         ConfigurationService configService = getContinuum().getConfiguration();
608         String path = null;
609 
610         if ( this.directoryType.equals( PURGE_DIRECTORY_RELEASES ) )
611         {
612             path = configService.getWorkingDirectory().getAbsolutePath();
613         }
614         else if ( this.directoryType.equals( PURGE_DIRECTORY_BUILDOUTPUT ) )
615         {
616             path = configService.getBuildOutputDirectory().getAbsolutePath();
617         }
618 
619         dirPurge.setLocation( path );
620 
621         return dirPurge;
622     }
623 
624     private void updateDefaultPurgeConfiguration()
625         throws Exception
626     {
627         if ( purgeConfig instanceof RepositoryPurgeConfiguration )
628         {
629             RepositoryPurgeConfiguration repoPurge = purgeConfigService.getDefaultPurgeConfigurationForRepository(
630                 repositoryId );
631 
632             if ( repoPurge != null && repoPurge.getId() != purgeConfig.getId() )
633             {
634                 repoPurge.setDefaultPurge( false );
635                 purgeConfigService.updateRepositoryPurgeConfiguration( repoPurge );
636             }
637         }
638         else if ( purgeConfig instanceof DirectoryPurgeConfiguration )
639         {
640             DirectoryPurgeConfiguration dirPurge = purgeConfigService.getDefaultPurgeConfigurationForDirectoryType(
641                 directoryType );
642 
643             if ( dirPurge != null && dirPurge.getId() != purgeConfig.getId() )
644             {
645                 dirPurge.setDefaultPurge( false );
646                 purgeConfigService.updateDirectoryPurgeConfiguration( dirPurge );
647             }
648         }
649     }
650 
651     public SecureActionBundle getSecureActionBundle()
652         throws SecureActionException
653     {
654         SecureActionBundle bundle = new SecureActionBundle();
655         bundle.setRequiresAuthentication( true );
656         bundle.addRequiredAuthorization( ContinuumRoleConstants.CONTINUUM_MANAGE_PURGING, Resource.GLOBAL );
657 
658         return bundle;
659     }
660 }