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