Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

AbstractRestService.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  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.AuditInformation;
  21. import org.apache.archiva.admin.model.RepositoryAdminException;
  22. import org.apache.archiva.admin.model.admin.ArchivaAdministration;
  23. import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
  24. import org.apache.archiva.audit.AuditEvent;
  25. import org.apache.archiva.audit.AuditListener;
  26. import org.apache.archiva.common.utils.VersionUtil;
  27. import org.apache.archiva.indexer.search.SearchResultHit;
  28. import org.apache.archiva.maven2.model.Artifact;
  29. import org.apache.archiva.metadata.model.ArtifactMetadata;
  30. import org.apache.archiva.metadata.repository.RepositorySessionFactory;
  31. import org.apache.archiva.redback.components.taskqueue.TaskQueueException;
  32. import org.apache.archiva.redback.configuration.UserConfiguration;
  33. import org.apache.archiva.redback.configuration.UserConfigurationKeys;
  34. import org.apache.archiva.redback.rest.services.RedbackAuthenticationThreadLocal;
  35. import org.apache.archiva.redback.rest.services.RedbackRequestInformation;
  36. import org.apache.archiva.redback.users.User;
  37. import org.apache.archiva.repository.RepositoryContentFactory;
  38. import org.apache.archiva.repository.RepositoryException;
  39. import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
  40. import org.apache.archiva.rest.services.utils.ArtifactBuilder;
  41. import org.apache.archiva.scheduler.repository.DefaultRepositoryArchivaTaskScheduler;
  42. import org.apache.archiva.scheduler.repository.model.RepositoryTask;
  43. import org.apache.archiva.security.AccessDeniedException;
  44. import org.apache.archiva.security.ArchivaSecurityException;
  45. import org.apache.archiva.security.PrincipalNotFoundException;
  46. import org.apache.archiva.security.UserRepositories;
  47. import org.apache.commons.lang.StringUtils;
  48. import org.modelmapper.ModelMapper;
  49. import org.modelmapper.PropertyMap;
  50. import org.modelmapper.convention.MatchingStrategies;
  51. import org.slf4j.Logger;
  52. import org.slf4j.LoggerFactory;
  53. import org.springframework.context.ApplicationContext;
  54. import javax.inject.Inject;
  55. import javax.inject.Named;
  56. import javax.servlet.http.HttpServletRequest;
  57. import javax.ws.rs.core.Context;
  58. import javax.ws.rs.core.Response;
  59. import java.util.ArrayList;
  60. import java.util.Collections;
  61. import java.util.HashMap;
  62. import java.util.List;
  63. import java.util.Map;
  64. /**
  65. * abstract class with common utilities methods
  66. *
  67. * @author Olivier Lamy
  68. * @since 1.4-M1
  69. */
  70. public abstract class AbstractRestService
  71. {
  72. protected Logger log = LoggerFactory.getLogger( getClass() );
  73. @Inject
  74. private List<AuditListener> auditListeners = new ArrayList<>();
  75. @Inject
  76. protected UserRepositories userRepositories;
  77. /**
  78. * FIXME: this could be multiple implementations and needs to be configured.
  79. */
  80. @Inject
  81. @Named( value = "repositorySessionFactory" )
  82. protected RepositorySessionFactory repositorySessionFactory;
  83. @Inject
  84. protected ArchivaAdministration archivaAdministration;
  85. @Inject
  86. protected ManagedRepositoryAdmin managedRepositoryAdmin;
  87. @Inject
  88. protected RepositoryContentFactory repositoryContentFactory;
  89. @Inject
  90. @Named( value = "archivaTaskScheduler#repository" )
  91. protected DefaultRepositoryArchivaTaskScheduler repositoryTaskScheduler;
  92. @Inject
  93. @Named( value = "userConfiguration#default" )
  94. protected UserConfiguration config;
  95. @Context
  96. protected HttpServletRequest httpServletRequest;
  97. protected AuditInformation getAuditInformation()
  98. {
  99. RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get();
  100. User user = redbackRequestInformation == null ? null : redbackRequestInformation.getUser();
  101. String remoteAddr = redbackRequestInformation == null ? null : redbackRequestInformation.getRemoteAddr();
  102. return new AuditInformation( user, remoteAddr );
  103. }
  104. public List<AuditListener> getAuditListeners()
  105. {
  106. return auditListeners;
  107. }
  108. public void setAuditListeners( List<AuditListener> auditListeners )
  109. {
  110. this.auditListeners = auditListeners;
  111. }
  112. protected List<String> getObservableRepos()
  113. {
  114. try
  115. {
  116. List<String> ids = userRepositories.getObservableRepositoryIds( getPrincipal() );
  117. return ids == null ? Collections.<String>emptyList() : ids;
  118. }
  119. catch ( PrincipalNotFoundException e )
  120. {
  121. log.warn( e.getMessage(), e );
  122. }
  123. catch ( AccessDeniedException e )
  124. {
  125. log.warn( e.getMessage(), e );
  126. }
  127. catch ( ArchivaSecurityException e )
  128. {
  129. log.warn( e.getMessage(), e );
  130. }
  131. return Collections.emptyList();
  132. }
  133. protected String getPrincipal()
  134. {
  135. RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get();
  136. return redbackRequestInformation == null
  137. ? config.getString( UserConfigurationKeys.DEFAULT_GUEST )
  138. : ( redbackRequestInformation.getUser() == null
  139. ? config.getString( UserConfigurationKeys.DEFAULT_GUEST )
  140. : redbackRequestInformation.getUser().getUsername() );
  141. }
  142. protected String getBaseUrl()
  143. throws RepositoryAdminException
  144. {
  145. String applicationUrl = archivaAdministration.getUiConfiguration().getApplicationUrl();
  146. if ( StringUtils.isNotBlank( applicationUrl ) )
  147. {
  148. return applicationUrl;
  149. }
  150. return httpServletRequest.getScheme() + "://" + httpServletRequest.getServerName() + (
  151. httpServletRequest.getServerPort() == 80 ? "" : ":" + httpServletRequest.getServerPort() )
  152. + httpServletRequest.getContextPath();
  153. }
  154. protected <T> Map<String, T> getBeansOfType( ApplicationContext applicationContext, Class<T> clazz )
  155. {
  156. //TODO do some caching here !!!
  157. // olamy : with plexus we get only roleHint
  158. // as per convention we named spring bean role#hint remove role# if exists
  159. Map<String, T> springBeans = applicationContext.getBeansOfType( clazz );
  160. Map<String, T> beans = new HashMap<>( springBeans.size() );
  161. for ( Map.Entry<String, T> entry : springBeans.entrySet() )
  162. {
  163. String key = StringUtils.contains( entry.getKey(), '#' )
  164. ? StringUtils.substringAfterLast( entry.getKey(), "#" )
  165. : entry.getKey();
  166. beans.put( key, entry.getValue() );
  167. }
  168. return beans;
  169. }
  170. protected void triggerAuditEvent( String repositoryId, String filePath, String action )
  171. {
  172. AuditEvent auditEvent = new AuditEvent( repositoryId, getPrincipal(), filePath, action );
  173. AuditInformation auditInformation = getAuditInformation();
  174. auditEvent.setUserId( auditInformation.getUser() == null ? "" : auditInformation.getUser().getUsername() );
  175. auditEvent.setRemoteIP( auditInformation.getRemoteAddr() );
  176. for ( AuditListener auditListener : getAuditListeners() )
  177. {
  178. auditListener.auditEvent( auditEvent );
  179. }
  180. }
  181. /**
  182. * @param artifact
  183. * @return
  184. */
  185. protected String getArtifactUrl( Artifact artifact )
  186. throws ArchivaRestServiceException
  187. {
  188. try
  189. {
  190. if ( httpServletRequest == null )
  191. {
  192. return null;
  193. }
  194. StringBuilder sb = new StringBuilder( getBaseUrl() );
  195. sb.append( "/repository" );
  196. // FIXME when artifact come from a remote repository when have here the remote repo id
  197. // we must replace it with a valid managed one available for the user.
  198. sb.append( '/' ).append( artifact.getContext() );
  199. sb.append( '/' ).append( StringUtils.replaceChars( artifact.getGroupId(), '.', '/' ) );
  200. sb.append( '/' ).append( artifact.getArtifactId() );
  201. if ( VersionUtil.isSnapshot( artifact.getVersion() ) )
  202. {
  203. sb.append( '/' ).append( VersionUtil.getBaseVersion( artifact.getVersion() ) );
  204. }
  205. else
  206. {
  207. sb.append( '/' ).append( artifact.getVersion() );
  208. }
  209. sb.append( '/' ).append( artifact.getArtifactId() );
  210. sb.append( '-' ).append( artifact.getVersion() );
  211. if ( StringUtils.isNotBlank( artifact.getClassifier() ) )
  212. {
  213. sb.append( '-' ).append( artifact.getClassifier() );
  214. }
  215. // maven-plugin packaging is a jar
  216. if ( StringUtils.equals( "maven-plugin", artifact.getPackaging() ) )
  217. {
  218. sb.append( "jar" );
  219. }
  220. else
  221. {
  222. sb.append( '.' ).append( artifact.getFileExtension() );
  223. }
  224. return sb.toString();
  225. }
  226. catch ( RepositoryAdminException e )
  227. {
  228. throw new ArchivaRestServiceException( e.getMessage(),
  229. Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
  230. }
  231. }
  232. protected List<Artifact> buildArtifacts( List<ArtifactMetadata> artifactMetadatas, String repositoryId )
  233. throws ArchivaRestServiceException
  234. {
  235. try
  236. {
  237. if ( artifactMetadatas != null && !artifactMetadatas.isEmpty() )
  238. {
  239. List<Artifact> artifacts = new ArrayList<>( artifactMetadatas.size() );
  240. for ( ArtifactMetadata artifact : artifactMetadatas )
  241. {
  242. ArtifactBuilder builder =
  243. new ArtifactBuilder().forArtifactMetadata( artifact ).withManagedRepositoryContent(
  244. repositoryContentFactory.getManagedRepositoryContent( repositoryId ) );
  245. Artifact art = builder.build();
  246. art.setUrl( getArtifactUrl( art ) );
  247. artifacts.add( art );
  248. }
  249. return artifacts;
  250. }
  251. return Collections.emptyList();
  252. }
  253. catch ( RepositoryException e )
  254. {
  255. log.error( e.getMessage(), e );
  256. throw new ArchivaRestServiceException( e.getMessage(),
  257. Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
  258. }
  259. }
  260. protected Boolean doScanRepository( String repositoryId, boolean fullScan )
  261. {
  262. if ( repositoryTaskScheduler.isProcessingRepositoryTask( repositoryId ) )
  263. {
  264. log.info( "scanning of repository with id {} already scheduled", repositoryId );
  265. return Boolean.FALSE;
  266. }
  267. RepositoryTask task = new RepositoryTask();
  268. task.setRepositoryId( repositoryId );
  269. task.setScanAll( fullScan );
  270. try
  271. {
  272. repositoryTaskScheduler.queueTask( task );
  273. }
  274. catch ( TaskQueueException e )
  275. {
  276. log.error( "failed to schedule scanning of repo with id {}", repositoryId, e );
  277. return false;
  278. }
  279. return true;
  280. }
  281. private static class ModelMapperHolder
  282. {
  283. private static ModelMapper MODEL_MAPPER = new ModelMapper();
  284. static
  285. {
  286. MODEL_MAPPER.addMappings( new SearchResultHitMap() );
  287. MODEL_MAPPER.getConfiguration().setMatchingStrategy( MatchingStrategies.STRICT );
  288. }
  289. }
  290. private static class SearchResultHitMap
  291. extends PropertyMap<SearchResultHit, Artifact>
  292. {
  293. protected void configure()
  294. {
  295. skip().setId( null );
  296. }
  297. }
  298. ;
  299. protected ModelMapper getModelMapper()
  300. {
  301. return ModelMapperHolder.MODEL_MAPPER;
  302. }
  303. }