This project has retired. For details please refer to its
Attic page.
DefaultRepositoryGroupAdmin xref
1 package org.apache.archiva.admin.repository.group;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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.indexer.merger.MergedRemoteIndexesScheduler;
32 import org.apache.archiva.repository.EditableRepositoryGroup;
33 import org.apache.archiva.repository.RepositoryException;
34 import org.apache.archiva.repository.RepositoryRegistry;
35 import org.apache.archiva.repository.features.IndexCreationFeature;
36 import org.apache.archiva.repository.storage.StorageAsset;
37 import org.apache.commons.lang3.StringUtils;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40 import org.springframework.stereotype.Service;
41
42 import javax.annotation.PostConstruct;
43 import javax.inject.Inject;
44 import javax.inject.Named;
45 import java.io.IOException;
46 import java.nio.file.Files;
47 import java.nio.file.Path;
48 import java.nio.file.Paths;
49 import java.util.ArrayList;
50 import java.util.HashMap;
51 import java.util.List;
52 import java.util.Map;
53 import java.util.regex.Matcher;
54 import java.util.regex.Pattern;
55 import java.util.stream.Collectors;
56
57
58
59
60 @Service("repositoryGroupAdmin#default")
61 public class DefaultRepositoryGroupAdmin
62 extends AbstractRepositoryAdmin
63 implements RepositoryGroupAdmin
64 {
65
66 private Logger log = LoggerFactory.getLogger( getClass() );
67
68 private static final Pattern REPO_GROUP_ID_PATTERN = Pattern.compile( "[A-Za-z0-9\\._\\-]+" );
69
70 @Inject
71 private ManagedRepositoryAdmin managedRepositoryAdmin;
72
73 @Inject
74 @Named("mergedRemoteIndexesScheduler#default")
75 private MergedRemoteIndexesScheduler mergedRemoteIndexesScheduler;
76
77 @Inject
78 private RepositoryRegistry repositoryRegistry;
79
80 private Path groupsDirectory;
81
82 @PostConstruct
83 public void initialize()
84 {
85 String appServerBase = getRegistry().getString( "appserver.base" );
86 groupsDirectory = Paths.get( appServerBase, "groups" );
87 if ( !Files.exists(groupsDirectory) )
88 {
89 Files.exists(groupsDirectory);
90 }
91
92 for ( org.apache.archiva.repository.RepositoryGroup repositoryGroup : repositoryRegistry.getRepositoryGroups() )
93 {
94 mergedRemoteIndexesScheduler.schedule( repositoryGroup,
95 getMergedIndexDirectory( repositoryGroup.getId() ));
96
97 Path groupPath = groupsDirectory.resolve(repositoryGroup.getId() );
98 if ( !Files.exists(groupPath) )
99 {
100 try {
101 Files.createDirectories(groupPath);
102 } catch (IOException e) {
103 log.error("Could not create directory {}", groupPath);
104 }
105 }
106 }
107
108 }
109
110
111 @Override
112 public StorageAsset getMergedIndexDirectory(String repositoryGroupId )
113 {
114 org.apache.archiva.repository.RepositoryGroup group = repositoryRegistry.getRepositoryGroup(repositoryGroupId);
115 if (group!=null) {
116 return group.getFeature(IndexCreationFeature.class).get().getLocalIndexPath();
117 } else {
118 return null;
119 }
120 }
121
122 @Override
123 public List<RepositoryGroup> getRepositoriesGroups() {
124 return repositoryRegistry.getRepositoryGroups().stream().map( r -> convertRepositoryGroupObject( r ) ).collect( Collectors.toList());
125 }
126
127 @Override
128 public RepositoryGroup getRepositoryGroup( String repositoryGroupId ) {
129 return convertRepositoryGroupObject( repositoryRegistry.getRepositoryGroup( repositoryGroupId ) );
130 }
131
132 @Override
133 public Boolean addRepositoryGroup( RepositoryGroup repositoryGroup, AuditInformation auditInformation )
134 throws RepositoryAdminException
135 {
136 validateRepositoryGroup( repositoryGroup, false );
137 validateManagedRepositoriesExists( repositoryGroup.getRepositories() );
138
139 RepositoryGroupConfiguration#RepositoryGroupConfiguration">RepositoryGroupConfiguration repositoryGroupConfiguration = new RepositoryGroupConfiguration();
140 repositoryGroupConfiguration.setId( repositoryGroup.getId() );
141 repositoryGroupConfiguration.setRepositories( repositoryGroup.getRepositories() );
142 repositoryGroupConfiguration.setMergedIndexPath( repositoryGroup.getMergedIndexPath() );
143 repositoryGroupConfiguration.setMergedIndexTtl( repositoryGroup.getMergedIndexTtl() );
144 repositoryGroupConfiguration.setCronExpression( StringUtils.isEmpty(repositoryGroup.getCronExpression()) ? "0 0 03 ? * MON" : repositoryGroup.getCronExpression() );
145
146 try {
147 repositoryRegistry.putRepositoryGroup(repositoryGroupConfiguration);
148 } catch (RepositoryException e) {
149 e.printStackTrace();
150 }
151
152 triggerAuditEvent( repositoryGroup.getId(), null, AuditEvent.ADD_REPO_GROUP, auditInformation );
153 mergedRemoteIndexesScheduler.schedule( repositoryRegistry.getRepositoryGroup( repositoryGroup.getId()), getMergedIndexDirectory( repositoryGroup.getId() ) );
154 return Boolean.TRUE;
155 }
156
157 @Override
158 public Boolean deleteRepositoryGroup( String repositoryGroupId, AuditInformation auditInformation )
159 throws RepositoryAdminException
160 {
161
162 org.apache.archiva.repository.RepositoryGroup repositoryGroup = repositoryRegistry.getRepositoryGroup(repositoryGroupId);
163 try {
164 repositoryRegistry.removeRepositoryGroup(repositoryGroup);
165 } catch (RepositoryException e) {
166 log.error("Removal of repository group {} failed: {}", repositoryGroup.getId(), e.getMessage(), e);
167 throw new RepositoryAdminException("Removal of repository failed: " + e.getMessage(), e);
168 }
169 mergedRemoteIndexesScheduler.unschedule(
170 repositoryGroup );
171 triggerAuditEvent( repositoryGroupId, null, AuditEvent.DELETE_REPO_GROUP, auditInformation );
172
173 return Boolean.TRUE;
174 }
175
176 @Override
177 public Boolean updateRepositoryGroup( RepositoryGroup repositoryGroup, AuditInformation auditInformation )
178 throws RepositoryAdminException
179 {
180 return updateRepositoryGroup( repositoryGroup, auditInformation, true );
181 }
182
183 private Boolean updateRepositoryGroup( RepositoryGroup repositoryGroup, AuditInformation auditInformation,
184 boolean triggerAuditEvent )
185 throws RepositoryAdminException
186 {
187 validateRepositoryGroup( repositoryGroup, true );
188 validateManagedRepositoriesExists( repositoryGroup.getRepositories() );
189
190
191 Configuration configuration = getArchivaConfiguration().getConfiguration();
192
193 RepositoryGroupConfiguration repositoryGroupConfiguration =
194 configuration.getRepositoryGroupsAsMap().get( repositoryGroup.getId() );
195
196 repositoryGroupConfiguration.setRepositories( repositoryGroup.getRepositories() );
197 repositoryGroupConfiguration.setMergedIndexPath( repositoryGroup.getMergedIndexPath() );
198 repositoryGroupConfiguration.setMergedIndexTtl( repositoryGroup.getMergedIndexTtl() );
199 repositoryGroupConfiguration.setCronExpression( repositoryGroup.getCronExpression() );
200 try {
201 repositoryRegistry.putRepositoryGroup(repositoryGroupConfiguration);
202 } catch (RepositoryException e) {
203 e.printStackTrace();
204 }
205
206 org.apache.archiva.repository.RepositoryGroup rg = repositoryRegistry.getRepositoryGroup( repositoryGroup.getId( ) );
207 mergedRemoteIndexesScheduler.unschedule( rg );
208 mergedRemoteIndexesScheduler.schedule( rg, getMergedIndexDirectory( repositoryGroup.getId() ) );
209 triggerAuditEvent( repositoryGroup.getId(), null, AuditEvent.MODIFY_REPO_GROUP, auditInformation );
210 return Boolean.TRUE;
211 }
212
213
214 @Override
215 public Boolean addRepositoryToGroup( String repositoryGroupId, String repositoryId,
216 AuditInformation auditInformation )
217 throws RepositoryAdminException
218 {
219 org.apache.archiva.repository.RepositoryGroup repositoryGroup = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
220 if ( repositoryGroup == null )
221 {
222 throw new RepositoryAdminException(
223 "repositoryGroup with id " + repositoryGroupId + " doesn't not exists so cannot add repository to it" );
224 }
225
226 if (!(repositoryGroup instanceof EditableRepositoryGroup)) {
227 throw new RepositoryAdminException("The repository group is not editable "+repositoryGroupId);
228 }
229 EditableRepositoryGroupva/repository/EditableRepositoryGroup.html#EditableRepositoryGroup">EditableRepositoryGroup editableRepositoryGroup = (EditableRepositoryGroup) repositoryGroup;
230 if ( editableRepositoryGroup.getRepositories().stream().anyMatch( repo -> repositoryId.equals(repo.getId())) )
231 {
232 throw new RepositoryAdminException(
233 "repositoryGroup with id " + repositoryGroupId + " already contain repository with id" + repositoryId );
234 }
235 org.apache.archiva.repository.ManagedRepository managedRepo = repositoryRegistry.getManagedRepository(repositoryId);
236 if (managedRepo==null) {
237 throw new RepositoryAdminException("Repository with id "+repositoryId+" does not exist" );
238 }
239
240 editableRepositoryGroup.addRepository( managedRepo );
241 try {
242 repositoryRegistry.putRepositoryGroup(editableRepositoryGroup);
243 } catch (RepositoryException e) {
244 throw new RepositoryAdminException("Could not store the repository group "+repositoryGroupId, e);
245 }
246 triggerAuditEvent( repositoryGroup.getId(), null, AuditEvent.ADD_REPO_TO_GROUP, auditInformation );
247 return Boolean.TRUE;
248 }
249
250 @Override
251 public Boolean deleteRepositoryFromGroup( String repositoryGroupId, String repositoryId,
252 AuditInformation auditInformation )
253 throws RepositoryAdminException
254 {
255 org.apache.archiva.repository.RepositoryGroup repositoryGroup = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
256 if ( repositoryGroup == null )
257 {
258 throw new RepositoryAdminException( "repositoryGroup with id " + repositoryGroupId
259 + " doesn't not exists so cannot remove repository from it" );
260 }
261
262 if ( !repositoryGroup.getRepositories().stream().anyMatch( repo -> repositoryId.equals(repo.getId()) ) )
263 {
264 throw new RepositoryAdminException(
265 "repositoryGroup with id " + repositoryGroupId + " doesn't not contains repository with id"
266 + repositoryId
267 );
268 }
269 if (!(repositoryGroup instanceof EditableRepositoryGroup)) {
270 throw new RepositoryAdminException("Repository group is not editable " + repositoryGroupId);
271 }
272 EditableRepositoryGroupva/repository/EditableRepositoryGroup.html#EditableRepositoryGroup">EditableRepositoryGroup editableRepositoryGroup = (EditableRepositoryGroup) repositoryGroup;
273
274 editableRepositoryGroup.removeRepository( repositoryId );
275 try {
276 repositoryRegistry.putRepositoryGroup(editableRepositoryGroup);
277 } catch (RepositoryException e) {
278 throw new RepositoryAdminException("Could not store repository group " + repositoryGroupId, e);
279 }
280 triggerAuditEvent( repositoryGroup.getId(), null, AuditEvent.DELETE_REPO_FROM_GROUP, auditInformation );
281 return Boolean.TRUE;
282 }
283
284 @Override
285 public Map<String, RepositoryGroup> getRepositoryGroupsAsMap()
286 throws RepositoryAdminException
287 {
288 List<RepositoryGroup> repositoriesGroups = getRepositoriesGroups();
289 Map<String, RepositoryGroup> map = new HashMap<>( repositoriesGroups.size() );
290 for ( RepositoryGroup repositoryGroup : repositoriesGroups )
291 {
292 map.put( repositoryGroup.getId(), repositoryGroup );
293 }
294 return map;
295 }
296
297 @Override
298 public Map<String, List<String>> getGroupToRepositoryMap()
299 throws RepositoryAdminException
300 {
301
302 Map<String, List<String>> map = new HashMap<>();
303
304 for ( ManagedRepository repo : getManagedRepositoryAdmin().getManagedRepositories() )
305 {
306 for ( RepositoryGroup group : getRepositoriesGroups() )
307 {
308 if ( !group.getRepositories().contains( repo.getId() ) )
309 {
310 String groupId = group.getId();
311 List<String> repos = map.get( groupId );
312 if ( repos == null )
313 {
314 repos = new ArrayList<>();
315 map.put( groupId, repos );
316 }
317 repos.add( repo.getId() );
318 }
319 }
320 }
321 return map;
322 }
323
324 @Override
325 public Map<String, List<String>> getRepositoryToGroupMap()
326 throws RepositoryAdminException
327 {
328 Map<String, List<String>> map = new HashMap<>();
329
330 for ( RepositoryGroup group : getRepositoriesGroups() )
331 {
332 for ( String repositoryId : group.getRepositories() )
333 {
334 List<String> groups = map.get( repositoryId );
335 if ( groups == null )
336 {
337 groups = new ArrayList<>();
338 map.put( repositoryId, groups );
339 }
340 groups.add( group.getId() );
341 }
342 }
343 return map;
344 }
345
346 public Boolean validateRepositoryGroup( RepositoryGroup repositoryGroup, boolean updateMode )
347 throws RepositoryAdminException
348 {
349 String repoGroupId = repositoryGroup.getId();
350 if ( StringUtils.isBlank( repoGroupId ) )
351 {
352 throw new RepositoryAdminException( "repositoryGroup id cannot be empty" );
353 }
354
355 if ( repoGroupId.length() > 100 )
356 {
357 throw new RepositoryAdminException(
358 "Identifier [" + repoGroupId + "] is over the maximum limit of 100 characters" );
359
360 }
361
362 Matcher matcher = REPO_GROUP_ID_PATTERN.matcher( repoGroupId );
363 if ( !matcher.matches() )
364 {
365 throw new RepositoryAdminException(
366 "Invalid character(s) found in identifier. Only the following characters are allowed: alphanumeric, '.', '-' and '_'" );
367 }
368
369 if ( repositoryGroup.getMergedIndexTtl() <= 0 )
370 {
371 throw new RepositoryAdminException( "Merged Index TTL must be greater than 0." );
372 }
373
374 Configuration configuration = getArchivaConfiguration().getConfiguration();
375
376 if ( configuration.getRepositoryGroupsAsMap().containsKey( repoGroupId ) )
377 {
378 if ( !updateMode )
379 {
380 throw new RepositoryAdminException( "Unable to add new repository group with id [" + repoGroupId
381 + "], that id already exists as a repository group." );
382 }
383 }
384 else if ( configuration.getManagedRepositoriesAsMap().containsKey( repoGroupId ) )
385 {
386 throw new RepositoryAdminException( "Unable to add new repository group with id [" + repoGroupId
387 + "], that id already exists as a managed repository." );
388 }
389 else if ( configuration.getRemoteRepositoriesAsMap().containsKey( repoGroupId ) )
390 {
391 throw new RepositoryAdminException( "Unable to add new repository group with id [" + repoGroupId
392 + "], that id already exists as a remote repository." );
393 }
394
395 return Boolean.TRUE;
396 }
397
398 private void validateManagedRepositoriesExists( List<String> managedRepositoriesIds )
399 throws RepositoryAdminException
400 {
401 for ( String id : managedRepositoriesIds )
402 {
403 if ( getManagedRepositoryAdmin().getManagedRepository( id ) == null )
404 {
405 throw new RepositoryAdminException(
406 "managedRepository with id " + id + " not exists so cannot be used in a repositoryGroup" );
407 }
408 }
409 }
410
411 public ManagedRepositoryAdmin getManagedRepositoryAdmin()
412 {
413 return managedRepositoryAdmin;
414 }
415
416 public void setManagedRepositoryAdmin( ManagedRepositoryAdmin managedRepositoryAdmin )
417 {
418 this.managedRepositoryAdmin = managedRepositoryAdmin;
419 }
420
421 private RepositoryGroup convertRepositoryGroupObject( org.apache.archiva.repository.RepositoryGroup group ) {
422 RepositoryGroupry/RepositoryGroup.html#RepositoryGroup">RepositoryGroup rg = new RepositoryGroup( group.getId( ), group.getRepositories().stream().map(r -> r.getId()).collect( Collectors.toList()) );
423 if (group.supportsFeature( IndexCreationFeature.class ))
424 {
425 IndexCreationFeature indexCreationFeature = group.getFeature( IndexCreationFeature.class ).get();
426 rg.setMergedIndexPath( indexCreationFeature.getIndexPath().getPath() );
427 }
428 rg.setCronExpression( group.getSchedulingDefinition() );
429 rg.setMergedIndexTtl( group.getMergedIndexTTL() );
430 return rg;
431 }
432 }