This project has retired. For details please refer to its
Attic page.
DefaultRepositoriesService xref
1 package org.apache.archiva.rest.services;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.archiva.admin.model.RepositoryAdminException;
23 import org.apache.archiva.admin.model.admin.ArchivaAdministration;
24 import org.apache.archiva.checksum.ChecksumAlgorithm;
25 import org.apache.archiva.checksum.ChecksummedFile;
26 import org.apache.archiva.common.utils.VersionComparator;
27 import org.apache.archiva.common.utils.VersionUtil;
28 import org.apache.archiva.maven2.metadata.MavenMetadataReader;
29 import org.apache.archiva.maven2.model.Artifact;
30 import org.apache.archiva.metadata.model.ArtifactMetadata;
31 import org.apache.archiva.metadata.model.facets.AuditEvent;
32 import org.apache.archiva.metadata.model.maven2.MavenArtifactFacet;
33 import org.apache.archiva.metadata.repository.*;
34 import org.apache.archiva.model.ArchivaRepositoryMetadata;
35 import org.apache.archiva.model.ArtifactReference;
36 import org.apache.archiva.model.VersionedReference;
37 import org.apache.archiva.redback.authentication.AuthenticationResult;
38 import org.apache.archiva.redback.authorization.AuthorizationException;
39 import org.apache.archiva.components.cache.Cache;
40 import org.apache.archiva.components.taskqueue.TaskQueueException;
41 import org.apache.archiva.redback.system.DefaultSecuritySession;
42 import org.apache.archiva.redback.system.SecuritySession;
43 import org.apache.archiva.redback.system.SecuritySystem;
44 import org.apache.archiva.redback.users.User;
45 import org.apache.archiva.redback.users.UserManagerException;
46 import org.apache.archiva.redback.users.UserNotFoundException;
47 import org.apache.archiva.repository.ContentNotFoundException;
48 import org.apache.archiva.repository.ManagedRepository;
49 import org.apache.archiva.repository.ManagedRepositoryContent;
50 import org.apache.archiva.repository.RepositoryException;
51 import org.apache.archiva.repository.RepositoryNotFoundException;
52 import org.apache.archiva.repository.RepositoryRegistry;
53 import org.apache.archiva.repository.storage.RepositoryStorage;
54 import org.apache.archiva.repository.storage.StorageAsset;
55 import org.apache.archiva.repository.storage.StorageUtil;
56 import org.apache.archiva.metadata.audit.RepositoryListener;
57 import org.apache.archiva.repository.metadata.base.MetadataTools;
58 import org.apache.archiva.repository.metadata.RepositoryMetadataException;
59 import org.apache.archiva.repository.metadata.base.RepositoryMetadataWriter;
60 import org.apache.archiva.repository.scanner.RepositoryScanStatistics;
61 import org.apache.archiva.repository.scanner.RepositoryScanner;
62 import org.apache.archiva.repository.scanner.RepositoryScannerException;
63 import org.apache.archiva.repository.scanner.RepositoryScannerInstance;
64 import org.apache.archiva.rest.api.model.ArtifactTransferRequest;
65 import org.apache.archiva.rest.api.model.StringList;
66 import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
67 import org.apache.archiva.rest.api.services.RepositoriesService;
68 import org.apache.archiva.scheduler.ArchivaTaskScheduler;
69 import org.apache.archiva.scheduler.indexing.maven.ArchivaIndexingTaskExecutor;
70 import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask;
71 import org.apache.archiva.scheduler.indexing.DownloadRemoteIndexException;
72 import org.apache.archiva.scheduler.indexing.DownloadRemoteIndexScheduler;
73 import org.apache.archiva.scheduler.repository.model.RepositoryTask;
74 import org.apache.archiva.security.ArchivaSecurityException;
75 import org.apache.archiva.security.common.ArchivaRoleConstants;
76 import org.apache.archiva.xml.XMLException;
77 import org.apache.commons.io.FilenameUtils;
78 import org.apache.commons.lang3.StringUtils;
79 import org.slf4j.Logger;
80 import org.slf4j.LoggerFactory;
81 import org.springframework.beans.factory.annotation.Autowired;
82 import org.springframework.stereotype.Service;
83
84 import javax.inject.Inject;
85 import javax.inject.Named;
86 import javax.ws.rs.core.Response;
87 import java.io.IOException;
88 import java.io.OutputStreamWriter;
89 import java.nio.file.Path;
90 import java.text.DateFormat;
91 import java.text.SimpleDateFormat;
92 import java.util.ArrayList;
93 import java.util.Arrays;
94 import java.util.Calendar;
95 import java.util.Collection;
96 import java.util.Collections;
97 import java.util.Date;
98 import java.util.List;
99 import java.util.Set;
100 import java.util.TimeZone;
101
102
103
104
105
106 @Service("repositoriesService#rest")
107 public class DefaultRepositoriesService
108 extends AbstractRestService
109 implements RepositoriesService
110 {
111 private Logger log = LoggerFactory.getLogger( getClass() );
112
113 @Inject
114 @Named(value = "taskExecutor#indexing")
115 private ArchivaIndexingTaskExecutor archivaIndexingTaskExecutor;
116
117 @Inject
118 private RepositoryRegistry repositoryRegistry;
119
120 @Inject
121 private SecuritySystem securitySystem;
122
123 @Inject
124 @Named(value = "archivaTaskScheduler#repository")
125 private ArchivaTaskScheduler<RepositoryTask> scheduler;
126
127 @Inject
128 private DownloadRemoteIndexScheduler downloadRemoteIndexScheduler;
129
130 @Inject
131 @Named(value = "repositorySessionFactory")
132 protected RepositorySessionFactory repositorySessionFactory;
133
134 @Inject
135 @Autowired(required = false)
136 protected List<RepositoryListener> listeners = new ArrayList<RepositoryListener>();
137
138 @Inject
139 private RepositoryScanner repoScanner;
140
141
142
143
144 @Inject
145 @Named(value = "cache#namespaces")
146 private Cache<String, Collection<String>> namespacesCache;
147
148 private List<ChecksumAlgorithm> algorithms = Arrays.asList(ChecksumAlgorithm.SHA256, ChecksumAlgorithm.SHA1, ChecksumAlgorithm.MD5 );
149
150 @Override
151 public Boolean scanRepository( String repositoryId, boolean fullScan )
152 {
153 return doScanRepository( repositoryId, fullScan );
154 }
155
156 @Override
157 public Boolean alreadyScanning( String repositoryId )
158 {
159
160 if ( repositoryTaskScheduler.isProcessingRepositoryTask( repositoryId ) )
161 {
162 return true;
163 }
164 for ( RepositoryScannerInstance scan : repoScanner.getInProgressScans() )
165 {
166 if ( scan.getRepository().getId().equals( repositoryId ) )
167 {
168 return true;
169 }
170 }
171 return false;
172 }
173
174 @Override
175 public Boolean removeScanningTaskFromQueue( String repositoryId )
176 {
177 RepositoryTaskpository/model/RepositoryTask.html#RepositoryTask">RepositoryTask task = new RepositoryTask();
178 task.setRepositoryId( repositoryId );
179 try
180 {
181 return repositoryTaskScheduler.unQueueTask( task );
182 }
183 catch ( TaskQueueException e )
184 {
185 log.error( "failed to unschedule scanning of repo with id {}", repositoryId, e );
186 return false;
187 }
188 }
189
190 private ManagedRepositoryContent getManagedRepositoryContent(String id) throws RepositoryException
191 {
192 org.apache.archiva.repository.ManagedRepository repo = repositoryRegistry.getManagedRepository( id );
193 if (repo==null) {
194 throw new RepositoryException( "Repository not found "+id );
195 }
196 return repo.getContent();
197 }
198
199 @Override
200 public Boolean scanRepositoryNow( String repositoryId, boolean fullScan )
201 throws ArchivaRestServiceException
202 {
203
204 try
205 {
206
207 org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository( repositoryId );
208
209
210 ArtifactIndexingTask task =
211 new ArtifactIndexingTask( repository, null, ArtifactIndexingTask.Action.FINISH, repository.getIndexingContext() );
212
213 task.setExecuteOnEntireRepo( true );
214 task.setOnlyUpdate( !fullScan );
215
216 archivaIndexingTaskExecutor.executeTask( task );
217
218 scheduler.queueTask( new RepositoryTask( repositoryId, fullScan ) );
219
220 return Boolean.TRUE;
221 }
222 catch ( Exception e )
223 {
224 log.error( e.getMessage(), e );
225 throw new ArchivaRestServiceException( e.getMessage(), e );
226 }
227 }
228
229 @Override
230 public Boolean scheduleDownloadRemoteIndex( String repositoryId, boolean now, boolean fullDownload )
231 throws ArchivaRestServiceException
232 {
233 try
234 {
235 downloadRemoteIndexScheduler.scheduleDownloadRemote( repositoryId, now, fullDownload );
236 }
237 catch ( DownloadRemoteIndexException e )
238 {
239 log.error( e.getMessage(), e );
240 throw new ArchivaRestServiceException( e.getMessage(), e );
241 }
242 return Boolean.TRUE;
243 }
244
245 @Override
246 public Boolean copyArtifact( ArtifactTransferRequest artifactTransferRequest )
247 throws ArchivaRestServiceException
248 {
249
250 String userName = getAuditInformation().getUser().getUsername();
251 if ( StringUtils.isBlank( userName ) )
252 {
253 throw new ArchivaRestServiceException( "copyArtifact call: userName not found", null );
254 }
255
256 if ( StringUtils.isBlank( artifactTransferRequest.getRepositoryId() ) )
257 {
258 throw new ArchivaRestServiceException( "copyArtifact call: sourceRepositoryId cannot be null", null );
259 }
260
261 if ( StringUtils.isBlank( artifactTransferRequest.getTargetRepositoryId() ) )
262 {
263 throw new ArchivaRestServiceException( "copyArtifact call: targetRepositoryId cannot be null", null );
264 }
265
266 ManagedRepository source = null;
267 source = repositoryRegistry.getManagedRepository( artifactTransferRequest.getRepositoryId() );
268
269 if ( source == null )
270 {
271 throw new ArchivaRestServiceException(
272 "cannot find repository with id " + artifactTransferRequest.getRepositoryId(), null );
273 }
274
275 ManagedRepository target = null;
276 target = repositoryRegistry.getManagedRepository( artifactTransferRequest.getTargetRepositoryId() );
277
278 if ( target == null )
279 {
280 throw new ArchivaRestServiceException(
281 "cannot find repository with id " + artifactTransferRequest.getTargetRepositoryId(), null );
282 }
283
284 if ( StringUtils.isBlank( artifactTransferRequest.getGroupId() ) )
285 {
286 throw new ArchivaRestServiceException( "groupId is mandatory", null );
287 }
288
289 if ( StringUtils.isBlank( artifactTransferRequest.getArtifactId() ) )
290 {
291 throw new ArchivaRestServiceException( "artifactId is mandatory", null );
292 }
293
294 if ( StringUtils.isBlank( artifactTransferRequest.getVersion() ) )
295 {
296 throw new ArchivaRestServiceException( "version is mandatory", null );
297 }
298
299 if ( VersionUtil.isSnapshot( artifactTransferRequest.getVersion() ) )
300 {
301 throw new ArchivaRestServiceException( "copy of SNAPSHOT not supported", null );
302 }
303
304
305
306 User user = null;
307 try
308 {
309 user = securitySystem.getUserManager().findUser( userName );
310 }
311 catch ( UserNotFoundException e )
312 {
313 throw new ArchivaRestServiceException( "user " + userName + " not found", e );
314 }
315 catch ( UserManagerException e )
316 {
317 throw new ArchivaRestServiceException( "ArchivaRestServiceException:" + e.getMessage(), e );
318 }
319
320
321 AuthenticationResult authn = new AuthenticationResult( true, userName, null );
322 SecuritySession securitySession = new DefaultSecuritySession( authn, user );
323 try
324 {
325 boolean authz =
326 securitySystem.isAuthorized( securitySession, ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS,
327 artifactTransferRequest.getRepositoryId() );
328 if ( !authz )
329 {
330 throw new ArchivaRestServiceException(
331 "not authorized to access repo:" + artifactTransferRequest.getRepositoryId(), null );
332 }
333 }
334 catch ( AuthorizationException e )
335 {
336 log.error( "error reading permission: {}", e.getMessage(), e );
337 throw new ArchivaRestServiceException( e.getMessage(), e );
338 }
339
340
341 try
342 {
343 boolean authz =
344 securitySystem.isAuthorized( securitySession, ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD,
345 artifactTransferRequest.getTargetRepositoryId() );
346 if ( !authz )
347 {
348 throw new ArchivaRestServiceException(
349 "not authorized to write to repo:" + artifactTransferRequest.getTargetRepositoryId(), null );
350 }
351 }
352 catch ( AuthorizationException e )
353 {
354 log.error( "error reading permission: {}", e.getMessage(), e );
355 throw new ArchivaRestServiceException( e.getMessage(), e );
356 }
357
358
359
360 ArtifactReference#ArtifactReference">ArtifactReference artifactReference = new ArtifactReference();
361 artifactReference.setArtifactId( artifactTransferRequest.getArtifactId() );
362 artifactReference.setGroupId( artifactTransferRequest.getGroupId() );
363 artifactReference.setVersion( artifactTransferRequest.getVersion() );
364 artifactReference.setClassifier( artifactTransferRequest.getClassifier() );
365 String packaging = StringUtils.trim( artifactTransferRequest.getPackaging() );
366 artifactReference.setType( StringUtils.isEmpty( packaging ) ? "jar" : packaging );
367
368 try
369 {
370
371 ManagedRepositoryContent sourceRepository =
372 getManagedRepositoryContent( artifactTransferRequest.getRepositoryId() );
373
374 String artifactSourcePath = sourceRepository.toPath( artifactReference );
375
376 if ( StringUtils.isEmpty( artifactSourcePath ) )
377 {
378 log.error( "cannot find artifact {}", artifactTransferRequest );
379 throw new ArchivaRestServiceException( "cannot find artifact " + artifactTransferRequest.toString(),
380 null );
381 }
382
383 StorageAsset artifactFile = source.getAsset( artifactSourcePath );
384
385 if ( !artifactFile.exists() )
386 {
387 log.error( "cannot find artifact {}", artifactTransferRequest );
388 throw new ArchivaRestServiceException( "cannot find artifact " + artifactTransferRequest.toString(),
389 null );
390 }
391
392 ManagedRepositoryContent targetRepository =
393 getManagedRepositoryContent( artifactTransferRequest.getTargetRepositoryId() );
394
395 String artifactPath = targetRepository.toPath( artifactReference );
396
397 int lastIndex = artifactPath.lastIndexOf( '/' );
398
399 String path = artifactPath.substring( 0, lastIndex );
400 StorageAsset targetDir = target.getAsset( path );
401
402 Date lastUpdatedTimestamp = Calendar.getInstance().getTime();
403 int newBuildNumber = 1;
404 String timestamp = null;
405
406 StorageAsset versionMetadataFile = target.getAsset(path + "/" + MetadataTools.MAVEN_METADATA );
407 getMetadata( versionMetadataFile );
408
409 if ( !targetDir.exists() )
410 {
411 targetDir = target.addAsset(targetDir.getPath(), true);
412 targetDir.create();
413 }
414
415 String filename = artifactPath.substring( lastIndex + 1 );
416
417 boolean fixChecksums =
418 !( archivaAdministration.getKnownContentConsumers().contains( "create-missing-checksums" ) );
419
420 StorageAsset targetFile = target.getAsset(targetDir.getPath() + "/" + filename );
421 if ( targetFile.exists() && target.blocksRedeployments())
422 {
423 throw new ArchivaRestServiceException(
424 "artifact already exists in target repo: " + artifactTransferRequest.getTargetRepositoryId()
425 + " and redeployment blocked", null
426 );
427 }
428 else
429 {
430 copyFile(artifactFile, targetFile, fixChecksums );
431 queueRepositoryTask( target.getId(), targetFile );
432 }
433
434
435 String pomFilename = filename;
436 if ( StringUtils.isNotBlank( artifactTransferRequest.getClassifier() ) )
437 {
438 pomFilename = StringUtils.remove( pomFilename, "-" + artifactTransferRequest.getClassifier() );
439 }
440 pomFilename = FilenameUtils.removeExtension( pomFilename ) + ".pom";
441
442 StorageAsset pomFile = source.getAsset(
443 artifactSourcePath.substring( 0, artifactPath.lastIndexOf( '/' ) )+"/"+ pomFilename );
444
445 if ( pomFile != null && pomFile.exists() )
446 {
447 StorageAsset targetPomFile = target.getAsset( targetDir.getPath() + "/" + pomFilename );
448 copyFile(pomFile, targetPomFile, fixChecksums );
449 queueRepositoryTask( target.getId(), targetPomFile );
450
451
452 }
453
454
455 if ( !archivaAdministration.getKnownContentConsumers().contains( "metadata-updater" ) )
456 {
457 updateProjectMetadata( target, targetDir, lastUpdatedTimestamp, timestamp, newBuildNumber,
458 fixChecksums, artifactTransferRequest );
459
460
461 }
462
463 String msg =
464 "Artifact \'" + artifactTransferRequest.getGroupId() + ":" + artifactTransferRequest.getArtifactId()
465 + ":" + artifactTransferRequest.getVersion() + "\' was successfully deployed to repository \'"
466 + artifactTransferRequest.getTargetRepositoryId() + "\'";
467 log.debug("copyArtifact {}", msg);
468
469 }
470 catch ( RepositoryException e )
471 {
472 log.error( "RepositoryException: {}", e.getMessage(), e );
473 throw new ArchivaRestServiceException( e.getMessage(), e );
474 }
475 catch ( RepositoryAdminException e )
476 {
477 log.error( "RepositoryAdminException: {}", e.getMessage(), e );
478 throw new ArchivaRestServiceException( e.getMessage(), e );
479 }
480 catch ( IOException e )
481 {
482 log.error( "IOException: {}", e.getMessage(), e );
483 throw new ArchivaRestServiceException( e.getMessage(), e );
484 }
485 return true;
486 }
487
488 private void queueRepositoryTask( String repositoryId, StorageAsset localFile )
489 {
490
491 RepositoryTaskpository/model/RepositoryTask.html#RepositoryTask">RepositoryTask task = new RepositoryTask();
492 task.setRepositoryId( repositoryId );
493 task.setResourceFile( localFile );
494 task.setUpdateRelatedArtifacts( true );
495
496
497 try
498 {
499 scheduler.queueTask( task );
500 }
501 catch ( TaskQueueException e )
502 {
503 log.error( "Unable to queue repository task to execute consumers on resource file ['{}"
504 + "'].", localFile.getName());
505 }
506 }
507
508 private ArchivaRepositoryMetadata getMetadata( StorageAsset metadataFile )
509 throws RepositoryMetadataException
510 {
511 ArchivaRepositoryMetadatadata.html#ArchivaRepositoryMetadata">ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
512 if ( metadataFile.exists() )
513 {
514 try
515 {
516 metadata = MavenMetadataReader.read( metadataFile.getFilePath() );
517 }
518 catch (XMLException e )
519 {
520 throw new RepositoryMetadataException( e.getMessage(), e );
521 }
522 }
523 return metadata;
524 }
525
526 private StorageAsset getMetadata( RepositoryStorage storage, String targetPath )
527 {
528 return storage.getAsset( targetPath + "/" + MetadataTools.MAVEN_METADATA );
529
530 }
531
532
533
534
535 private void copyFile(StorageAsset/../../org/apache/archiva/repository/storage/StorageAsset.html#StorageAsset">StorageAsset sourceFile, StorageAsset targetPath, boolean fixChecksums)
536 throws IOException
537 {
538
539 StorageUtil.copyAsset( sourceFile, targetPath, true );
540 if ( fixChecksums )
541 {
542 fixChecksums( targetPath );
543 }
544 }
545
546 private void fixChecksums( StorageAsset file )
547 {
548 Path destinationFile = file.getFilePath();
549 if (destinationFile!=null)
550 {
551 ChecksummedFilemedFile.html#ChecksummedFile">ChecksummedFile checksum = new ChecksummedFile( destinationFile );
552 checksum.fixChecksums( algorithms );
553 }
554 }
555
556 private void updateProjectMetadata( RepositoryStorage storage, StorageAsset targetPath, Date lastUpdatedTimestamp, String timestamp, int buildNumber,
557 boolean fixChecksums, ArtifactTransferRequest artifactTransferRequest )
558 throws RepositoryMetadataException
559 {
560 List<String> availableVersions = new ArrayList<>();
561 String latestVersion = artifactTransferRequest.getVersion();
562
563 StorageAsset projectDir = targetPath.getParent();
564 StorageAsset projectMetadataFile = storage.getAsset( projectDir.getPath()+"/"+MetadataTools.MAVEN_METADATA );
565
566 ArchivaRepositoryMetadata projectMetadata = getMetadata( projectMetadataFile );
567
568 if ( projectMetadataFile.exists() )
569 {
570 availableVersions = projectMetadata.getAvailableVersions();
571
572 Collections.sort( availableVersions, VersionComparator.getInstance() );
573
574 if ( !availableVersions.contains( artifactTransferRequest.getVersion() ) )
575 {
576 availableVersions.add( artifactTransferRequest.getVersion() );
577 }
578
579 latestVersion = availableVersions.get( availableVersions.size() - 1 );
580 }
581 else
582 {
583 availableVersions.add( artifactTransferRequest.getVersion() );
584
585 projectMetadata.setGroupId( artifactTransferRequest.getGroupId() );
586 projectMetadata.setArtifactId( artifactTransferRequest.getArtifactId() );
587 }
588
589 if ( projectMetadata.getGroupId() == null )
590 {
591 projectMetadata.setGroupId( artifactTransferRequest.getGroupId() );
592 }
593
594 if ( projectMetadata.getArtifactId() == null )
595 {
596 projectMetadata.setArtifactId( artifactTransferRequest.getArtifactId() );
597 }
598
599 projectMetadata.setLatestVersion( latestVersion );
600 projectMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
601 projectMetadata.setAvailableVersions( availableVersions );
602
603 if ( !VersionUtil.isSnapshot( artifactTransferRequest.getVersion() ) )
604 {
605 projectMetadata.setReleasedVersion( latestVersion );
606 }
607
608 try(OutputStreamWriter writer = new OutputStreamWriter(projectMetadataFile.getWriteStream(true))) {
609 RepositoryMetadataWriter.write(projectMetadata, writer);
610 } catch (IOException e) {
611 throw new RepositoryMetadataException(e);
612 }
613
614 if ( fixChecksums )
615 {
616 fixChecksums( projectMetadataFile );
617 }
618 }
619
620 @Override
621 public Boolean removeProjectVersion( String repositoryId, String namespace, String projectId, String version )
622 throws ArchivaRestServiceException
623 {
624
625 if ( !VersionUtil.isGenericSnapshot( version ) )
626 {
627 Artifactel/Artifact.html#Artifact">Artifact artifact = new Artifact( namespace, projectId, version );
628 artifact.setRepositoryId( repositoryId );
629 artifact.setContext( repositoryId );
630 return deleteArtifact( artifact );
631 }
632
633 if ( StringUtils.isEmpty( repositoryId ) )
634 {
635 throw new ArchivaRestServiceException( "repositoryId cannot be null", 400, null );
636 }
637
638 if ( !isAuthorizedToDeleteArtifacts( repositoryId ) )
639 {
640 throw new ArchivaRestServiceException( "not authorized to delete artifacts", 403, null );
641 }
642
643 if ( StringUtils.isEmpty( namespace ) )
644 {
645 throw new ArchivaRestServiceException( "groupId cannot be null", 400, null );
646 }
647
648 if ( StringUtils.isEmpty( projectId ) )
649 {
650 throw new ArchivaRestServiceException( "artifactId cannot be null", 400, null );
651 }
652
653 if ( StringUtils.isEmpty( version ) )
654 {
655 throw new ArchivaRestServiceException( "version cannot be null", 400, null );
656 }
657
658 RepositorySession repositorySession = null;
659 try
660 {
661 repositorySession = repositorySessionFactory.createSession();
662 }
663 catch ( MetadataRepositoryException e )
664 {
665 e.printStackTrace( );
666 }
667
668 try
669 {
670 ManagedRepositoryContent repository = getManagedRepositoryContent( repositoryId );
671
672 VersionedReferenceReference.html#VersionedReference">VersionedReference ref = new VersionedReference();
673 ref.setArtifactId( projectId );
674 ref.setGroupId( namespace );
675 ref.setVersion( version );
676
677 repository.deleteVersion( ref );
678
679
680
681
682
683
684
685
686
687 ArtifactReference#ArtifactReference">ArtifactReference artifactReference = new ArtifactReference();
688 artifactReference.setGroupId( namespace );
689 artifactReference.setArtifactId( projectId );
690 artifactReference.setVersion( version );
691
692 MetadataRepository metadataRepository = repositorySession.getRepository();
693
694 Set<ArtifactReference> related = repository.getRelatedArtifacts( artifactReference );
695 log.debug( "related: {}", related );
696 for ( ArtifactReference artifactRef : related )
697 {
698 repository.deleteArtifact( artifactRef );
699 }
700
701 Collection<ArtifactMetadata> artifacts =
702 metadataRepository.getArtifacts(repositorySession , repositoryId, namespace, projectId, version );
703
704 for ( ArtifactMetadata artifactMetadata : artifacts )
705 {
706 metadataRepository.removeTimestampedArtifact(repositorySession , artifactMetadata, version );
707 }
708
709 metadataRepository.removeProjectVersion(repositorySession , repositoryId, namespace, projectId, version );
710 }
711 catch ( MetadataRepositoryException e )
712 {
713 throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
714 }
715 catch ( MetadataResolutionException e )
716 {
717 throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
718 }
719 catch ( RepositoryException e )
720 {
721 throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
722 }
723 finally
724 {
725
726 try {
727 repositorySession.save();
728 } catch (MetadataSessionException e) {
729 log.error("Session save failed {}", e.getMessage());
730 }
731
732 repositorySession.close();
733 }
734
735 return Boolean.TRUE;
736 }
737
738 @Override
739 public Boolean deleteArtifact( Artifact artifact )
740 throws ArchivaRestServiceException
741 {
742
743 String repositoryId = artifact.getContext();
744
745
746 if ( StringUtils.isEmpty( repositoryId ) )
747 {
748 repositoryId = artifact.getRepositoryId();
749 }
750 if ( StringUtils.isEmpty( repositoryId ) )
751 {
752 throw new ArchivaRestServiceException( "repositoryId cannot be null", 400, null );
753 }
754
755 if ( !isAuthorizedToDeleteArtifacts( repositoryId ) )
756 {
757 throw new ArchivaRestServiceException( "not authorized to delete artifacts", 403, null );
758 }
759
760 if ( artifact == null )
761 {
762 throw new ArchivaRestServiceException( "artifact cannot be null", 400, null );
763 }
764
765 if ( StringUtils.isEmpty( artifact.getGroupId() ) )
766 {
767 throw new ArchivaRestServiceException( "artifact.groupId cannot be null", 400, null );
768 }
769
770 if ( StringUtils.isEmpty( artifact.getArtifactId() ) )
771 {
772 throw new ArchivaRestServiceException( "artifact.artifactId cannot be null", 400, null );
773 }
774
775
776
777 boolean snapshotVersion =
778 VersionUtil.isSnapshot( artifact.getVersion() ) | VersionUtil.isGenericSnapshot( artifact.getVersion() );
779
780 RepositorySession repositorySession = null;
781 try
782 {
783 repositorySession = repositorySessionFactory.createSession();
784 }
785 catch ( MetadataRepositoryException e )
786 {
787 e.printStackTrace( );
788 }
789 try
790 {
791 Date lastUpdatedTimestamp = Calendar.getInstance().getTime();
792
793 TimeZone timezone = TimeZone.getTimeZone( "UTC" );
794 DateFormat fmt = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
795 fmt.setTimeZone( timezone );
796 ManagedRepository repo = repositoryRegistry.getManagedRepository( repositoryId );
797
798 VersionedReferenceReference.html#VersionedReference">VersionedReference ref = new VersionedReference();
799 ref.setArtifactId( artifact.getArtifactId() );
800 ref.setGroupId( artifact.getGroupId() );
801 ref.setVersion( artifact.getVersion() );
802
803 ManagedRepositoryContent repository = getManagedRepositoryContent( repositoryId );
804
805 ArtifactReference#ArtifactReference">ArtifactReference artifactReference = new ArtifactReference();
806 artifactReference.setArtifactId( artifact.getArtifactId() );
807 artifactReference.setGroupId( artifact.getGroupId() );
808 artifactReference.setVersion( artifact.getVersion() );
809 artifactReference.setClassifier( artifact.getClassifier() );
810 artifactReference.setType( artifact.getPackaging() );
811
812 MetadataRepository metadataRepository = repositorySession.getRepository();
813
814 String path = repository.toMetadataPath( ref );
815
816 if ( StringUtils.isNotBlank( artifact.getClassifier() ) )
817 {
818 if ( StringUtils.isBlank( artifact.getPackaging() ) )
819 {
820 throw new ArchivaRestServiceException( "You must configure a type/packaging when using classifier",
821 400, null );
822 }
823
824 repository.deleteArtifact( artifactReference );
825
826 }
827 else
828 {
829
830 int index = path.lastIndexOf( '/' );
831 path = path.substring( 0, index );
832 StorageAsset targetPath = repo.getAsset( path );
833
834 if ( !targetPath.exists() )
835 {
836
837
838 log.warn( "targetPath {} not found skip file deletion", targetPath );
839 return false;
840 }
841
842
843
844 if ( !snapshotVersion )
845 {
846 repository.deleteVersion( ref );
847 }
848 else
849 {
850 Set<ArtifactReference> related = repository.getRelatedArtifacts( artifactReference );
851 log.debug( "related: {}", related );
852 for ( ArtifactReference artifactRef : related )
853 {
854 repository.deleteArtifact( artifactRef );
855 }
856 StorageAsset metadataFile = getMetadata( repo, targetPath.getPath() );
857 ArchivaRepositoryMetadata metadata = getMetadata( metadataFile );
858
859 updateMetadata( metadata, metadataFile, lastUpdatedTimestamp, artifact );
860 }
861 }
862 Collection<ArtifactMetadata> artifacts = Collections.emptyList();
863
864 if ( snapshotVersion )
865 {
866 String baseVersion = VersionUtil.getBaseVersion( artifact.getVersion() );
867 artifacts =
868 metadataRepository.getArtifacts(repositorySession , repositoryId, artifact.getGroupId(),
869 artifact.getArtifactId(), baseVersion );
870 }
871 else
872 {
873 artifacts =
874 metadataRepository.getArtifacts(repositorySession , repositoryId, artifact.getGroupId(),
875 artifact.getArtifactId(), artifact.getVersion() );
876 }
877
878 log.debug( "artifacts: {}", artifacts );
879
880 if ( artifacts.isEmpty() )
881 {
882 if ( !snapshotVersion )
883 {
884
885 Collection<String> projectVersions =
886 metadataRepository.getProjectVersions(repositorySession , repositoryId,
887 artifact.getGroupId(), artifact.getArtifactId() );
888
889 if ( projectVersions.contains( artifact.getVersion() ) )
890 {
891 log.warn( "artifact not found when deleted but version still here ! so force cleanup" );
892 metadataRepository.removeProjectVersion(repositorySession , repositoryId,
893 artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() );
894 }
895
896 }
897 }
898
899 for ( ArtifactMetadata artifactMetadata : artifacts )
900 {
901
902
903 if ( artifactMetadata.getVersion().equals( artifact.getVersion() ) )
904 {
905 if ( StringUtils.isNotBlank( artifact.getClassifier() ) )
906 {
907 if ( StringUtils.isBlank( artifact.getPackaging() ) )
908 {
909 throw new ArchivaRestServiceException(
910 "You must configure a type/packaging when using classifier", 400, null );
911 }
912
913 MavenArtifactFacet mavenArtifactFacet =
914 (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID );
915
916 if ( StringUtils.equals( artifact.getClassifier(), mavenArtifactFacet.getClassifier() ) )
917 {
918 artifactMetadata.removeFacet( MavenArtifactFacet.FACET_ID );
919 String groupId = artifact.getGroupId(), artifactId = artifact.getArtifactId(), version =
920 artifact.getVersion();
921 MavenArtifactFacett.html#MavenArtifactFacet">MavenArtifactFacet mavenArtifactFacetToCompare = new MavenArtifactFacet();
922 mavenArtifactFacetToCompare.setClassifier( artifact.getClassifier() );
923 metadataRepository.removeFacetFromArtifact(repositorySession , repositoryId, groupId, artifactId,
924 version, mavenArtifactFacetToCompare );
925 repositorySession.save();
926 }
927
928 }
929 else
930 {
931 if ( snapshotVersion )
932 {
933 metadataRepository.removeTimestampedArtifact(repositorySession ,
934 artifactMetadata, VersionUtil.getBaseVersion( artifact.getVersion() ) );
935 }
936 else
937 {
938 metadataRepository.removeArtifact(repositorySession ,
939 artifactMetadata.getRepositoryId(),
940 artifactMetadata.getNamespace(), artifactMetadata.getProject(),
941 artifact.getVersion(), artifactMetadata.getId() );
942 }
943 }
944
945
946 for ( RepositoryListener listener : listeners )
947 {
948 listener.deleteArtifact( metadataRepository, repository.getId(),
949 artifactMetadata.getNamespace(), artifactMetadata.getProject(),
950 artifactMetadata.getVersion(), artifactMetadata.getId() );
951 }
952
953 triggerAuditEvent( repositoryId, path, AuditEvent.REMOVE_FILE );
954 }
955 }
956 }
957 catch ( ContentNotFoundException e )
958 {
959 throw new ArchivaRestServiceException( "Artifact does not exist: " + e.getMessage(), 400, e );
960 }
961 catch ( RepositoryNotFoundException e )
962 {
963 throw new ArchivaRestServiceException( "Target repository cannot be found: " + e.getMessage(), 400, e );
964 }
965 catch ( RepositoryException e )
966 {
967 throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
968 }
969 catch (MetadataResolutionException | MetadataSessionException e )
970 {
971 throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
972 }
973 catch ( MetadataRepositoryException e )
974 {
975 throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
976 }
977 finally
978 {
979
980 try {
981 repositorySession.save();
982 } catch (MetadataSessionException e) {
983 log.error("Could not save sesion {}", e.getMessage());
984 }
985
986 repositorySession.close();
987 }
988 return Boolean.TRUE;
989 }
990
991 @Override
992 public Boolean deleteGroupId( String groupId, String repositoryId )
993 throws ArchivaRestServiceException
994 {
995 if ( StringUtils.isEmpty( repositoryId ) )
996 {
997 throw new ArchivaRestServiceException( "repositoryId cannot be null", 400, null );
998 }
999
1000 if ( !isAuthorizedToDeleteArtifacts( repositoryId ) )
1001 {
1002 throw new ArchivaRestServiceException( "not authorized to delete artifacts", 403, null );
1003 }
1004
1005 if ( StringUtils.isEmpty( groupId ) )
1006 {
1007 throw new ArchivaRestServiceException( "groupId cannot be null", 400, null );
1008 }
1009
1010 RepositorySession repositorySession = null;
1011 try
1012 {
1013 repositorySession = repositorySessionFactory.createSession();
1014 }
1015 catch ( MetadataRepositoryException e )
1016 {
1017 e.printStackTrace( );
1018 }
1019
1020 try
1021 {
1022 ManagedRepositoryContent repository = getManagedRepositoryContent( repositoryId );
1023
1024 repository.deleteGroupId( groupId );
1025
1026 MetadataRepository metadataRepository = repositorySession.getRepository();
1027
1028 metadataRepository.removeNamespace(repositorySession , repositoryId, groupId );
1029
1030
1031 String cacheKey = repositoryId + "-" + groupId;
1032 namespacesCache.remove( cacheKey );
1033 namespacesCache.remove( repositoryId );
1034
1035 repositorySession.save();
1036 }
1037 catch (MetadataRepositoryException | MetadataSessionException e )
1038 {
1039 log.error( e.getMessage(), e );
1040 throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
1041 }
1042 catch ( RepositoryException e )
1043 {
1044 log.error( e.getMessage(), e );
1045 throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
1046 }
1047 finally
1048 {
1049
1050 repositorySession.close();
1051 }
1052 return true;
1053 }
1054
1055 @Override
1056 public Boolean deleteProject( String groupId, String projectId, String repositoryId )
1057 throws ArchivaRestServiceException
1058 {
1059 if ( StringUtils.isEmpty( repositoryId ) )
1060 {
1061 throw new ArchivaRestServiceException( "repositoryId cannot be null", 400, null );
1062 }
1063
1064 if ( !isAuthorizedToDeleteArtifacts( repositoryId ) )
1065 {
1066 throw new ArchivaRestServiceException( "not authorized to delete artifacts", 403, null );
1067 }
1068
1069 if ( StringUtils.isEmpty( groupId ) )
1070 {
1071 throw new ArchivaRestServiceException( "groupId cannot be null", 400, null );
1072 }
1073
1074 if ( StringUtils.isEmpty( projectId ) )
1075 {
1076 throw new ArchivaRestServiceException( "artifactId cannot be null", 400, null );
1077 }
1078
1079 RepositorySession repositorySession = null;
1080 try
1081 {
1082 repositorySession = repositorySessionFactory.createSession();
1083 }
1084 catch ( MetadataRepositoryException e )
1085 {
1086 e.printStackTrace( );
1087 }
1088
1089 try
1090 {
1091 ManagedRepositoryContent repository = getManagedRepositoryContent( repositoryId );
1092
1093 repository.deleteProject( groupId, projectId );
1094 }
1095 catch ( ContentNotFoundException e )
1096 {
1097 log.warn( "skip ContentNotFoundException: {}", e.getMessage() );
1098 }
1099 catch ( RepositoryException e )
1100 {
1101 log.error( e.getMessage(), e );
1102 throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
1103 }
1104
1105 try
1106 {
1107
1108 MetadataRepository metadataRepository = repositorySession.getRepository();
1109
1110 metadataRepository.removeProject(repositorySession , repositoryId, groupId, projectId );
1111
1112 repositorySession.save();
1113 }
1114 catch (MetadataRepositoryException | MetadataSessionException e )
1115 {
1116 log.error( e.getMessage(), e );
1117 throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
1118 }
1119 finally
1120 {
1121
1122 repositorySession.close();
1123 }
1124 return true;
1125
1126 }
1127
1128 @Override
1129 public Boolean isAuthorizedToDeleteArtifacts( String repoId )
1130 throws ArchivaRestServiceException
1131 {
1132 String userName =
1133 getAuditInformation().getUser() == null ? "guest" : getAuditInformation().getUser().getUsername();
1134
1135 try
1136 {
1137 return userRepositories.isAuthorizedToDeleteArtifacts( userName, repoId );
1138 }
1139 catch ( ArchivaSecurityException e )
1140 {
1141 throw new ArchivaRestServiceException( e.getMessage(),
1142 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
1143 }
1144 }
1145
1146 @Override
1147 public RepositoryScanStatistics scanRepositoryDirectoriesNow( String repositoryId )
1148 throws ArchivaRestServiceException
1149 {
1150 long sinceWhen = RepositoryScanner.FRESH_SCAN;
1151 try
1152 {
1153 return repoScanner.scan( repositoryRegistry.getManagedRepository( repositoryId ), sinceWhen );
1154 }
1155 catch ( RepositoryScannerException e )
1156 {
1157 log.error( e.getMessage(), e );
1158 throw new ArchivaRestServiceException( "RepositoryScannerException exception: " + e.getMessage(), 500, e );
1159 }
1160 }
1161
1162
1163
1164
1165
1166
1167 private void updateMetadata( ArchivaRepositoryMetadata metadata, StorageAsset metadataFile, Date lastUpdatedTimestamp,
1168 Artifact artifact )
1169 throws RepositoryMetadataException
1170 {
1171 List<String> availableVersions = new ArrayList<>();
1172 String latestVersion = "";
1173
1174 if ( metadataFile.exists() )
1175 {
1176 if ( metadata.getAvailableVersions() != null )
1177 {
1178 availableVersions = metadata.getAvailableVersions();
1179
1180 if ( availableVersions.size() > 0 )
1181 {
1182 Collections.sort( availableVersions, VersionComparator.getInstance() );
1183
1184 if ( availableVersions.contains( artifact.getVersion() ) )
1185 {
1186 availableVersions.remove( availableVersions.indexOf( artifact.getVersion() ) );
1187 }
1188 if ( availableVersions.size() > 0 )
1189 {
1190 latestVersion = availableVersions.get( availableVersions.size() - 1 );
1191 }
1192 }
1193 }
1194 }
1195
1196 if ( metadata.getGroupId() == null )
1197 {
1198 metadata.setGroupId( artifact.getGroupId() );
1199 }
1200 if ( metadata.getArtifactId() == null )
1201 {
1202 metadata.setArtifactId( artifact.getArtifactId() );
1203 }
1204
1205 if ( !VersionUtil.isSnapshot( artifact.getVersion() ) )
1206 {
1207 if ( metadata.getReleasedVersion() != null && metadata.getReleasedVersion().equals(
1208 artifact.getVersion() ) )
1209 {
1210 metadata.setReleasedVersion( latestVersion );
1211 }
1212 }
1213
1214 metadata.setLatestVersion( latestVersion );
1215 metadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
1216 metadata.setAvailableVersions( availableVersions );
1217
1218 try (OutputStreamWriter writer = new OutputStreamWriter(metadataFile.getWriteStream(true))) {
1219 RepositoryMetadataWriter.write(metadata, writer);
1220 } catch (IOException e) {
1221 throw new RepositoryMetadataException(e);
1222 }
1223 ChecksummedFilemedFile.html#ChecksummedFile">ChecksummedFile checksum = new ChecksummedFile( metadataFile.getFilePath() );
1224 checksum.fixChecksums( algorithms );
1225 }
1226
1227 @Override
1228 public StringList getRunningRemoteDownloadIds()
1229 {
1230 return new StringList( downloadRemoteIndexScheduler.getRunningRemoteDownloadIds() );
1231 }
1232
1233 public RepositorySessionFactory getRepositorySessionFactory()
1234 {
1235 return repositorySessionFactory;
1236 }
1237
1238 public void setRepositorySessionFactory( RepositorySessionFactory repositorySessionFactory )
1239 {
1240 this.repositorySessionFactory = repositorySessionFactory;
1241 }
1242
1243 public List<RepositoryListener> getListeners()
1244 {
1245 return listeners;
1246 }
1247
1248 public void setListeners( List<RepositoryListener> listeners )
1249 {
1250 this.listeners = listeners;
1251 }
1252
1253 public ArchivaAdministration getArchivaAdministration()
1254 {
1255 return archivaAdministration;
1256 }
1257
1258 public void setArchivaAdministration( ArchivaAdministration archivaAdministration )
1259 {
1260 this.archivaAdministration = archivaAdministration;
1261 }
1262 }
1263
1264