This project has retired. For details please refer to its Attic page.
MetadataUpdaterConsumer xref
View Javadoc
1   package org.apache.archiva.consumers.core;
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.admin.model.beans.ManagedRepository;
23  import org.apache.archiva.configuration.ArchivaConfiguration;
24  import org.apache.archiva.configuration.FileTypes;
25  import org.apache.archiva.consumers.AbstractMonitoredConsumer;
26  import org.apache.archiva.consumers.ConsumerException;
27  import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
28  import org.apache.archiva.model.ArtifactReference;
29  import org.apache.archiva.model.ProjectReference;
30  import org.apache.archiva.model.VersionedReference;
31  import org.apache.archiva.repository.ContentNotFoundException;
32  import org.apache.archiva.repository.ManagedRepositoryContent;
33  import org.apache.archiva.repository.RepositoryContentFactory;
34  import org.apache.archiva.repository.RepositoryException;
35  import org.apache.archiva.repository.RepositoryNotFoundException;
36  import org.apache.archiva.repository.layout.LayoutException;
37  import org.apache.archiva.repository.metadata.MetadataTools;
38  import org.apache.archiva.repository.metadata.RepositoryMetadataException;
39  import org.slf4j.Logger;
40  import org.slf4j.LoggerFactory;
41  import org.springframework.context.annotation.Scope;
42  import org.springframework.stereotype.Service;
43  
44  import javax.annotation.PostConstruct;
45  import javax.inject.Inject;
46  import java.io.File;
47  import java.io.IOException;
48  import java.util.ArrayList;
49  import java.util.Date;
50  import java.util.List;
51  
52  /**
53   * MetadataUpdaterConsumer will create and update the metadata present within the repository.
54   */
55  @Service( "knownRepositoryContentConsumer#metadata-updater" )
56  @Scope( "prototype" )
57  public class MetadataUpdaterConsumer
58      extends AbstractMonitoredConsumer
59      implements KnownRepositoryContentConsumer
60      // it's prototype bean so we assume configuration won't change during a run
61      //, RegistryListener
62  {
63      private Logger log = LoggerFactory.getLogger( MetadataUpdaterConsumer.class );
64  
65      /**
66       * default-value="metadata-updater"
67       */
68      private String id = "metadata-updater";
69  
70      private String description = "Update / Create maven-metadata.xml files";
71  
72      @Inject
73      private RepositoryContentFactory repositoryFactory;
74  
75      @Inject
76      private MetadataTools metadataTools;
77  
78      @Inject
79      private ArchivaConfiguration configuration;
80  
81      @Inject
82      private FileTypes filetypes;
83  
84      private static final String TYPE_METADATA_BAD_INTERNAL_REF = "metadata-bad-internal-ref";
85  
86      private static final String TYPE_METADATA_WRITE_FAILURE = "metadata-write-failure";
87  
88      private static final String TYPE_METADATA_IO = "metadata-io-warning";
89  
90      private ManagedRepositoryContent repository;
91  
92      private File repositoryDir;
93  
94      private List<String> includes = new ArrayList<>( 0 );
95  
96      private long scanStartTimestamp = 0;
97  
98      @Override
99      public String getDescription( )
100     {
101         return description;
102     }
103 
104     @Override
105     public String getId( )
106     {
107         return id;
108     }
109 
110     public void setIncludes( List<String> includes )
111     {
112         this.includes = includes;
113     }
114 
115     @Override
116     public void beginScan( ManagedRepository repoConfig, Date whenGathered )
117         throws ConsumerException
118     {
119         try
120         {
121             this.repository = repositoryFactory.getManagedRepositoryContent( repoConfig.getId( ) );
122             this.repositoryDir = new File( repository.getRepoRoot( ) );
123             this.scanStartTimestamp = System.currentTimeMillis( );
124         }
125         catch ( RepositoryNotFoundException e )
126         {
127             throw new ConsumerException( e.getMessage( ), e );
128         }
129         catch ( RepositoryException e )
130         {
131             throw new ConsumerException( e.getMessage( ), e );
132         }
133     }
134 
135     @Override
136     public void beginScan( ManagedRepository repository, Date whenGathered, boolean executeOnEntireRepo )
137         throws ConsumerException
138     {
139         beginScan( repository, whenGathered );
140     }
141 
142     @Override
143     public void completeScan( )
144     {
145         /* do nothing here */
146     }
147 
148     @Override
149     public void completeScan( boolean executeOnEntireRepo )
150     {
151         completeScan( );
152     }
153 
154     @Override
155     public List<String> getExcludes( )
156     {
157         return getDefaultArtifactExclusions( );
158     }
159 
160     @Override
161     public List<String> getIncludes( )
162     {
163         return this.includes;
164     }
165 
166     @Override
167     public void processFile( String path )
168         throws ConsumerException
169     {
170         // Ignore paths like .index etc
171         if ( !path.startsWith( "." ) )
172         {
173             try
174             {
175                 ArtifactReference artifact = repository.toArtifactReference( path );
176                 updateVersionMetadata( artifact, path );
177                 updateProjectMetadata( artifact, path );
178             }
179             catch ( LayoutException e )
180             {
181                 log.info( "Not processing path that is not an artifact: {} ({})", path, e.getMessage( ) );
182             }
183         }
184     }
185 
186     @Override
187     public void processFile( String path, boolean executeOnEntireRepo )
188         throws Exception
189     {
190         processFile( path );
191     }
192 
193     private void updateProjectMetadata( ArtifactReference artifact, String path )
194     {
195         ProjectReference projectRef = new ProjectReference( );
196         projectRef.setGroupId( artifact.getGroupId( ) );
197         projectRef.setArtifactId( artifact.getArtifactId( ) );
198 
199         try
200         {
201             String metadataPath = this.metadataTools.toPath( projectRef );
202 
203             File projectMetadata = new File( this.repositoryDir, metadataPath );
204 
205             if ( projectMetadata.exists( ) && ( projectMetadata.lastModified( ) >= this.scanStartTimestamp ) )
206             {
207                 // This metadata is up to date. skip it.
208                 log.debug( "Skipping uptodate metadata: {}", this.metadataTools.toPath( projectRef ) );
209                 return;
210             }
211 
212             metadataTools.updateMetadata( this.repository, projectRef );
213             log.debug( "Updated metadata: {}", this.metadataTools.toPath( projectRef ) );
214         }
215         catch ( LayoutException e )
216         {
217             log.warn( "Unable to convert path [{}] to an internal project reference: ", path, e );
218             triggerConsumerWarning( TYPE_METADATA_BAD_INTERNAL_REF,
219                 "Unable to convert path [" + path + "] to an internal project reference: "
220                     + e.getMessage( ) );
221         }
222         catch ( RepositoryMetadataException e )
223         {
224             log.error( "Unable to write project metadat for artifact [{}]:", path, e );
225             triggerConsumerError( TYPE_METADATA_WRITE_FAILURE,
226                 "Unable to write project metadata for artifact [" + path + "]: " + e.getMessage( ) );
227         }
228         catch ( IOException e )
229         {
230             log.warn( "Project metadata not written due to IO warning: ", e );
231             triggerConsumerWarning( TYPE_METADATA_IO,
232                 "Project metadata not written due to IO warning: " + e.getMessage( ) );
233         }
234         catch ( ContentNotFoundException e )
235         {
236             log.warn( "Project metadata not written because no versions were found to update: ", e );
237             triggerConsumerWarning( TYPE_METADATA_IO,
238                 "Project metadata not written because no versions were found to update: "
239                     + e.getMessage( ) );
240         }
241     }
242 
243     private void updateVersionMetadata( ArtifactReference artifact, String path )
244     {
245         VersionedReference versionRef = new VersionedReference( );
246         versionRef.setGroupId( artifact.getGroupId( ) );
247         versionRef.setArtifactId( artifact.getArtifactId( ) );
248         versionRef.setVersion( artifact.getVersion( ) );
249 
250         try
251         {
252             String metadataPath = this.metadataTools.toPath( versionRef );
253 
254             File projectMetadata = new File( this.repositoryDir, metadataPath );
255 
256             if ( projectMetadata.exists( ) && ( projectMetadata.lastModified( ) >= this.scanStartTimestamp ) )
257             {
258                 // This metadata is up to date. skip it.
259                 log.debug( "Skipping uptodate metadata: {}", this.metadataTools.toPath( versionRef ) );
260                 return;
261             }
262 
263             metadataTools.updateMetadata( this.repository, versionRef );
264             log.debug( "Updated metadata: {}", this.metadataTools.toPath( versionRef ) );
265         }
266         catch ( LayoutException e )
267         {
268             log.warn( "Unable to convert path [{}] to an internal version reference: ", path, e );
269             triggerConsumerWarning( TYPE_METADATA_BAD_INTERNAL_REF,
270                 "Unable to convert path [" + path + "] to an internal version reference: "
271                     + e.getMessage( ) );
272         }
273         catch ( RepositoryMetadataException e )
274         {
275             log.error( "Unable to write version metadata for artifact [{}]: ", path, e );
276             triggerConsumerError( TYPE_METADATA_WRITE_FAILURE,
277                 "Unable to write version metadata for artifact [" + path + "]: " + e.getMessage( ) );
278         }
279         catch ( IOException e )
280         {
281             log.warn( "Version metadata not written due to IO warning: ", e );
282             triggerConsumerWarning( TYPE_METADATA_IO,
283                 "Version metadata not written due to IO warning: " + e.getMessage( ) );
284         }
285         catch ( ContentNotFoundException e )
286         {
287             log.warn( "Version metadata not written because no versions were found to update: ", e );
288             triggerConsumerWarning( TYPE_METADATA_IO,
289                 "Version metadata not written because no versions were found to update: "
290                     + e.getMessage( ) );
291         }
292     }
293 
294     /*
295     @Override
296     public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
297     {
298         if ( ConfigurationNames.isRepositoryScanning( propertyName ) )
299         {
300             initIncludes();
301         }
302     }
303 
304     @Override
305     public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
306     {
307         // do nothing here
308     }
309     */
310 
311     private void initIncludes( )
312     {
313         includes = new ArrayList<>( filetypes.getFileTypePatterns( FileTypes.ARTIFACTS ) );
314     }
315 
316     @PostConstruct
317     public void initialize( )
318     {
319         //configuration.addChangeListener( this );
320 
321         initIncludes( );
322     }
323 }