This project has retired. For details please refer to its Attic page.
DefaultRepositoryGroupAdmin xref
View Javadoc
1   package org.apache.archiva.admin.repository.group;
2   /*
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   */
20  
21  import org.apache.archiva.admin.model.AuditInformation;
22  import org.apache.archiva.admin.model.RepositoryAdminException;
23  import org.apache.archiva.admin.model.beans.ManagedRepository;
24  import org.apache.archiva.admin.model.beans.RepositoryGroup;
25  import org.apache.archiva.admin.model.group.RepositoryGroupAdmin;
26  import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
27  import org.apache.archiva.admin.repository.AbstractRepositoryAdmin;
28  import org.apache.archiva.configuration.Configuration;
29  import org.apache.archiva.configuration.RepositoryGroupConfiguration;
30  import org.apache.archiva.metadata.model.facets.AuditEvent;
31  import org.apache.archiva.scheduler.MergedRemoteIndexesScheduler;
32  import org.apache.commons.lang.StringUtils;
33  import org.slf4j.Logger;
34  import org.slf4j.LoggerFactory;
35  import org.springframework.stereotype.Service;
36  
37  import javax.annotation.PostConstruct;
38  import javax.inject.Inject;
39  import java.io.File;
40  import java.util.ArrayList;
41  import java.util.Arrays;
42  import java.util.Collections;
43  import java.util.HashMap;
44  import java.util.List;
45  import java.util.Map;
46  import java.util.regex.Matcher;
47  import java.util.regex.Pattern;
48  
49  /**
50   * @author Olivier Lamy
51   */
52  @Service("repositoryGroupAdmin#default")
53  public class DefaultRepositoryGroupAdmin
54      extends AbstractRepositoryAdmin
55      implements RepositoryGroupAdmin
56  {
57  
58      private Logger log = LoggerFactory.getLogger( getClass() );
59  
60      private static final Pattern REPO_GROUP_ID_PATTERN = Pattern.compile( "[A-Za-z0-9\\._\\-]+" );
61  
62      @Inject
63      private ManagedRepositoryAdmin managedRepositoryAdmin;
64  
65      @Inject
66      private MergedRemoteIndexesScheduler mergedRemoteIndexesScheduler;
67  
68      private File groupsDirectory;
69  
70      @PostConstruct
71      public void initialize()
72      {
73          String appServerBase = getRegistry().getString( "appserver.base" );
74          groupsDirectory = new File( appServerBase + File.separatorChar + "groups" );
75          if ( !groupsDirectory.exists() )
76          {
77              groupsDirectory.mkdirs();
78          }
79  
80          try
81          {
82              for ( RepositoryGroup repositoryGroup : getRepositoriesGroups() )
83              {
84                  mergedRemoteIndexesScheduler.schedule( repositoryGroup,
85                                                         getMergedIndexDirectory( repositoryGroup.getId() ) );
86                  // create the directory for each group if not exists
87                  File groupPath = new File( groupsDirectory, repositoryGroup.getId() );
88                  if ( !groupPath.exists() )
89                  {
90                      groupPath.mkdirs();
91                  }
92              }
93          }
94          catch ( RepositoryAdminException e )
95          {
96              log.warn( "fail to getRepositoriesGroups {}", e.getMessage(), e );
97          }
98  
99      }
100 
101 
102     @Override
103     public File getMergedIndexDirectory( String repositoryGroupId )
104     {
105         return new File( groupsDirectory, repositoryGroupId );
106     }
107 
108     @Override
109     public List<RepositoryGroup> getRepositoriesGroups()
110         throws RepositoryAdminException
111     {
112         List<RepositoryGroup> repositoriesGroups =
113             new ArrayList<>( getArchivaConfiguration().getConfiguration().getRepositoryGroups().size() );
114 
115         for ( RepositoryGroupConfiguration repositoryGroupConfiguration : getArchivaConfiguration().getConfiguration().getRepositoryGroups() )
116         {
117             repositoriesGroups.add( new RepositoryGroup( repositoryGroupConfiguration.getId(), new ArrayList<String>(
118                 repositoryGroupConfiguration.getRepositories() ) ).mergedIndexPath(
119                 repositoryGroupConfiguration.getMergedIndexPath() ).mergedIndexTtl(
120                 repositoryGroupConfiguration.getMergedIndexTtl() ).cronExpression(
121                 repositoryGroupConfiguration.getCronExpression() ) );
122         }
123 
124         return repositoriesGroups;
125     }
126 
127     @Override
128     public RepositoryGroup getRepositoryGroup( String repositoryGroupId )
129         throws RepositoryAdminException
130     {
131         List<RepositoryGroup> repositoriesGroups = getRepositoriesGroups();
132         for ( RepositoryGroup repositoryGroup : repositoriesGroups )
133         {
134             if ( StringUtils.equals( repositoryGroupId, repositoryGroup.getId() ) )
135             {
136                 return repositoryGroup;
137             }
138         }
139         return null;
140     }
141 
142     @Override
143     public Boolean addRepositoryGroup( RepositoryGroup repositoryGroup, AuditInformation auditInformation )
144         throws RepositoryAdminException
145     {
146         validateRepositoryGroup( repositoryGroup, false );
147         validateManagedRepositoriesExists( repositoryGroup.getRepositories() );
148 
149         RepositoryGroupConfiguration repositoryGroupConfiguration = new RepositoryGroupConfiguration();
150         repositoryGroupConfiguration.setId( repositoryGroup.getId() );
151         repositoryGroupConfiguration.setRepositories( repositoryGroup.getRepositories() );
152         repositoryGroupConfiguration.setMergedIndexPath( repositoryGroup.getMergedIndexPath() );
153         repositoryGroupConfiguration.setMergedIndexTtl( repositoryGroup.getMergedIndexTtl() );
154         repositoryGroupConfiguration.setCronExpression( repositoryGroup.getCronExpression() );
155         Configuration configuration = getArchivaConfiguration().getConfiguration();
156         configuration.addRepositoryGroup( repositoryGroupConfiguration );
157         saveConfiguration( configuration );
158         triggerAuditEvent( repositoryGroup.getId(), null, AuditEvent.ADD_REPO_GROUP, auditInformation );
159         mergedRemoteIndexesScheduler.schedule( repositoryGroup, getMergedIndexDirectory( repositoryGroup.getId() ) );
160         return Boolean.TRUE;
161     }
162 
163     @Override
164     public Boolean deleteRepositoryGroup( String repositoryGroupId, AuditInformation auditInformation )
165         throws RepositoryAdminException
166     {
167         Configuration configuration = getArchivaConfiguration().getConfiguration();
168         RepositoryGroupConfiguration repositoryGroupConfiguration =
169             configuration.getRepositoryGroupsAsMap().get( repositoryGroupId );
170         mergedRemoteIndexesScheduler.unschedule(
171             new RepositoryGroup( repositoryGroupId, Collections.<String>emptyList() ) );
172         if ( repositoryGroupConfiguration == null )
173         {
174             throw new RepositoryAdminException(
175                 "repositoryGroup with id " + repositoryGroupId + " doesn't not exists so cannot remove" );
176         }
177         configuration.removeRepositoryGroup( repositoryGroupConfiguration );
178         triggerAuditEvent( repositoryGroupId, null, AuditEvent.DELETE_REPO_GROUP, auditInformation );
179 
180         return Boolean.TRUE;
181     }
182 
183     @Override
184     public Boolean updateRepositoryGroup( RepositoryGroup repositoryGroup, AuditInformation auditInformation )
185         throws RepositoryAdminException
186     {
187         return updateRepositoryGroup( repositoryGroup, auditInformation, true );
188     }
189 
190     private Boolean updateRepositoryGroup( RepositoryGroup repositoryGroup, AuditInformation auditInformation,
191                                            boolean triggerAuditEvent )
192         throws RepositoryAdminException
193     {
194         validateRepositoryGroup( repositoryGroup, true );
195         validateManagedRepositoriesExists( repositoryGroup.getRepositories() );
196         Configuration configuration = getArchivaConfiguration().getConfiguration();
197 
198         RepositoryGroupConfiguration repositoryGroupConfiguration =
199             configuration.getRepositoryGroupsAsMap().get( repositoryGroup.getId() );
200 
201         configuration.removeRepositoryGroup( repositoryGroupConfiguration );
202 
203         repositoryGroupConfiguration.setRepositories( repositoryGroup.getRepositories() );
204         repositoryGroupConfiguration.setMergedIndexPath( repositoryGroup.getMergedIndexPath() );
205         repositoryGroupConfiguration.setMergedIndexTtl( repositoryGroup.getMergedIndexTtl() );
206         repositoryGroupConfiguration.setCronExpression( repositoryGroup.getCronExpression() );
207         configuration.addRepositoryGroup( repositoryGroupConfiguration );
208 
209         saveConfiguration( configuration );
210         if ( triggerAuditEvent )
211         {
212             triggerAuditEvent( repositoryGroup.getId(), null, AuditEvent.MODIFY_REPO_GROUP, auditInformation );
213         }
214         mergedRemoteIndexesScheduler.unschedule( repositoryGroup );
215         mergedRemoteIndexesScheduler.schedule( repositoryGroup, getMergedIndexDirectory( repositoryGroup.getId() ) );
216         return Boolean.TRUE;
217     }
218 
219 
220     @Override
221     public Boolean addRepositoryToGroup( String repositoryGroupId, String repositoryId,
222                                          AuditInformation auditInformation )
223         throws RepositoryAdminException
224     {
225         RepositoryGroup repositoryGroup = getRepositoryGroup( repositoryGroupId );
226         if ( repositoryGroup == null )
227         {
228             throw new RepositoryAdminException(
229                 "repositoryGroup with id " + repositoryGroupId + " doesn't not exists so cannot add repository to it" );
230         }
231 
232         if ( repositoryGroup.getRepositories().contains( repositoryId ) )
233         {
234             throw new RepositoryAdminException(
235                 "repositoryGroup with id " + repositoryGroupId + " already contain repository with id" + repositoryId );
236         }
237         validateManagedRepositoriesExists( Arrays.asList( repositoryId ) );
238 
239         repositoryGroup.addRepository( repositoryId );
240         updateRepositoryGroup( repositoryGroup, auditInformation, false );
241         triggerAuditEvent( repositoryGroup.getId(), null, AuditEvent.ADD_REPO_TO_GROUP, auditInformation );
242         return Boolean.TRUE;
243     }
244 
245     @Override
246     public Boolean deleteRepositoryFromGroup( String repositoryGroupId, String repositoryId,
247                                               AuditInformation auditInformation )
248         throws RepositoryAdminException
249     {
250         RepositoryGroup repositoryGroup = getRepositoryGroup( repositoryGroupId );
251         if ( repositoryGroup == null )
252         {
253             throw new RepositoryAdminException( "repositoryGroup with id " + repositoryGroupId
254                                                     + " doesn't not exists so cannot remove repository from it" );
255         }
256 
257         if ( !repositoryGroup.getRepositories().contains( repositoryId ) )
258         {
259             throw new RepositoryAdminException(
260                 "repositoryGroup with id " + repositoryGroupId + " doesn't not contains repository with id"
261                     + repositoryId
262             );
263         }
264 
265         repositoryGroup.removeRepository( repositoryId );
266         updateRepositoryGroup( repositoryGroup, auditInformation, false );
267         triggerAuditEvent( repositoryGroup.getId(), null, AuditEvent.DELETE_REPO_FROM_GROUP, auditInformation );
268         return Boolean.TRUE;
269     }
270 
271     @Override
272     public Map<String, RepositoryGroup> getRepositoryGroupsAsMap()
273         throws RepositoryAdminException
274     {
275         List<RepositoryGroup> repositoriesGroups = getRepositoriesGroups();
276         Map<String, RepositoryGroup> map = new HashMap<>( repositoriesGroups.size() );
277         for ( RepositoryGroup repositoryGroup : repositoriesGroups )
278         {
279             map.put( repositoryGroup.getId(), repositoryGroup );
280         }
281         return map;
282     }
283 
284     @Override
285     public Map<String, List<String>> getGroupToRepositoryMap()
286         throws RepositoryAdminException
287     {
288 
289         Map<String, List<String>> map = new HashMap<>();
290 
291         for ( ManagedRepository repo : getManagedRepositoryAdmin().getManagedRepositories() )
292         {
293             for ( RepositoryGroup group : getRepositoriesGroups() )
294             {
295                 if ( !group.getRepositories().contains( repo.getId() ) )
296                 {
297                     String groupId = group.getId();
298                     List<String> repos = map.get( groupId );
299                     if ( repos == null )
300                     {
301                         repos = new ArrayList<>();
302                         map.put( groupId, repos );
303                     }
304                     repos.add( repo.getId() );
305                 }
306             }
307         }
308         return map;
309     }
310 
311     @Override
312     public Map<String, List<String>> getRepositoryToGroupMap()
313         throws RepositoryAdminException
314     {
315         Map<String, List<String>> map = new HashMap<>();
316 
317         for ( RepositoryGroup group : getRepositoriesGroups() )
318         {
319             for ( String repositoryId : group.getRepositories() )
320             {
321                 List<String> groups = map.get( repositoryId );
322                 if ( groups == null )
323                 {
324                     groups = new ArrayList<>();
325                     map.put( repositoryId, groups );
326                 }
327                 groups.add( group.getId() );
328             }
329         }
330         return map;
331     }
332 
333     public Boolean validateRepositoryGroup( RepositoryGroup repositoryGroup, boolean updateMode )
334         throws RepositoryAdminException
335     {
336         String repoGroupId = repositoryGroup.getId();
337         if ( StringUtils.isBlank( repoGroupId ) )
338         {
339             throw new RepositoryAdminException( "repositoryGroup id cannot be empty" );
340         }
341 
342         if ( repoGroupId.length() > 100 )
343         {
344             throw new RepositoryAdminException(
345                 "Identifier [" + repoGroupId + "] is over the maximum limit of 100 characters" );
346 
347         }
348 
349         Matcher matcher = REPO_GROUP_ID_PATTERN.matcher( repoGroupId );
350         if ( !matcher.matches() )
351         {
352             throw new RepositoryAdminException(
353                 "Invalid character(s) found in identifier. Only the following characters are allowed: alphanumeric, '.', '-' and '_'" );
354         }
355 
356         if ( repositoryGroup.getMergedIndexTtl() <= 0 )
357         {
358             throw new RepositoryAdminException( "Merged Index TTL must be greater than 0." );
359         }
360 
361         Configuration configuration = getArchivaConfiguration().getConfiguration();
362 
363         if ( configuration.getRepositoryGroupsAsMap().containsKey( repoGroupId ) )
364         {
365             if ( !updateMode )
366             {
367                 throw new RepositoryAdminException( "Unable to add new repository group with id [" + repoGroupId
368                                                         + "], that id already exists as a repository group." );
369             }
370         }
371         else if ( configuration.getManagedRepositoriesAsMap().containsKey( repoGroupId ) )
372         {
373             throw new RepositoryAdminException( "Unable to add new repository group with id [" + repoGroupId
374                                                     + "], that id already exists as a managed repository." );
375         }
376         else if ( configuration.getRemoteRepositoriesAsMap().containsKey( repoGroupId ) )
377         {
378             throw new RepositoryAdminException( "Unable to add new repository group with id [" + repoGroupId
379                                                     + "], that id already exists as a remote repository." );
380         }
381 
382         return Boolean.TRUE;
383     }
384 
385     private void validateManagedRepositoriesExists( List<String> managedRepositoriesIds )
386         throws RepositoryAdminException
387     {
388         for ( String id : managedRepositoriesIds )
389         {
390             if ( getManagedRepositoryAdmin().getManagedRepository( id ) == null )
391             {
392                 throw new RepositoryAdminException(
393                     "managedRepository with id " + id + " not exists so cannot be used in a repositoryGroup" );
394             }
395         }
396     }
397 
398     public ManagedRepositoryAdmin getManagedRepositoryAdmin()
399     {
400         return managedRepositoryAdmin;
401     }
402 
403     public void setManagedRepositoryAdmin( ManagedRepositoryAdmin managedRepositoryAdmin )
404     {
405         this.managedRepositoryAdmin = managedRepositoryAdmin;
406     }
407 }