You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DefaultRepositoriesService.java 49KB

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