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