]> source.dussan.org Git - archiva.git/blob
f7c4dcc847421593ecc45062ef292938932896ca
[archiva.git] /
1 package org.apache.archiva.metadata.repository.stats;
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.metadata.repository.MetadataRepository;
23 import org.apache.archiva.metadata.repository.MetadataRepositoryException;
24 import org.apache.archiva.metadata.repository.stats.model.DefaultRepositoryStatistics;
25 import org.apache.archiva.metadata.repository.stats.model.RepositoryStatistics;
26 import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsManager;
27 import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsProvider;
28 import org.apache.archiva.metadata.repository.stats.model.RepositoryWalkingStatisticsProvider;
29 import org.apache.commons.lang.time.StopWatch;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32 import org.springframework.stereotype.Service;
33
34 import java.text.ParseException;
35 import java.text.SimpleDateFormat;
36 import java.util.ArrayList;
37 import java.util.Collections;
38 import java.util.Date;
39 import java.util.List;
40 import java.util.TimeZone;
41
42 /**
43  *
44  */
45 @Service("repositoryStatisticsManager#default")
46 public class DefaultRepositoryStatisticsManager
47     implements RepositoryStatisticsManager
48 {
49     private static final Logger log = LoggerFactory.getLogger( DefaultRepositoryStatisticsManager.class );
50
51     private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" );
52
53     private RepositoryWalkingStatisticsProvider walkingProvider = new RepositoryWalkingStatisticsProvider();
54
55     @Override
56     public boolean hasStatistics( MetadataRepository metadataRepository, String repositoryId )
57         throws MetadataRepositoryException
58     {
59         return metadataRepository.hasMetadataFacet( repositoryId, DefaultRepositoryStatistics.FACET_ID );
60     }
61
62     @Override
63     public RepositoryStatistics getLastStatistics( MetadataRepository metadataRepository, String repositoryId )
64         throws MetadataRepositoryException
65     {
66         StopWatch stopWatch = new StopWatch();
67         stopWatch.start();
68         // TODO: consider a more efficient implementation that directly gets the last one from the content repository
69         List<String> scans = metadataRepository.getMetadataFacets( repositoryId, DefaultRepositoryStatistics.FACET_ID );
70         if ( scans == null )
71         {
72             return null;
73         }
74         Collections.sort( scans );
75         if ( !scans.isEmpty() )
76         {
77             String name = scans.get( scans.size() - 1 );
78             RepositoryStatistics repositoryStatistics =
79                 RepositoryStatistics.class.cast( metadataRepository.getMetadataFacet( repositoryId, RepositoryStatistics.FACET_ID,
80                                                                             name ));
81             stopWatch.stop();
82             log.debug( "time to find last RepositoryStatistics: {} ms", stopWatch.getTime() );
83             return repositoryStatistics;
84         }
85         else
86         {
87             return null;
88         }
89     }
90
91     @Override
92     public void addStatisticsAfterScan( MetadataRepository metadataRepository, String repositoryId, Date startTime,
93                                         Date endTime, long totalFiles, long newFiles )
94         throws MetadataRepositoryException
95     {
96         DefaultRepositoryStatistics repositoryStatistics = new DefaultRepositoryStatistics();
97         repositoryStatistics.setRepositoryId( repositoryId );
98         repositoryStatistics.setScanStartTime( startTime );
99         repositoryStatistics.setScanEndTime( endTime );
100         repositoryStatistics.setTotalFileCount( totalFiles );
101         repositoryStatistics.setNewFileCount( newFiles );
102
103         // TODO
104         // In the future, instead of being tied to a scan we might want to record information in the fly based on
105         // events that are occurring. Even without these totals we could query much of the information on demand based
106         // on information from the metadata content repository. In the mean time, we lock information in at scan time.
107         // Note that if new types are later discoverable due to a code change or new plugin, historical stats will not
108         // be updated and the repository will need to be rescanned.
109
110         long startGather = System.currentTimeMillis();
111
112         if ( metadataRepository instanceof RepositoryStatisticsProvider)
113         {
114             ((RepositoryStatisticsProvider)metadataRepository).populateStatistics( metadataRepository,
115                 repositoryId, repositoryStatistics);
116         }
117         else
118         {
119             walkingProvider.populateStatistics( metadataRepository, repositoryId, repositoryStatistics );
120         }
121
122         log.info( "Gathering statistics executed in {} ms",  ( System.currentTimeMillis() - startGather ) );
123
124         metadataRepository.addMetadataFacet( repositoryId, repositoryStatistics );
125     }
126
127     @Override
128     public void deleteStatistics( MetadataRepository metadataRepository, String repositoryId )
129         throws MetadataRepositoryException
130     {
131         metadataRepository.removeMetadataFacets( repositoryId, DefaultRepositoryStatistics.FACET_ID );
132     }
133
134     @Override
135     public List<RepositoryStatistics> getStatisticsInRange( MetadataRepository metadataRepository, String repositoryId,
136                                                             Date startTime, Date endTime )
137         throws MetadataRepositoryException
138     {
139         List<RepositoryStatistics> results = new ArrayList<>();
140         List<String> list = metadataRepository.getMetadataFacets( repositoryId, DefaultRepositoryStatistics.FACET_ID );
141         Collections.sort( list, Collections.reverseOrder() );
142         for ( String name : list )
143         {
144             try
145             {
146                 Date date = createNameFormat().parse( name );
147                 if ( ( startTime == null || !date.before( startTime ) ) && ( endTime == null || !date.after(
148                     endTime ) ) )
149                 {
150                     RepositoryStatistics stats =
151                         (RepositoryStatistics) metadataRepository.getMetadataFacet( repositoryId,
152                                                                                     DefaultRepositoryStatistics.FACET_ID,
153                                                                                     name );
154                     results.add( stats );
155                 }
156             }
157             catch ( ParseException e )
158             {
159                 log.error( "Invalid scan result found in the metadata repository: " + e.getMessage() );
160                 // continue and ignore this one
161             }
162         }
163         return results;
164     }
165
166     private static SimpleDateFormat createNameFormat()
167     {
168         SimpleDateFormat fmt = new SimpleDateFormat( DefaultRepositoryStatistics.SCAN_TIMESTAMP_FORMAT );
169         fmt.setTimeZone( UTC_TIME_ZONE );
170         return fmt;
171     }
172 }