This project has retired. For details please refer to its Attic page.
ArchivaMetadataCreationConsumer xref
View Javadoc
1   package org.apache.archiva.consumers.metadata;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.archiva.common.utils.VersionUtil;
23  import org.apache.archiva.configuration.ArchivaConfiguration;
24  import org.apache.archiva.configuration.ConfigurationNames;
25  import org.apache.archiva.configuration.FileTypes;
26  import org.apache.archiva.consumers.AbstractMonitoredConsumer;
27  import org.apache.archiva.consumers.ConsumerException;
28  import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
29  import org.apache.archiva.metadata.model.ArtifactMetadata;
30  import org.apache.archiva.metadata.model.ProjectMetadata;
31  import org.apache.archiva.metadata.model.ProjectVersionMetadata;
32  import org.apache.archiva.metadata.repository.*;
33  import org.apache.archiva.metadata.repository.storage.ReadMetadataRequest;
34  import org.apache.archiva.metadata.repository.storage.RepositoryStorage;
35  import org.apache.archiva.metadata.repository.storage.RepositoryStorageMetadataInvalidException;
36  import org.apache.archiva.metadata.repository.storage.RepositoryStorageMetadataNotFoundException;
37  import org.apache.archiva.metadata.repository.storage.RepositoryStorageRuntimeException;
38  import org.apache.archiva.components.registry.Registry;
39  import org.apache.archiva.components.registry.RegistryListener;
40  import org.apache.archiva.repository.ManagedRepository;
41  import org.slf4j.Logger;
42  import org.slf4j.LoggerFactory;
43  import org.springframework.context.annotation.Scope;
44  import org.springframework.stereotype.Service;
45  
46  import javax.annotation.PostConstruct;
47  import javax.inject.Inject;
48  import javax.inject.Named;
49  import java.time.ZoneId;
50  import java.time.ZonedDateTime;
51  import java.util.ArrayList;
52  import java.util.Date;
53  import java.util.List;
54  
55  /**
56   * Take an artifact off of disk and put it into the metadata repository.
57   */
58  @Service ("knownRepositoryContentConsumer#create-archiva-metadata")
59  @Scope ("prototype")
60  public class ArchivaMetadataCreationConsumer
61      extends AbstractMonitoredConsumer
62      implements KnownRepositoryContentConsumer, RegistryListener
63  {
64      private String id = "create-archiva-metadata";
65  
66      private String description = "Create basic metadata for Archiva to be able to reference the artifact";
67  
68      @Inject
69      private ArchivaConfiguration configuration;
70  
71      @Inject
72      private FileTypes filetypes;
73  
74      private ZonedDateTime whenGathered;
75  
76      private List<String> includes = new ArrayList<>( 0 );
77  
78      /**
79       * FIXME: this could be multiple implementations and needs to be configured.
80       */
81      @Inject
82      private RepositorySessionFactory repositorySessionFactory;
83  
84      /**
85       * FIXME: this needs to be configurable based on storage type - and could also be instantiated per repo. Change to a
86       * factory.
87       */
88      @Inject
89      @Named (value = "repositoryStorage#maven2")
90      private RepositoryStorage repositoryStorage;
91  
92      private static final Logger log = LoggerFactory.getLogger( ArchivaMetadataCreationConsumer.class );
93  
94      private String repoId;
95  
96      @Override
97      public String getId()
98      {
99          return this.id;
100     }
101 
102     @Override
103     public String getDescription()
104     {
105         return this.description;
106     }
107 
108     @Override
109     public List<String> getExcludes()
110     {
111         return getDefaultArtifactExclusions();
112     }
113 
114     @Override
115     public List<String> getIncludes()
116     {
117         return this.includes;
118     }
119 
120     @Override
121     public void beginScan( ManagedRepository repo, Date whenGathered )
122         throws ConsumerException
123     {
124         repoId = repo.getId();
125         this.whenGathered = ZonedDateTime.ofInstant(whenGathered.toInstant(), ZoneId.of("GMT"));
126     }
127 
128     @Override
129     public void beginScan( ManagedRepository repository, Date whenGathered, boolean executeOnEntireRepo )
130         throws ConsumerException
131     {
132         beginScan( repository, whenGathered );
133     }
134 
135     @Override
136     public void processFile( String path )
137         throws ConsumerException
138     {
139 
140         RepositorySession repositorySession = null;
141         try
142         {
143             repositorySession = repositorySessionFactory.createSession();
144         }
145         catch ( MetadataRepositoryException e )
146         {
147             e.printStackTrace( );
148         }
149         try
150         {
151             // note that we do minimal processing including checksums and POM information for performance of
152             // the initial scan. Any request for this information will be intercepted and populated on-demand
153             // or picked up by subsequent scans
154 
155             ArtifactMetadata artifact = repositoryStorage.readArtifactMetadataFromPath( repoId, path );
156 
157             ProjectMetadatarojectMetadata.html#ProjectMetadata">ProjectMetadata project = new ProjectMetadata();
158             project.setNamespace( artifact.getNamespace() );
159             project.setId( artifact.getProject() );
160 
161             String projectVersion = VersionUtil.getBaseVersion( artifact.getVersion() );
162 
163             MetadataRepository metadataRepository = repositorySession.getRepository();
164 
165             boolean createVersionMetadata = false;
166 
167             // FIXME: maybe not too efficient since it may have already been read and stored for this artifact
168             ProjectVersionMetadata versionMetadata = null;
169             try
170             {
171                 ReadMetadataRequest readMetadataRequest =
172                     new ReadMetadataRequest().repositoryId( repoId ).namespace( artifact.getNamespace() ).projectId(
173                         artifact.getProject() ).projectVersion( projectVersion );
174                 versionMetadata = repositoryStorage.readProjectVersionMetadata( readMetadataRequest );
175                 createVersionMetadata = true;
176             }
177             catch ( RepositoryStorageMetadataNotFoundException e )
178             {
179                 log.warn( "Missing or invalid POM for artifact:{} (repository:{}); creating empty metadata", path,
180                           repoId );
181 
182                 versionMetadata = new ProjectVersionMetadata();
183                 versionMetadata.setId( projectVersion );
184                 versionMetadata.setIncomplete( true );
185                 createVersionMetadata = true;
186             }
187             catch ( RepositoryStorageMetadataInvalidException e )
188             {
189                 log.warn( "Error occurred resolving POM for artifact:{} (repository:{}); message: {}",
190                           new Object[]{ path, repoId, e.getMessage() } );
191             }
192 
193             // read the metadata and update it if it is newer or doesn't exist
194             artifact.setWhenGathered( whenGathered );
195             metadataRepository.updateArtifact(repositorySession , repoId, project.getNamespace(), project.getId(),
196                 projectVersion, artifact );
197             if ( createVersionMetadata )
198             {
199                 metadataRepository.updateProjectVersion(repositorySession , repoId, project.getNamespace(),
200                     project.getId(), versionMetadata );
201             }
202             metadataRepository.updateProject(repositorySession , repoId, project );
203             repositorySession.save();
204         }
205         catch ( MetadataRepositoryException e )
206         {
207             log.warn(
208                 "Error occurred persisting metadata for artifact:{} (repository:{}); message: {}" ,
209                 path, repoId, e.getMessage(), e );
210             try {
211                 repositorySession.revert();
212             } catch (MetadataSessionException ex) {
213                 log.error("Reverting failed {}", ex.getMessage());
214             }
215         }
216         catch ( RepositoryStorageRuntimeException e )
217         {
218             log.warn(
219                 "Error occurred persisting metadata for artifact:{} (repository:{}); message: {}",
220                 path, repoId, e.getMessage(), e );
221             try {
222                 repositorySession.revert();
223             } catch (MetadataSessionException ex) {
224                 log.error("Reverting failed {}", ex.getMessage());
225             }
226         } catch (MetadataSessionException e) {
227             throw new ConsumerException(e.getMessage(), e);
228         } finally
229         {
230             repositorySession.close();
231         }
232     }
233 
234     @Override
235     public void processFile( String path, boolean executeOnEntireRepo )
236         throws ConsumerException
237     {
238         processFile( path );
239     }
240 
241     @Override
242     public void completeScan()
243     {
244         /* do nothing */
245     }
246 
247     @Override
248     public void completeScan( boolean executeOnEntireRepo )
249     {
250         completeScan();
251     }
252 
253     @Override
254     public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
255     {
256         if ( ConfigurationNames.isRepositoryScanning( propertyName ) )
257         {
258             initIncludes();
259         }
260     }
261 
262     @Override
263     public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
264     {
265         /* do nothing */
266     }
267 
268     private void initIncludes()
269     {
270         includes = new ArrayList<String>( filetypes.getFileTypePatterns( FileTypes.ARTIFACTS ) );
271     }
272 
273     @PostConstruct
274     public void initialize()
275     {
276         configuration.addChangeListener( this );
277 
278         initIncludes();
279     }
280 }