1 package org.apache.archiva.consumers.metadata;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
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
80
81 @Inject
82 private RepositorySessionFactory repositorySessionFactory;
83
84
85
86
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
152
153
154
155 ArtifactMetadata artifact = repositoryStorage.readArtifactMetadataFromPath( repoId, path );
156
157 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
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
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
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
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 }