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