1 package org.apache.archiva.metadata.repository.stats;
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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
22 import junit.framework.TestCase;
23 import org.apache.archiva.metadata.model.MetadataFacetFactory;
24 import org.apache.archiva.metadata.repository.AbstractMetadataRepositoryTest;
25 import org.apache.archiva.metadata.repository.DefaultMetadataResolver;
26 import org.apache.archiva.metadata.repository.MetadataRepository;
27 import org.apache.archiva.metadata.repository.MetadataRepositoryException;
28 import org.apache.archiva.metadata.repository.MetadataService;
29 import org.apache.archiva.metadata.repository.RepositorySession;
30 import org.apache.archiva.metadata.repository.RepositorySessionFactory;
31 import org.apache.archiva.metadata.repository.jcr.JcrMetadataRepository;
32 import org.apache.archiva.metadata.repository.jcr.JcrRepositorySessionFactory;
33 import org.apache.archiva.metadata.repository.jcr.JcrRepositorySession;
34 import org.apache.archiva.metadata.repository.stats.model.DefaultRepositoryStatistics;
35 import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
36 import org.apache.jackrabbit.commons.JcrUtils;
37 import org.apache.jackrabbit.oak.segment.file.InvalidFileStoreVersionException;
38 import org.junit.After;
39 import org.junit.AfterClass;
40 import org.junit.BeforeClass;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45 import org.springframework.test.context.ContextConfiguration;
46 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
48 import javax.jcr.ImportUUIDBehavior;
49 import javax.jcr.Node;
50 import javax.jcr.Repository;
51 import javax.jcr.RepositoryException;
52 import javax.jcr.Session;
53 import javax.jcr.nodetype.NodeTypeManager;
54 import javax.jcr.nodetype.NodeTypeTemplate;
55 import java.io.IOException;
56 import java.io.InputStream;
57 import java.nio.file.Files;
58 import java.nio.file.Path;
59 import java.nio.file.Paths;
60 import java.util.Calendar;
61 import java.util.Date;
62 import java.util.List;
64 import java.util.zip.GZIPInputStream;
66 @RunWith( SpringJUnit4ClassRunner.class )
67 @ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context.xml" } )
68 public class JcrRepositoryStatisticsGatheringTest
71 private static final Logger log = LoggerFactory.getLogger( JcrRepositoryStatisticsGatheringTest.class );
72 private static final int TOTAL_FILE_COUNT = 1000;
74 private static final int NEW_FILE_COUNT = 500;
76 private static final String TEST_REPO = "test-repo";
78 static JcrMetadataRepository repository;
79 static JcrRepositorySessionFactory sessionFactory;
83 private static Repository jcrRepository;
85 Logger logger = LoggerFactory.getLogger( getClass() );
86 private int assertRetrySleepMs = 500;
87 private int assertMaxTries = 5;
90 public static void setupSpec()
91 throws IOException, InvalidFileStoreVersionException
93 Path directory = Paths.get( "target/test-repositories" );
94 if ( Files.exists(directory) )
96 org.apache.archiva.common.utils.FileUtils.deleteDirectory( directory );
98 directory = Paths.get( "target/jcr" );
99 if (Files.exists( directory )) {
100 org.apache.archiva.common.utils.FileUtils.deleteDirectory( directory );
103 List<MetadataFacetFactory> factories = AbstractMetadataRepositoryTest.createTestMetadataFacetFactories();
105 MetadataService metadataService = new MetadataService( );
106 metadataService.setMetadataFacetFactories( factories );
108 JcrRepositorySessionFactory jcrSessionFactory = new JcrRepositorySessionFactory();
109 jcrSessionFactory.setMetadataResolver(new DefaultMetadataResolver());
110 jcrSessionFactory.setMetadataService(metadataService);
112 jcrSessionFactory.open();
113 sessionFactory = jcrSessionFactory;
114 repository = jcrSessionFactory.getMetadataRepository();
119 public static void stopSpec() {
124 catch ( MetadataRepositoryException e )
126 e.printStackTrace( );
128 sessionFactory.close();
132 * Used by tryAssert to allow to throw exceptions in the lambda expression.
135 protected interface AssertFunction
137 void accept( ) throws Exception;
140 protected void tryAssert( AssertFunction func ) throws Exception
142 tryAssert( func, assertMaxTries, assertRetrySleepMs );
147 * Runs the assert method until the assert is successful or the number of retries
148 * is reached. This is needed because the JCR Oak index update is asynchronous, so updates
149 * may not be visible immediately after the modification.
151 private void tryAssert( AssertFunction func, int retries, int sleepMillis ) throws Exception
155 while ( retry-- > 0 )
162 catch ( Exception | AssertionError e )
165 Thread.currentThread( ).sleep( sleepMillis );
166 log.warn( "Retrying assert {}: {}", retry, e.getMessage( ) );
169 log.warn( "Retries: {}, Exception: {}", retry, t.getMessage( ) );
170 if ( retry <= 0 && t != null )
172 if ( t instanceof RuntimeException )
174 throw (RuntimeException) t;
176 else if ( t instanceof Exception )
180 else if ( t instanceof Error )
187 private static void registerMixinNodeType( NodeTypeManager nodeTypeManager, String type )
188 throws RepositoryException
190 NodeTypeTemplate nodeType = nodeTypeManager.createNodeTypeTemplate();
191 nodeType.setMixin( true );
192 nodeType.setName( type );
193 nodeTypeManager.registerNodeType( nodeType, false );
197 public void tearDown()
200 if ( repository != null )
205 } catch (Throwable e) {
209 if (sessionFactory!=null) {
212 sessionFactory.close( );
213 } catch (Throwable e) {
222 public void testJcrStatisticsQuery()
225 try(RepositorySession repSession = sessionFactory.createSession()) {
226 Calendar cal = Calendar.getInstance();
227 Date endTime = cal.getTime();
228 cal.add(Calendar.HOUR, -1);
229 Date startTime = cal.getTime();
231 loadContentIntoRepo(repSession, TEST_REPO);
232 loadContentIntoRepo( repSession, "another-repo");
234 DefaultRepositoryStatistics testedStatistics = new DefaultRepositoryStatistics();
235 testedStatistics.setNewFileCount(NEW_FILE_COUNT);
236 testedStatistics.setTotalFileCount(TOTAL_FILE_COUNT);
237 testedStatistics.setScanStartTime(startTime);
238 testedStatistics.setScanEndTime(endTime);
241 DefaultRepositoryStatistics expectedStatistics = new DefaultRepositoryStatistics();
242 expectedStatistics.setNewFileCount(NEW_FILE_COUNT);
243 expectedStatistics.setTotalFileCount(TOTAL_FILE_COUNT);
244 expectedStatistics.setScanEndTime(endTime);
245 expectedStatistics.setScanStartTime(startTime);
246 expectedStatistics.setTotalArtifactFileSize(95954585);
247 expectedStatistics.setTotalArtifactCount(269);
248 expectedStatistics.setTotalGroupCount(1);
249 expectedStatistics.setTotalProjectCount(43);
250 expectedStatistics.setTotalCountForType("zip", 1);
251 expectedStatistics.setTotalCountForType("gz", 1); // FIXME: should be tar.gz
252 expectedStatistics.setTotalCountForType("java-source", 10);
253 expectedStatistics.setTotalCountForType("jar", 108);
254 expectedStatistics.setTotalCountForType("xml", 3);
255 expectedStatistics.setTotalCountForType("war", 2);
256 expectedStatistics.setTotalCountForType("pom", 144);
257 expectedStatistics.setRepositoryId(TEST_REPO);
260 repository.populateStatistics(repSession, repository, TEST_REPO, testedStatistics);
262 logger.info("getTotalCountForType: {}", testedStatistics.getTotalCountForType());
264 assertEquals(NEW_FILE_COUNT, testedStatistics.getNewFileCount());
265 assertEquals(TOTAL_FILE_COUNT, testedStatistics.getTotalFileCount());
266 assertEquals(endTime, testedStatistics.getScanEndTime());
267 assertEquals(startTime, testedStatistics.getScanStartTime());
268 assertEquals(269, testedStatistics.getTotalArtifactCount());
269 assertEquals(1, testedStatistics.getTotalGroupCount());
270 assertEquals(43, testedStatistics.getTotalProjectCount());
271 assertEquals(1, testedStatistics.getTotalCountForType("zip"));
272 assertEquals(1, testedStatistics.getTotalCountForType("gz"));
273 assertEquals(10, testedStatistics.getTotalCountForType("java-source"));
274 assertEquals(108, testedStatistics.getTotalCountForType("jar"));
275 assertEquals(3, testedStatistics.getTotalCountForType("xml"));
276 assertEquals(2, testedStatistics.getTotalCountForType("war"));
277 assertEquals(144, testedStatistics.getTotalCountForType("pom"));
278 assertEquals(10, testedStatistics.getTotalCountForType("java-source"));
279 assertEquals(95954585, testedStatistics.getTotalArtifactFileSize());
285 private void loadContentIntoRepo( RepositorySession repoSession, String repoId )
286 throws RepositoryException, IOException, MetadataRepositoryException
288 jcrSession = ((JcrRepositorySession) repoSession).getJcrSession();
289 Node n = JcrUtils.getOrAddNode( jcrSession.getRootNode( ), "repositories" );
290 n = JcrUtils.getOrAddNode( n, repoId );
291 n = JcrUtils.getOrAddNode( n, "content" );
292 n = JcrUtils.getOrAddNode( n, "org" );
293 n = JcrUtils.getOrAddNode( n, "apache" );
295 InputStream inputStream = getClass( ).getResourceAsStream( "/artifacts.xml" );
296 jcrSession.importXML( n.getPath( ), inputStream, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW );