<groupId>org.apache.archiva</groupId>
<artifactId>metadata-repository-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.archiva</groupId>
+ <artifactId>repository-statistics</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>metadata-model</artifactId>
import org.apache.archiva.metadata.repository.MetadataRepositoryException;
import org.apache.archiva.metadata.repository.RepositorySession;
import org.apache.archiva.metadata.repository.RepositorySessionFactory;
-import org.apache.archiva.metadata.repository.stats.RepositoryStatisticsManager;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsManager;
import org.apache.archiva.redback.components.cache.Cache;
import org.apache.archiva.redback.components.taskqueue.TaskQueueException;
import org.apache.archiva.redback.role.RoleManager;
<feature version="[3,4)">spring</feature>
<bundle>mvn:org.apache.archiva/metadata-model/${project.version}</bundle>
<bundle>mvn:org.apache.archiva/metadata-repository-api/${project.version}</bundle>
+ <bundle>mvn:org.apache.archiva/metadata-statistics-api/${project.version}</bundle>
</feature>
<feature name="archiva-audit" description="Archiva Audit module" version="${project.version}" resolver="(obr)">
<feature name="archiva-repository-statistics" description="Archiva Repository Statistics module" version="${project.version}" resolver="(obr)">
<feature version="${project.version}">archiva-repository-layer</feature>
- <bundle dependency="true">mvn:javax.jcr/jcr/${javax.jcr.version}</bundle>
- <bundle dependency="true">mvn:org.apache.jackrabbit/jackrabbit-jcr-commons/${jackrabbit.version}</bundle>
<bundle>mvn:org.apache.archiva/repository-statistics/${project.version}</bundle>
</feature>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
- <artifactId>repository-statistics</artifactId>
+ <artifactId>metadata-statistics-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
import org.apache.archiva.metadata.repository.MetadataRepositoryException;
import org.apache.archiva.metadata.repository.RepositorySession;
import org.apache.archiva.metadata.repository.RepositorySessionFactory;
-import org.apache.archiva.metadata.repository.stats.RepositoryStatistics;
-import org.apache.archiva.metadata.repository.stats.RepositoryStatisticsManager;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatistics;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsManager;
import org.apache.archiva.repository.scanner.RepositoryContentConsumers;
import org.apache.archiva.repository.scanner.RepositoryScanStatistics;
import org.apache.archiva.repository.scanner.RepositoryScanner;
import org.apache.archiva.metadata.repository.MetadataRepositoryException;
import org.apache.archiva.metadata.repository.RepositorySession;
import org.apache.archiva.metadata.repository.RepositorySessionFactory;
-import org.apache.archiva.metadata.repository.stats.RepositoryStatisticsManager;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsManager;
import org.apache.archiva.redback.components.scheduler.CronExpressionValidator;
import org.apache.archiva.redback.components.scheduler.Scheduler;
import org.apache.archiva.redback.components.taskqueue.TaskQueue;
import org.apache.archiva.configuration.ArchivaConfiguration;
import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.archiva.metadata.repository.MetadataRepository;
-import org.apache.archiva.metadata.repository.stats.RepositoryStatisticsManager;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsManager;
import org.apache.archiva.mock.MockRepositorySessionFactory;
import org.apache.archiva.redback.components.taskqueue.execution.TaskExecutor;
import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
-import org.apache.commons.lang.StringUtils;
import org.codehaus.plexus.util.FileUtils;
import org.junit.After;
import org.junit.Before;
-import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import javax.inject.Named;
import java.io.File;
import java.util.Calendar;
-import java.util.List;
import static org.mockito.Mockito.mock;
*/
import org.apache.archiva.metadata.repository.MetadataRepositoryException;
-import org.apache.archiva.metadata.repository.stats.RepositoryStatistics;
+import org.apache.archiva.metadata.repository.stats.model.DefaultRepositoryStatistics;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatistics;
import org.apache.archiva.model.ArtifactReference;
import org.apache.archiva.scheduler.repository.model.RepositoryTask;
import org.codehaus.plexus.util.FileUtils;
throws MetadataRepositoryException
{
Date date = Calendar.getInstance().getTime();
- RepositoryStatistics stats = new RepositoryStatistics();
+ DefaultRepositoryStatistics stats = new DefaultRepositoryStatistics();
stats.setScanStartTime( new Date( date.getTime() - 1234567 ) );
stats.setScanEndTime( date );
stats.setNewFileCount( 31 );
import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.archiva.metadata.repository.MetadataRepositoryException;
-import org.apache.archiva.metadata.repository.stats.RepositoryStatistics;
-import org.apache.archiva.metadata.repository.stats.RepositoryStatisticsManager;
+import org.apache.archiva.metadata.repository.stats.model.DefaultRepositoryStatistics;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatistics;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsManager;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
{
List<RepositoryStatistics> stats = getStatsList( repositoryId );
- RepositoryStatistics repositoryStatistics = new RepositoryStatistics();
+ DefaultRepositoryStatistics repositoryStatistics = new DefaultRepositoryStatistics();
repositoryStatistics.setScanStartTime( startTime );
repositoryStatistics.setScanEndTime( endTime );
repositoryStatistics.setNewFileCount( newFiles );
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
import java.util.Date;
+import java.util.Map;
/**
* @author Olivier Lamy
private String lastScanDate;
+ private Map<String, Long> totalCountForType;
+
+ private Map<String, Long> customValues;
+
public ArchivaRepositoryStatistics()
{
// no op
this.lastScanDate = lastScanDate;
}
+ public void setTotalCountForType(Map<String, Long> totalCountForType) {
+ this.totalCountForType = totalCountForType;
+ }
+
+ public Map<String, Long> getTotalCountForType() {
+ return this.totalCountForType;
+ }
+
+ public void setCustomValues(Map<String,Long> customValues) {
+ this.customValues = customValues;
+ }
+
+ public Map<String,Long> getCustomValues() {
+ return this.customValues;
+ }
+
+
+
@Override
public String toString()
{
sb.append( ", newFileCount=" ).append( newFileCount );
sb.append( ", duration=" ).append( duration );
sb.append( ", lastScanDate='" ).append( lastScanDate ).append( '\'' );
+ addMapString( sb, totalCountForType );
+ addMapString( sb, customValues );
sb.append( '}' );
return sb.toString();
}
+
+ private void addMapString(StringBuilder builder, Map<String, Long> map) {
+ if (map!=null)
+ {
+ map.entrySet( ).stream( ).forEach( entry -> builder.append( ", " ).append( entry.getKey( ) ).append( '=' ).append( entry.getValue( ) ) );
+ }
+ }
}
*/
import org.apache.archiva.metadata.model.facets.RepositoryProblemFacet;
-import org.apache.archiva.metadata.repository.stats.RepositoryStatistics;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatistics;
import org.apache.archiva.redback.authorization.RedbackAuthorization;
import org.apache.archiva.security.common.ArchivaRoleConstants;
import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.archiva.metadata.repository.MetadataRepositoryException;
import org.apache.archiva.metadata.repository.RepositorySession;
-import org.apache.archiva.metadata.repository.stats.RepositoryStatistics;
-import org.apache.archiva.metadata.repository.stats.RepositoryStatisticsManager;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatistics;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsManager;
import org.apache.archiva.rest.api.model.ArchivaRepositoryStatistics;
import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
import org.apache.archiva.rest.api.services.ManagedRepositoriesService;
import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.archiva.metadata.repository.MetadataRepositoryException;
import org.apache.archiva.metadata.repository.RepositorySession;
-import org.apache.archiva.metadata.repository.stats.RepositoryStatistics;
-import org.apache.archiva.metadata.repository.stats.RepositoryStatisticsManager;
+import org.apache.archiva.metadata.repository.stats.model.DefaultRepositoryStatistics;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatistics;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsManager;
import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
import org.apache.archiva.rest.api.services.ReportRepositoriesService;
import org.apache.commons.lang.StringUtils;
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit-jcr-commons</artifactId>
+ </dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
* under the License.
*/
+import org.apache.archiva.webdav.util.RepositoryPathUtil;
import org.apache.jackrabbit.util.Text;
import org.apache.jackrabbit.webdav.DavLocatorFactory;
import org.apache.jackrabbit.webdav.DavResourceLocator;
-import org.apache.archiva.webdav.util.RepositoryPathUtil;
/**
*/
protected Logger log = LoggerFactory.getLogger( getClass() );
- protected static Map<String, MetadataFacetFactory> createTestMetadataFacetFactories()
+ public static Map<String, MetadataFacetFactory> createTestMetadataFacetFactories()
{
Map<String, MetadataFacetFactory> factories = new HashMap<>();
factories.put( TEST_FACET_ID, new MetadataFacetFactory()
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>metadata</artifactId>
+ <groupId>org.apache.archiva</groupId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>metadata-statistics-api</artifactId>
+ <packaging>bundle</packaging>
+ <name>Archiva Metadata :: Statistics API</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.archiva</groupId>
+ <artifactId>metadata-repository-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.archiva</groupId>
+ <artifactId>metadata-model-maven2</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>org.apache.archiva.metadata.repository.api</Bundle-SymbolicName>
+ <Bundle-Version>${project.version}</Bundle-Version>
+ <Export-Package>
+ org.apache.archiva.metadata.repository.stats.model;version=${project.version}
+ </Export-Package>
+ <Import-Package>
+ org.apache.archiva.metadata.model;version=${project.version},
+ org.apache.archiva.maven2.model;version=${project.version},
+ org.slf4j;resolution:=optional,
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+package org.apache.archiva.metadata.repository.stats.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.stream.Collectors;
+
+/**
+ * Default statistics implementation
+ */
+public class DefaultRepositoryStatistics
+ implements RepositoryStatistics
+{
+ private Date scanEndTime;
+
+ private Date scanStartTime;
+
+ private long totalArtifactCount;
+
+ private long totalArtifactFileSize;
+
+ private long totalFileCount;
+
+ private long totalGroupCount;
+
+ private long totalProjectCount;
+
+ private long newFileCount;
+
+ public static final String SCAN_TIMESTAMP_FORMAT = "yyyy/MM/dd/HHmmss.SSS";
+
+ private Map<String, Long> totalCountForType = new ZeroForNullHashMap<>();
+
+ private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" );
+
+ private String repositoryId;
+
+ private Map<String, Long> customValues;
+
+ public static final String TYPE_PREFIX = "count-type-";
+ public static final String CUSTOM_PREFIX = "count-custom-";
+
+ @Override
+ public Date getScanEndTime( )
+ {
+ return scanEndTime;
+ }
+
+ public void setScanEndTime( Date scanEndTime )
+ {
+ this.scanEndTime = scanEndTime;
+ }
+
+ @Override
+ public Date getScanStartTime( )
+ {
+ return scanStartTime;
+ }
+
+ public void setScanStartTime( Date scanStartTime )
+ {
+ this.scanStartTime = scanStartTime;
+ }
+
+ @Override
+ public long getTotalArtifactCount( )
+ {
+ return totalArtifactCount;
+ }
+
+ @Override
+ public void setTotalArtifactCount( long totalArtifactCount )
+ {
+ this.totalArtifactCount = totalArtifactCount;
+ }
+
+ @Override
+ public long getTotalArtifactFileSize( )
+ {
+ return totalArtifactFileSize;
+ }
+
+ @Override
+ public void setTotalArtifactFileSize( long totalArtifactFileSize )
+ {
+ this.totalArtifactFileSize = totalArtifactFileSize;
+ }
+
+ @Override
+ public long getTotalFileCount( )
+ {
+ return totalFileCount;
+ }
+
+ @Override
+ public void setTotalFileCount( long totalFileCount )
+ {
+ this.totalFileCount = totalFileCount;
+ }
+
+ @Override
+ public long getTotalGroupCount( )
+ {
+ return totalGroupCount;
+ }
+
+ @Override
+ public void setTotalGroupCount( long totalGroupCount )
+ {
+ this.totalGroupCount = totalGroupCount;
+ }
+
+ @Override
+ public long getTotalProjectCount( )
+ {
+ return totalProjectCount;
+ }
+
+ @Override
+ public void setTotalProjectCount( long totalProjectCount )
+ {
+ this.totalProjectCount = totalProjectCount;
+ }
+
+ @Override
+ public void setNewFileCount( long newFileCount )
+ {
+ this.newFileCount = newFileCount;
+ }
+
+ @Override
+ public long getNewFileCount( )
+ {
+ return newFileCount;
+ }
+
+ @Override
+ public long getDuration( )
+ {
+ return scanEndTime.getTime() - scanStartTime.getTime();
+ }
+
+ @Override
+ public String getRepositoryId( )
+ {
+ return repositoryId;
+ }
+
+ public void setRepositoryId( String repositoryId )
+ {
+ this.repositoryId = repositoryId;
+ }
+
+ @Override
+ public String getFacetId()
+ {
+ return FACET_ID;
+ }
+
+ @Override
+ public String getName()
+ {
+ return createNameFormat().format( scanStartTime );
+ }
+
+ private static SimpleDateFormat createNameFormat()
+ {
+ SimpleDateFormat fmt = new SimpleDateFormat( SCAN_TIMESTAMP_FORMAT );
+ fmt.setTimeZone( UTC_TIME_ZONE );
+ return fmt;
+ }
+
+ @Override
+ public Map<String, String> toProperties()
+ {
+ Map<String, String> properties = new HashMap<>();
+ if (scanEndTime==null) {
+ properties.put("scanEndTime", "0");
+ } else
+ {
+ properties.put( "scanEndTime", String.valueOf( scanEndTime.getTime( ) ) );
+ }
+ if (scanStartTime==null) {
+ properties.put("scanStartTime","0");
+ } else
+ {
+ properties.put( "scanStartTime", String.valueOf( scanStartTime.getTime( ) ) );
+ }
+ properties.put( "totalArtifactCount", String.valueOf( totalArtifactCount ) );
+ properties.put( "totalArtifactFileSize", String.valueOf( totalArtifactFileSize ) );
+ properties.put( "totalFileCount", String.valueOf( totalFileCount ) );
+ properties.put( "totalGroupCount", String.valueOf( totalGroupCount ) );
+ properties.put( "totalProjectCount", String.valueOf( totalProjectCount ) );
+ properties.put( "newFileCount", String.valueOf( newFileCount ) );
+ properties.put( "repositoryId", repositoryId );
+ for ( Map.Entry<String, Long> entry : totalCountForType.entrySet() )
+ {
+ properties.put( TYPE_PREFIX + entry.getKey(), String.valueOf( entry.getValue() ) );
+ }
+ if (customValues!=null) {
+ for (Map.Entry<String, Long> entry : customValues.entrySet()) {
+ properties.put(CUSTOM_PREFIX+entry.getKey(), String.valueOf(entry.getValue()));
+ }
+ }
+ return properties;
+ }
+
+ @Override
+ public void fromProperties( Map<String, String> properties )
+ {
+ scanEndTime = new Date( Long.parseLong( properties.get( "scanEndTime" ) ) );
+ scanStartTime = new Date( Long.parseLong( properties.get( "scanStartTime" ) ) );
+ totalArtifactCount = Long.parseLong( properties.get( "totalArtifactCount" ) );
+ totalArtifactFileSize = Long.parseLong( properties.get( "totalArtifactFileSize" ) );
+ totalFileCount = Long.parseLong( properties.get( "totalFileCount" ) );
+ totalGroupCount = Long.parseLong( properties.get( "totalGroupCount" ) );
+ totalProjectCount = Long.parseLong( properties.get( "totalProjectCount" ) );
+ newFileCount = Long.parseLong( properties.get( "newFileCount" ) );
+ repositoryId = properties.get( "repositoryId" );
+ totalCountForType.clear();
+ for ( Map.Entry<String, String> entry : properties.entrySet() )
+ {
+ if ( entry.getKey().startsWith( TYPE_PREFIX ) )
+ {
+ totalCountForType.put( entry.getKey().substring( TYPE_PREFIX.length() ), Long.valueOf( entry.getValue() ) );
+ } else if (entry.getKey().startsWith( CUSTOM_PREFIX )) {
+ if (customValues==null) {
+ createCustomValueMap();
+ }
+ customValues.put(entry.getKey().substring( CUSTOM_PREFIX.length() ), Long.valueOf(entry.getValue()));
+ }
+ }
+ }
+
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o )
+ {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() )
+ {
+ return false;
+ }
+
+ DefaultRepositoryStatistics that = (DefaultRepositoryStatistics) o;
+
+ if ( newFileCount != that.newFileCount )
+ {
+ return false;
+ }
+ if ( totalArtifactCount != that.totalArtifactCount )
+ {
+ return false;
+ }
+ if ( totalArtifactFileSize != that.totalArtifactFileSize )
+ {
+ return false;
+ }
+ if ( totalFileCount != that.totalFileCount )
+ {
+ return false;
+ }
+ if ( totalGroupCount != that.totalGroupCount )
+ {
+ return false;
+ }
+ if ( totalProjectCount != that.totalProjectCount )
+ {
+ return false;
+ }
+ if ( !scanEndTime.equals( that.scanEndTime ) )
+ {
+ return false;
+ }
+ if ( !scanStartTime.equals( that.scanStartTime ) )
+ {
+ return false;
+ }
+ if ( !totalCountForType.equals( that.totalCountForType ) )
+ {
+ return false;
+ }
+ if ( customValues==null && that.customValues!=null) {
+ return false;
+ }
+ if ( customValues!=null && that.customValues==null) {
+ return false;
+ }
+ if (customValues!=null && !customValues.equals(that.customValues)) {
+ return false;
+ }
+ return repositoryId.equals( that.repositoryId );
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int result = scanEndTime.hashCode();
+ result = 31 * result + scanStartTime.hashCode();
+ result = 31 * result + (int) ( totalArtifactCount ^ ( totalArtifactCount >>> 32 ) );
+ result = 31 * result + (int) ( totalArtifactFileSize ^ ( totalArtifactFileSize >>> 32 ) );
+ result = 31 * result + (int) ( totalFileCount ^ ( totalFileCount >>> 32 ) );
+ result = 31 * result + (int) ( totalGroupCount ^ ( totalGroupCount >>> 32 ) );
+ result = 31 * result + (int) ( totalProjectCount ^ ( totalProjectCount >>> 32 ) );
+ result = 31 * result + (int) ( newFileCount ^ ( newFileCount >>> 32 ) );
+ result = 31 * result + totalCountForType.hashCode();
+ result = 31 * result + repositoryId.hashCode();
+ if (customValues!=null)
+ result = 31 * result + customValues.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "RepositoryStatistics{" + "scanEndTime=" + scanEndTime + ", scanStartTime=" + scanStartTime +
+ ", totalArtifactCount=" + totalArtifactCount + ", totalArtifactFileSize=" + totalArtifactFileSize +
+ ", totalFileCount=" + totalFileCount + ", totalGroupCount=" + totalGroupCount + ", totalProjectCount=" +
+ totalProjectCount + ", newFileCount=" + newFileCount + ", totalCountForType=" + totalCountForType + ", " +
+ "repositoryId=" + repositoryId +
+ getCustomValueString() +
+ '}';
+ }
+
+ private String getCustomValueString() {
+ if (customValues==null) {
+ return "";
+ } else {
+ return customValues.entrySet().stream().map(entry -> entry.getKey()+"="+entry.getValue()).collect(
+ Collectors.joining( ",")
+ );
+ }
+ }
+
+ @Override
+ public Map<String, Long> getTotalCountForType( )
+ {
+ return totalCountForType;
+ }
+
+ @Override
+ public long getTotalCountForType( String type )
+ {
+ return totalCountForType.get( type );
+ }
+
+ @Override
+ public void setTotalCountForType( String type, long count )
+ {
+ totalCountForType.put( type, count );
+ }
+
+ @Override
+ public long getCustomValue( String fieldName )
+ {
+ // Lazy evaluation, because it may not be used very often.
+ if (customValues==null) {
+ createCustomValueMap();
+ }
+ return customValues.get(fieldName);
+ }
+
+ @Override
+ public void setCustomValue( String fieldName, long count )
+ {
+ // Lazy evaluation, because it may not be used very often.
+ if (customValues==null) {
+ createCustomValueMap();
+ }
+ customValues.put(fieldName, count);
+ }
+
+ private void createCustomValueMap( )
+ {
+ customValues = new ZeroForNullHashMap<>();
+ }
+
+
+ private static final class ZeroForNullHashMap<K> extends HashMap<K, Long>
+ {
+ @Override
+ public Long get(Object key) {
+ Long value = super.get( key );
+
+ return ( value != null ) ? value : Long.valueOf( 0L );
+ }
+ }
+}
--- /dev/null
+package org.apache.archiva.metadata.repository.stats.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.metadata.model.MetadataFacet;
+
+import java.util.Date;
+import java.util.Map;
+
+/**
+ *
+ * Provides statistics data of metadata repositories.
+ *
+ * @since 2.3
+ */
+public interface RepositoryStatistics extends MetadataFacet
+{
+ String FACET_ID = "org.apache.archiva.metadata.repository.stats";
+
+ String getRepositoryId( );
+
+ Date getScanEndTime( );
+
+ Date getScanStartTime( );
+
+ long getTotalArtifactCount( );
+
+ void setTotalArtifactCount( long totalArtifactCount );
+
+ long getTotalArtifactFileSize( );
+
+ void setTotalArtifactFileSize( long totalArtifactFileSize );
+
+ long getTotalFileCount( );
+
+ void setTotalFileCount( long totalFileCount );
+
+ long getTotalGroupCount( );
+
+ void setTotalGroupCount( long totalGroupCount );
+
+ long getTotalProjectCount( );
+
+ void setTotalProjectCount( long totalProjectCount );
+
+ void setNewFileCount( long newFileCount );
+
+ long getNewFileCount( );
+
+ long getDuration( );
+
+ /**
+ * Statistics data by artifact type.
+ *
+ * @return A list of data keys and values
+ */
+ Map<String, Long> getTotalCountForType( );
+
+ /**
+ * Returns the value for the given artifact type.
+ *
+ * @param type The artifact type
+ * @return The count value.
+ */
+ long getTotalCountForType( String type );
+
+ /**
+ * Sets the value for the given artifact type.
+ * @param type The artifact type.
+ * @param count The count value.
+ */
+ void setTotalCountForType( String type, long count );
+
+ /**
+ * Reads custom statistic values that are store implementation
+ * specific.
+ *
+ * @param fieldName A unique field name.
+ */
+ long getCustomValue(String fieldName);
+
+ /**
+ * Saves custom statistic values that are store implementation
+ * specific. The field name should be unique (e.g. prefixed by the
+ * package name of the data provider).
+ *
+ * @param fieldName A unique field name.
+ * @param count The statistic counter value
+ */
+ void setCustomValue(String fieldName, long count);
+
+}
--- /dev/null
+package org.apache.archiva.metadata.repository.stats.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.metadata.repository.MetadataRepository;
+import org.apache.archiva.metadata.repository.MetadataRepositoryException;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * The statistics manager is the central entry point for handling repository
+ * statistics data.
+ *
+ *
+ */
+public interface RepositoryStatisticsManager
+{
+ RepositoryStatistics getLastStatistics( MetadataRepository metadataRepository, String repositoryId )
+ throws MetadataRepositoryException;
+
+ boolean hasStatistics( MetadataRepository metadataRepository, String repositoryId )
+ throws MetadataRepositoryException;
+
+ void addStatisticsAfterScan( MetadataRepository metadataRepository, String repositoryId, Date startTime,
+ Date endTime, long totalFiles, long newFiles )
+ throws MetadataRepositoryException;
+
+ void deleteStatistics( MetadataRepository metadataRepository, String repositoryId )
+ throws MetadataRepositoryException;
+
+ List<RepositoryStatistics> getStatisticsInRange( MetadataRepository metadataRepository, String repositoryId,
+ Date startTime, Date endTime )
+ throws MetadataRepositoryException;
+}
--- /dev/null
+package org.apache.archiva.metadata.repository.stats.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.metadata.repository.MetadataRepository;
+import org.apache.archiva.metadata.repository.MetadataRepositoryException;
+
+/**
+ *
+ * This interface is used for populating statistics data. It should be implemented
+ * by metadata store implementations in the MetadataRepository class, if the store
+ * implementation can provide a faster implementation than walking the tree.
+ *
+ * @author Martin Stockhammer
+ * @since 2.3
+ */
+public interface RepositoryStatisticsProvider
+{
+
+ /**
+ * Populate the statistics object with the statistics data of this repository.
+ *
+ * @param repository The current metadata repository implementation
+ * @param repositoryId The repository Id
+ * @param statistics The statistics object that should be filled.
+ * @throws MetadataRepositoryException Is thrown, if an error occurs while accessing the repository
+ */
+ void populateStatistics( MetadataRepository repository, String repositoryId, RepositoryStatistics statistics)
+ throws MetadataRepositoryException;
+}
--- /dev/null
+package org.apache.archiva.metadata.repository.stats.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.metadata.model.ArtifactMetadata;
+import org.apache.archiva.metadata.model.maven2.MavenArtifactFacet;
+import org.apache.archiva.metadata.repository.MetadataRepository;
+import org.apache.archiva.metadata.repository.MetadataRepositoryException;
+import org.apache.archiva.metadata.repository.MetadataResolutionException;
+
+import java.util.Collection;
+
+/**
+ *
+ * This is a default implementation of a statistics provider that walks the tree and
+ * counts the artifacts found during the walk.
+ * The implementation is not very fast. If metadata store provider can improve the
+ * process by using store specific techniques (like query language) they should provide
+ * their own implementation.
+ *
+ * @author Martin Stockhammer
+ */
+public class RepositoryWalkingStatisticsProvider implements RepositoryStatisticsProvider
+{
+
+ /**
+ * Walks each namespace of the given repository id and counts the artifacts.
+ *
+ * @param metadataRepository The repository implementation
+ * @param repositoryId The repository Id
+ * @param repositoryStatistics The statistics object that must be populated
+ * @throws MetadataRepositoryException Throws the repository exception, if an error occurs while accessing the repository.
+ */
+ @Override
+ public void populateStatistics( MetadataRepository metadataRepository, String repositoryId,
+ RepositoryStatistics repositoryStatistics )
+ throws MetadataRepositoryException
+ {
+ try
+ {
+ for ( String ns : metadataRepository.getRootNamespaces( repositoryId ) )
+ {
+ walkRepository( metadataRepository, repositoryStatistics, repositoryId, ns );
+ }
+ }
+ catch ( MetadataResolutionException e )
+ {
+ throw new MetadataRepositoryException( e.getMessage(), e );
+ }
+ }
+
+ private void walkRepository( MetadataRepository metadataRepository, RepositoryStatistics stats, String repositoryId,
+ String ns )
+ throws MetadataResolutionException
+ {
+ for ( String namespace : metadataRepository.getNamespaces( repositoryId, ns ) )
+ {
+ walkRepository( metadataRepository, stats, repositoryId, ns + "." + namespace );
+ }
+
+ Collection<String> projects = metadataRepository.getProjects( repositoryId, ns );
+ if ( !projects.isEmpty() )
+ {
+ stats.setTotalGroupCount( stats.getTotalGroupCount() + 1 );
+ stats.setTotalProjectCount( stats.getTotalProjectCount() + projects.size() );
+
+ for ( String project : projects )
+ {
+ for ( String version : metadataRepository.getProjectVersions( repositoryId, ns, project ) )
+ {
+ for ( ArtifactMetadata artifact : metadataRepository.getArtifacts( repositoryId, ns, project,
+ version ) )
+ {
+ stats.setTotalArtifactCount( stats.getTotalArtifactCount() + 1 );
+ stats.setTotalArtifactFileSize( stats.getTotalArtifactFileSize() + artifact.getSize() );
+
+ MavenArtifactFacet facet =
+ (MavenArtifactFacet) artifact.getFacet( MavenArtifactFacet.FACET_ID );
+ if ( facet != null )
+ {
+ String type = facet.getType();
+ stats.setTotalCountForType( type, stats.getTotalCountForType( type ) + 1 );
+ }
+ }
+ }
+ }
+ }
+ }
+}
--- /dev/null
+package org.apache.archiva.metadata.repository.stats.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.junit.Test;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public class DefaultRepositoryStatisticsTest
+{
+ @Test
+ public void toProperties( ) throws Exception
+ {
+ DefaultRepositoryStatistics stats = new DefaultRepositoryStatistics();
+ Date startTime = new Date();
+ Date endTime = new Date();
+ stats.setScanStartTime( startTime );
+ stats.setScanEndTime( endTime );
+ stats.setTotalFileCount( 500 );
+ stats.setNewFileCount( 10 );
+ stats.setRepositoryId( "test-repo" );
+ stats.setTotalArtifactCount( 300 );
+ stats.setTotalArtifactFileSize( 4848484 );
+ stats.setTotalGroupCount( 4 );
+ stats.setTotalProjectCount( 6 );
+ stats.setCustomValue( "test.value.1", 55 );
+ stats.setCustomValue( "test.value.2", 44);
+ stats.setTotalCountForType( "java-source",13 );
+ stats.setTotalCountForType( "pom", 5 );
+
+ Map<String, String> props = stats.toProperties( );
+
+ assertEquals( "500", props.get("totalFileCount") );
+ assertEquals( "10", props.get("newFileCount"));
+ assertEquals( "300", props.get("totalArtifactCount"));
+ assertEquals( "4848484", props.get("totalArtifactFileSize"));
+ assertEquals("4", props.get("totalGroupCount"));
+ assertEquals("6", props.get("totalProjectCount"));
+ assertEquals("55",props.get("count-custom-test.value.1" ));
+ assertEquals("44", props.get("count-custom-test.value.2"));
+ assertEquals("13", props.get("count-type-java-source"));
+ assertEquals("5", props.get("count-type-pom"));
+ assertEquals( String.valueOf(startTime.getTime()), props.get("scanStartTime"));
+ assertEquals( String.valueOf(endTime.getTime()), props.get("scanEndTime"));
+ }
+
+ @Test
+ public void fromProperties( ) throws Exception
+ {
+ DefaultRepositoryStatistics stats = new DefaultRepositoryStatistics( );
+ Date startTime = new Date();
+ Date endTime = new Date();
+ Map<String,String> props = new HashMap<>( );
+ props.put("totalFileCount","501");
+ props.put("newFileCount","11");
+ props.put("totalArtifactCount","301");
+ props.put("totalArtifactFileSize","473565557");
+ props.put("totalGroupCount","5");
+ props.put("totalProjectCount","7");
+ props.put("count-custom-test.value.1","56");
+ props.put("count-custom-test.value.2","45");
+ props.put("count-type-java-source","14");
+ props.put("count-type-pom","6");
+ props.put("scanStartTime", String.valueOf(startTime.getTime()));
+ props.put("scanEndTime", String.valueOf(endTime.getTime()));
+
+ stats.fromProperties( props );
+
+ assertEquals(501,stats.getTotalFileCount());
+ assertEquals(11,stats.getNewFileCount());
+ assertEquals(301, stats.getTotalArtifactCount());
+ assertEquals(473565557, stats.getTotalArtifactFileSize());
+ assertEquals(5, stats.getTotalGroupCount());
+ assertEquals(7, stats.getTotalProjectCount());
+ assertEquals(56, stats.getCustomValue( "test.value.1" ));
+ assertEquals(45, stats.getCustomValue( "test.value.2" ));
+ assertEquals(14, stats.getTotalCountForType( "java-source" ));
+ assertEquals(6, stats.getTotalCountForType( "pom" ));
+ assertEquals(startTime, stats.getScanStartTime());
+ assertEquals( endTime, stats.getScanEndTime() );
+ }
+
+
+
+}
\ No newline at end of file
<module>metadata-model</module>
<module>metadata-repository-api</module>
<module>metadata-model-maven2</module>
+ <module>metadata-statistics-api</module>
<module>test-repository</module>
</modules>
</project>
\ No newline at end of file
<groupId>org.apache.archiva</groupId>
<artifactId>metadata-repository-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.archiva</groupId>
+ <artifactId>metadata-statistics-api</artifactId>
+ </dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<directory>src/test/filtered-resources</directory>
<filtering>true</filtering>
</testResource>
+ <testResource>
+ <directory>src/test/resources</directory>
+ <filtering>false</filtering>
+ </testResource>
</testResources>
<plugins>
<plugin>
import org.apache.archiva.metadata.model.ProjectVersionMetadata;
import org.apache.archiva.metadata.model.ProjectVersionReference;
import org.apache.archiva.metadata.model.Scm;
+import org.apache.archiva.metadata.model.maven2.MavenArtifactFacet;
import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.archiva.metadata.repository.MetadataRepositoryException;
import org.apache.archiva.metadata.repository.MetadataResolutionException;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatistics;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsProvider;
import org.apache.commons.lang.StringUtils;
import org.apache.jackrabbit.commons.JcrUtils;
import org.slf4j.Logger;
import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.nodetype.NodeTypeTemplate;
import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.jcr.query.Row;
import javax.jcr.query.RowIterator;
* TODO revise reference storage
*/
public class JcrMetadataRepository
- implements MetadataRepository
+ implements MetadataRepository,RepositoryStatisticsProvider
{
private static final String JCR_LAST_MODIFIED = "jcr:lastModified";
}
- static void initialize( Session session )
+ public static void initialize( Session session )
throws RepositoryException
{
}
return this.jcrSession;
}
+
+ @Override
+ public void populateStatistics( MetadataRepository repository, String repositoryId,
+ RepositoryStatistics repositoryStatistics )
+ throws MetadataRepositoryException
+ {
+ if (!(repository instanceof JcrMetadataRepository)) {
+ throw new MetadataRepositoryException( "The statistics population is only possible for JcrMetdataRepository implementations" );
+ }
+ Session session = (Session) repository.obtainAccess( Session.class );
+ // TODO: these may be best as running totals, maintained by observations on the properties in JCR
+
+ try
+ {
+ QueryManager queryManager = session.getWorkspace().getQueryManager();
+
+ // TODO: JCR-SQL2 query will not complete on a large repo in Jackrabbit 2.2.0 - see JCR-2835
+ // Using the JCR-SQL2 variants gives
+ // "org.apache.lucene.search.BooleanQuery$TooManyClauses: maxClauseCount is set to 1024"
+// String whereClause = "WHERE ISDESCENDANTNODE([/repositories/" + repositoryId + "/content])";
+// Query query = queryManager.createQuery( "SELECT size FROM [archiva:artifact] " + whereClause,
+// Query.JCR_SQL2 );
+ String whereClause = "WHERE jcr:path LIKE '/repositories/" + repositoryId + "/content/%'";
+ Query query = queryManager.createQuery( "SELECT size FROM archiva:artifact " + whereClause, Query.SQL );
+
+ QueryResult queryResult = query.execute();
+
+ Map<String, Integer> totalByType = new HashMap<>();
+ long totalSize = 0, totalArtifacts = 0;
+ for ( Row row : JcrUtils.getRows( queryResult ) )
+ {
+ Node n = row.getNode();
+ totalSize += row.getValue( "size" ).getLong();
+
+ String type;
+ if ( n.hasNode( MavenArtifactFacet.FACET_ID ) )
+ {
+ Node facetNode = n.getNode( MavenArtifactFacet.FACET_ID );
+ type = facetNode.getProperty( "type" ).getString();
+ }
+ else
+ {
+ type = "Other";
+ }
+ Integer prev = totalByType.get( type );
+ totalByType.put( type, prev != null ? prev + 1 : 1 );
+
+ totalArtifacts++;
+ }
+
+ repositoryStatistics.setTotalArtifactCount( totalArtifacts );
+ repositoryStatistics.setTotalArtifactFileSize( totalSize );
+ for ( Map.Entry<String, Integer> entry : totalByType.entrySet() )
+ {
+ System.out.println("Setting count for type: "+entry.getKey()+" = "+entry.getValue());
+ repositoryStatistics.setTotalCountForType( entry.getKey(), entry.getValue() );
+ }
+
+ // The query ordering is a trick to ensure that the size is correct, otherwise due to lazy init it will be -1
+// query = queryManager.createQuery( "SELECT * FROM [archiva:project] " + whereClause, Query.JCR_SQL2 );
+ query = queryManager.createQuery( "SELECT * FROM archiva:project " + whereClause + " ORDER BY jcr:score",
+ Query.SQL );
+ repositoryStatistics.setTotalProjectCount( query.execute().getRows().getSize() );
+
+// query = queryManager.createQuery(
+// "SELECT * FROM [archiva:namespace] " + whereClause + " AND namespace IS NOT NULL", Query.JCR_SQL2 );
+ query = queryManager.createQuery(
+ "SELECT * FROM archiva:namespace " + whereClause + " AND namespace IS NOT NULL ORDER BY jcr:score",
+ Query.SQL );
+ repositoryStatistics.setTotalGroupCount( query.execute().getRows().getSize() );
+ }
+ catch ( RepositoryException e )
+ {
+ throw new MetadataRepositoryException( e.getMessage(), e );
+ }
+ }
+
}
--- /dev/null
+package org.apache.archiva.metadata.repository.stats;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+import org.apache.archiva.metadata.model.MetadataFacetFactory;
+import org.apache.archiva.metadata.repository.AbstractMetadataRepositoryTest;
+import org.apache.archiva.metadata.repository.RepositorySessionFactory;
+import org.apache.archiva.metadata.repository.jcr.JcrMetadataRepository;
+import org.apache.archiva.metadata.repository.stats.model.DefaultRepositoryStatistics;
+import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner;
+import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
+import org.apache.commons.io.FileUtils;
+import org.apache.jackrabbit.commons.JcrUtils;
+import org.apache.jackrabbit.core.TransientRepository;
+import org.apache.jackrabbit.core.config.RepositoryConfig;
+import org.apache.regexp.RE;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.context.ContextConfiguration;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.jcr.ImportUUIDBehavior;
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.Workspace;
+import javax.jcr.nodetype.NodeTypeManager;
+import javax.jcr.nodetype.NodeTypeTemplate;
+import java.io.File;
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Map;
+import java.util.zip.GZIPInputStream;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith( ArchivaSpringJUnit4ClassRunner.class )
+@ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context.xml" } )
+public class JcrRepositoryStatisticsGatheringTest extends TestCase
+
+{
+ private static final int TOTAL_FILE_COUNT = 1000;
+
+ private static final int NEW_FILE_COUNT = 500;
+
+ private static final String TEST_REPO = "test-repo";
+
+ JcrMetadataRepository repository;
+
+ @Inject
+ private RepositorySessionFactory repositorySessionFactory;
+
+ @Inject
+ private ApplicationContext applicationContext;
+
+ @Inject
+ @Named("repository")
+ Repository jcrRepository;
+
+ Session session;
+
+
+
+
+ @Before
+ public void setUp()
+ throws Exception
+ {
+
+ File directory = new File( "target/test-repositories" );
+ if ( directory.exists() )
+ {
+ FileUtils.deleteDirectory( directory );
+ }
+
+ Map<String, MetadataFacetFactory> factories = AbstractMetadataRepositoryTest.createTestMetadataFacetFactories();
+
+ assertNotNull( jcrRepository );
+ // TODO: probably don't need to use Spring for this
+ JcrMetadataRepository jcrMetadataRepository = new JcrMetadataRepository( factories, jcrRepository );
+
+ try
+ {
+ session = jcrMetadataRepository.getJcrSession();
+
+ // set up namespaces, etc.
+ JcrMetadataRepository.initialize( session );
+
+ // removing content is faster than deleting and re-copying the files from target/jcr
+ session.getRootNode().getNode( "repositories" ).remove();
+ }
+ catch ( RepositoryException e )
+ {
+ // ignore
+ }
+
+ this.repository = jcrMetadataRepository;
+ }
+
+ private static void registerMixinNodeType( NodeTypeManager nodeTypeManager, String type )
+ throws RepositoryException
+ {
+ NodeTypeTemplate nodeType = nodeTypeManager.createNodeTypeTemplate();
+ nodeType.setMixin( true );
+ nodeType.setName( type );
+ nodeTypeManager.registerNodeType( nodeType, false );
+ }
+
+ @After
+ public void tearDown()
+ throws Exception
+ {
+ if (repository!=null)
+ {
+ repository.close( );
+ }
+
+ }
+
+ @Test
+ public void testJcrStatisticsQuery()
+ throws Exception
+ {
+ Calendar cal = Calendar.getInstance();
+ Date endTime = cal.getTime();
+ cal.add( Calendar.HOUR, -1 );
+ Date startTime = cal.getTime();
+
+ loadContentIntoRepo( TEST_REPO );
+ loadContentIntoRepo( "another-repo" );
+
+ DefaultRepositoryStatistics testedStatistics = new DefaultRepositoryStatistics();
+ testedStatistics.setNewFileCount( NEW_FILE_COUNT );
+ testedStatistics.setTotalFileCount( TOTAL_FILE_COUNT );
+ testedStatistics.setScanStartTime( startTime );
+ testedStatistics.setScanEndTime( endTime );
+
+ repository.populateStatistics( repository, TEST_REPO, testedStatistics );
+
+ DefaultRepositoryStatistics expectedStatistics = new DefaultRepositoryStatistics();
+ expectedStatistics.setNewFileCount( NEW_FILE_COUNT );
+ expectedStatistics.setTotalFileCount( TOTAL_FILE_COUNT );
+ expectedStatistics.setScanEndTime( endTime );
+ expectedStatistics.setScanStartTime( startTime );
+ expectedStatistics.setTotalArtifactFileSize( 95954585 );
+ expectedStatistics.setTotalArtifactCount( 269 );
+ expectedStatistics.setTotalGroupCount( 1 );
+ expectedStatistics.setTotalProjectCount( 43 );
+ expectedStatistics.setTotalCountForType( "zip", 1 );
+ expectedStatistics.setTotalCountForType( "gz", 1 ); // FIXME: should be tar.gz
+ expectedStatistics.setTotalCountForType( "java-source", 10 );
+ expectedStatistics.setTotalCountForType( "jar", 108 );
+ expectedStatistics.setTotalCountForType( "xml", 3 );
+ expectedStatistics.setTotalCountForType( "war", 2 );
+ expectedStatistics.setTotalCountForType( "pom", 144 );
+ expectedStatistics.setRepositoryId( TEST_REPO );
+
+ System.out.println(testedStatistics.getTotalCountForType());
+
+ assertEquals( NEW_FILE_COUNT, testedStatistics.getNewFileCount());
+ assertEquals( TOTAL_FILE_COUNT, testedStatistics.getTotalFileCount() );
+ assertEquals( endTime, testedStatistics.getScanEndTime() );
+ assertEquals( startTime, testedStatistics.getScanStartTime() );
+ assertEquals( 95954585, testedStatistics.getTotalArtifactFileSize() );
+ assertEquals( 269, testedStatistics.getTotalArtifactCount() );
+ assertEquals( 1, testedStatistics.getTotalGroupCount() );
+ assertEquals( 43, testedStatistics.getTotalProjectCount() );
+ assertEquals( 1, testedStatistics.getTotalCountForType( "zip" ) );
+ assertEquals( 1, testedStatistics.getTotalCountForType( "gz" ) );
+ assertEquals( 10, testedStatistics.getTotalCountForType( "java-source" ) );
+ assertEquals( 108, testedStatistics.getTotalCountForType( "jar" ) );
+ assertEquals( 3, testedStatistics.getTotalCountForType( "xml" ) );
+ assertEquals( 2, testedStatistics.getTotalCountForType( "war" ) );
+ assertEquals( 144, testedStatistics.getTotalCountForType( "pom" ) );
+ assertEquals( 10, testedStatistics.getTotalCountForType( "java-source" ) );
+
+
+ }
+
+ private void loadContentIntoRepo( String repoId )
+ throws RepositoryException, IOException
+ {
+ Node n = JcrUtils.getOrAddNode( session.getRootNode(), "repositories" );
+ n = JcrUtils.getOrAddNode( n, repoId );
+ n = JcrUtils.getOrAddNode( n, "content" );
+ n = JcrUtils.getOrAddNode( n, "org" );
+ n = JcrUtils.getOrAddNode( n, "apache" );
+
+ GZIPInputStream inputStream = new GZIPInputStream( getClass().getResourceAsStream( "/artifacts.xml.gz" ) );
+ session.importXML( n.getPath(), inputStream, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW );
+ session.save();
+ }
+}
<groupId>org.apache.archiva</groupId>
<artifactId>metadata-repository-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.archiva</groupId>
+ <artifactId>metadata-statistics-api</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>metadata-model-maven2</artifactId>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
- <dependency>
- <groupId>javax.jcr</groupId>
- <artifactId>jcr</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>jackrabbit-jcr-commons</artifactId>
- </dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-test-utils</artifactId>
<artifactId>log4j-jcl</artifactId>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>jackrabbit-core</artifactId>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
* under the License.
*/
-import org.apache.archiva.metadata.model.ArtifactMetadata;
-import org.apache.archiva.metadata.model.maven2.MavenArtifactFacet;
import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.archiva.metadata.repository.MetadataRepositoryException;
-import org.apache.archiva.metadata.repository.MetadataResolutionException;
+import org.apache.archiva.metadata.repository.stats.model.DefaultRepositoryStatistics;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatistics;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsManager;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsProvider;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryWalkingStatisticsProvider;
import org.apache.commons.lang.time.StopWatch;
-import org.apache.jackrabbit.commons.JcrUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.Date;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.TimeZone;
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.query.Query;
-import javax.jcr.query.QueryManager;
-import javax.jcr.query.QueryResult;
-import javax.jcr.query.Row;
/**
*
private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" );
+ private RepositoryWalkingStatisticsProvider walkingProvider = new RepositoryWalkingStatisticsProvider();
+
@Override
public boolean hasStatistics( MetadataRepository metadataRepository, String repositoryId )
throws MetadataRepositoryException
{
- return metadataRepository.hasMetadataFacet( repositoryId, RepositoryStatistics.FACET_ID );
+ return metadataRepository.hasMetadataFacet( repositoryId, DefaultRepositoryStatistics.FACET_ID );
}
@Override
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// TODO: consider a more efficient implementation that directly gets the last one from the content repository
- List<String> scans = metadataRepository.getMetadataFacets( repositoryId, RepositoryStatistics.FACET_ID );
+ List<String> scans = metadataRepository.getMetadataFacets( repositoryId, DefaultRepositoryStatistics.FACET_ID );
if ( scans == null )
{
return null;
}
}
- private void walkRepository( MetadataRepository metadataRepository, RepositoryStatistics stats, String repositoryId,
- String ns )
- throws MetadataResolutionException
- {
- for ( String namespace : metadataRepository.getNamespaces( repositoryId, ns ) )
- {
- walkRepository( metadataRepository, stats, repositoryId, ns + "." + namespace );
- }
-
- Collection<String> projects = metadataRepository.getProjects( repositoryId, ns );
- if ( !projects.isEmpty() )
- {
- stats.setTotalGroupCount( stats.getTotalGroupCount() + 1 );
- stats.setTotalProjectCount( stats.getTotalProjectCount() + projects.size() );
-
- for ( String project : projects )
- {
- for ( String version : metadataRepository.getProjectVersions( repositoryId, ns, project ) )
- {
- for ( ArtifactMetadata artifact : metadataRepository.getArtifacts( repositoryId, ns, project,
- version ) )
- {
- stats.setTotalArtifactCount( stats.getTotalArtifactCount() + 1 );
- stats.setTotalArtifactFileSize( stats.getTotalArtifactFileSize() + artifact.getSize() );
-
- MavenArtifactFacet facet =
- (MavenArtifactFacet) artifact.getFacet( MavenArtifactFacet.FACET_ID );
- if ( facet != null )
- {
- String type = facet.getType();
- stats.setTotalCountForType( type, stats.getTotalCountForType( type ) + 1 );
- }
- }
- }
- }
- }
- }
-
@Override
public void addStatisticsAfterScan( MetadataRepository metadataRepository, String repositoryId, Date startTime,
Date endTime, long totalFiles, long newFiles )
throws MetadataRepositoryException
{
- RepositoryStatistics repositoryStatistics = new RepositoryStatistics();
+ DefaultRepositoryStatistics repositoryStatistics = new DefaultRepositoryStatistics();
repositoryStatistics.setRepositoryId( repositoryId );
repositoryStatistics.setScanStartTime( startTime );
repositoryStatistics.setScanEndTime( endTime );
long startGather = System.currentTimeMillis();
- // FIXME what about other implementations ?
-
- if ( metadataRepository.canObtainAccess( Session.class ) )
+ if ( metadataRepository instanceof RepositoryStatisticsProvider)
{
- // TODO: this is currently very raw and susceptible to changes in content structure. Should we instead
- // depend directly on the plugin and interrogate the JCR repository's knowledge of the structure?
- populateStatisticsFromJcr( (Session) metadataRepository.obtainAccess( Session.class ), repositoryId,
- repositoryStatistics );
+ ((RepositoryStatisticsProvider)metadataRepository).populateStatistics( metadataRepository,
+ repositoryId, repositoryStatistics);
}
else
{
- // TODO:
- // if the file repository is used more permanently, we may seek a more efficient mechanism - e.g. we could
- // build an index, or store the aggregate information and update it on the fly. We can perhaps even walk
- // but retrieve less information to speed it up. In the mean time, we walk the repository using the
- // standard APIs
- populateStatisticsFromRepositoryWalk( metadataRepository, repositoryId, repositoryStatistics );
+ walkingProvider.populateStatistics( metadataRepository, repositoryId, repositoryStatistics );
}
log.info( "Gathering statistics executed in {} ms", ( System.currentTimeMillis() - startGather ) );
metadataRepository.addMetadataFacet( repositoryId, repositoryStatistics );
}
- private void populateStatisticsFromJcr( Session session, String repositoryId,
- RepositoryStatistics repositoryStatistics )
- throws MetadataRepositoryException
- {
- // TODO: these may be best as running totals, maintained by observations on the properties in JCR
-
- try
- {
- QueryManager queryManager = session.getWorkspace().getQueryManager();
-
- // TODO: JCR-SQL2 query will not complete on a large repo in Jackrabbit 2.2.0 - see JCR-2835
- // Using the JCR-SQL2 variants gives
- // "org.apache.lucene.search.BooleanQuery$TooManyClauses: maxClauseCount is set to 1024"
-// String whereClause = "WHERE ISDESCENDANTNODE([/repositories/" + repositoryId + "/content])";
-// Query query = queryManager.createQuery( "SELECT size FROM [archiva:artifact] " + whereClause,
-// Query.JCR_SQL2 );
- String whereClause = "WHERE jcr:path LIKE '/repositories/" + repositoryId + "/content/%'";
- Query query = queryManager.createQuery( "SELECT size FROM archiva:artifact " + whereClause, Query.SQL );
-
- QueryResult queryResult = query.execute();
-
- Map<String, Integer> totalByType = new HashMap<>();
- long totalSize = 0, totalArtifacts = 0;
- for ( Row row : JcrUtils.getRows( queryResult ) )
- {
- Node n = row.getNode();
- totalSize += row.getValue( "size" ).getLong();
-
- String type;
- if ( n.hasNode( MavenArtifactFacet.FACET_ID ) )
- {
- Node facetNode = n.getNode( MavenArtifactFacet.FACET_ID );
- type = facetNode.getProperty( "type" ).getString();
- }
- else
- {
- type = "Other";
- }
- Integer prev = totalByType.get( type );
- totalByType.put( type, prev != null ? prev + 1 : 1 );
-
- totalArtifacts++;
- }
-
- repositoryStatistics.setTotalArtifactCount( totalArtifacts );
- repositoryStatistics.setTotalArtifactFileSize( totalSize );
- for ( Map.Entry<String, Integer> entry : totalByType.entrySet() )
- {
- repositoryStatistics.setTotalCountForType( entry.getKey(), entry.getValue() );
- }
-
- // The query ordering is a trick to ensure that the size is correct, otherwise due to lazy init it will be -1
-// query = queryManager.createQuery( "SELECT * FROM [archiva:project] " + whereClause, Query.JCR_SQL2 );
- query = queryManager.createQuery( "SELECT * FROM archiva:project " + whereClause + " ORDER BY jcr:score",
- Query.SQL );
- repositoryStatistics.setTotalProjectCount( query.execute().getRows().getSize() );
-
-// query = queryManager.createQuery(
-// "SELECT * FROM [archiva:namespace] " + whereClause + " AND namespace IS NOT NULL", Query.JCR_SQL2 );
- query = queryManager.createQuery(
- "SELECT * FROM archiva:namespace " + whereClause + " AND namespace IS NOT NULL ORDER BY jcr:score",
- Query.SQL );
- repositoryStatistics.setTotalGroupCount( query.execute().getRows().getSize() );
- }
- catch ( RepositoryException e )
- {
- throw new MetadataRepositoryException( e.getMessage(), e );
- }
- }
-
- private void populateStatisticsFromRepositoryWalk( MetadataRepository metadataRepository, String repositoryId,
- RepositoryStatistics repositoryStatistics )
- throws MetadataRepositoryException
- {
- try
- {
- for ( String ns : metadataRepository.getRootNamespaces( repositoryId ) )
- {
- walkRepository( metadataRepository, repositoryStatistics, repositoryId, ns );
- }
- }
- catch ( MetadataResolutionException e )
- {
- throw new MetadataRepositoryException( e.getMessage(), e );
- }
- }
-
@Override
public void deleteStatistics( MetadataRepository metadataRepository, String repositoryId )
throws MetadataRepositoryException
{
- metadataRepository.removeMetadataFacets( repositoryId, RepositoryStatistics.FACET_ID );
+ metadataRepository.removeMetadataFacets( repositoryId, DefaultRepositoryStatistics.FACET_ID );
}
@Override
throws MetadataRepositoryException
{
List<RepositoryStatistics> results = new ArrayList<>();
- List<String> list = metadataRepository.getMetadataFacets( repositoryId, RepositoryStatistics.FACET_ID );
+ List<String> list = metadataRepository.getMetadataFacets( repositoryId, DefaultRepositoryStatistics.FACET_ID );
Collections.sort( list, Collections.reverseOrder() );
for ( String name : list )
{
{
RepositoryStatistics stats =
(RepositoryStatistics) metadataRepository.getMetadataFacet( repositoryId,
- RepositoryStatistics.FACET_ID,
+ DefaultRepositoryStatistics.FACET_ID,
name );
results.add( stats );
}
private static SimpleDateFormat createNameFormat()
{
- SimpleDateFormat fmt = new SimpleDateFormat( RepositoryStatistics.SCAN_TIMESTAMP_FORMAT );
+ SimpleDateFormat fmt = new SimpleDateFormat( DefaultRepositoryStatistics.SCAN_TIMESTAMP_FORMAT );
fmt.setTimeZone( UTC_TIME_ZONE );
return fmt;
}
+++ /dev/null
-package org.apache.archiva.metadata.repository.stats;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import org.apache.archiva.metadata.model.MetadataFacet;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TimeZone;
-
-public class RepositoryStatistics
- implements MetadataFacet
-{
- private Date scanEndTime;
-
- private Date scanStartTime;
-
- private long totalArtifactCount;
-
- private long totalArtifactFileSize;
-
- private long totalFileCount;
-
- private long totalGroupCount;
-
- private long totalProjectCount;
-
- private long newFileCount;
-
- public static String FACET_ID = "org.apache.archiva.metadata.repository.stats";
-
- static final String SCAN_TIMESTAMP_FORMAT = "yyyy/MM/dd/HHmmss.SSS";
-
- private Map<String, Long> totalCountForType = new ZeroForNullHashMap<String, Long>();
-
- private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" );
-
- private String repositoryId;
-
- public Date getScanEndTime()
- {
- return scanEndTime;
- }
-
- public void setScanEndTime( Date scanEndTime )
- {
- this.scanEndTime = scanEndTime;
- }
-
- public Date getScanStartTime()
- {
- return scanStartTime;
- }
-
- public void setScanStartTime( Date scanStartTime )
- {
- this.scanStartTime = scanStartTime;
- }
-
- public long getTotalArtifactCount()
- {
- return totalArtifactCount;
- }
-
- public void setTotalArtifactCount( long totalArtifactCount )
- {
- this.totalArtifactCount = totalArtifactCount;
- }
-
- public long getTotalArtifactFileSize()
- {
- return totalArtifactFileSize;
- }
-
- public void setTotalArtifactFileSize( long totalArtifactFileSize )
- {
- this.totalArtifactFileSize = totalArtifactFileSize;
- }
-
- public long getTotalFileCount()
- {
- return totalFileCount;
- }
-
- public void setTotalFileCount( long totalFileCount )
- {
- this.totalFileCount = totalFileCount;
- }
-
- public long getTotalGroupCount()
- {
- return totalGroupCount;
- }
-
- public void setTotalGroupCount( long totalGroupCount )
- {
- this.totalGroupCount = totalGroupCount;
- }
-
- public long getTotalProjectCount()
- {
- return totalProjectCount;
- }
-
- public void setTotalProjectCount( long totalProjectCount )
- {
- this.totalProjectCount = totalProjectCount;
- }
-
- public void setNewFileCount( long newFileCount )
- {
- this.newFileCount = newFileCount;
- }
-
- public long getNewFileCount()
- {
- return newFileCount;
- }
-
- public long getDuration()
- {
- return scanEndTime.getTime() - scanStartTime.getTime();
- }
-
- public String getRepositoryId()
- {
- return repositoryId;
- }
-
- public void setRepositoryId( String repositoryId )
- {
- this.repositoryId = repositoryId;
- }
-
- @Override
- public String getFacetId()
- {
- return FACET_ID;
- }
-
- @Override
- public String getName()
- {
- return createNameFormat().format( scanStartTime );
- }
-
- private static SimpleDateFormat createNameFormat()
- {
- SimpleDateFormat fmt = new SimpleDateFormat( SCAN_TIMESTAMP_FORMAT );
- fmt.setTimeZone( UTC_TIME_ZONE );
- return fmt;
- }
-
- @Override
- public Map<String, String> toProperties()
- {
- Map<String, String> properties = new HashMap<>();
- properties.put( "scanEndTime", String.valueOf( scanEndTime.getTime() ) );
- properties.put( "scanStartTime", String.valueOf( scanStartTime.getTime() ) );
- properties.put( "totalArtifactCount", String.valueOf( totalArtifactCount ) );
- properties.put( "totalArtifactFileSize", String.valueOf( totalArtifactFileSize ) );
- properties.put( "totalFileCount", String.valueOf( totalFileCount ) );
- properties.put( "totalGroupCount", String.valueOf( totalGroupCount ) );
- properties.put( "totalProjectCount", String.valueOf( totalProjectCount ) );
- properties.put( "newFileCount", String.valueOf( newFileCount ) );
- properties.put( "repositoryId", repositoryId );
- for ( Map.Entry<String, Long> entry : totalCountForType.entrySet() )
- {
- properties.put( "count-" + entry.getKey(), String.valueOf( entry.getValue() ) );
- }
- return properties;
- }
-
- @Override
- public void fromProperties( Map<String, String> properties )
- {
- scanEndTime = new Date( Long.parseLong( properties.get( "scanEndTime" ) ) );
- scanStartTime = new Date( Long.parseLong( properties.get( "scanStartTime" ) ) );
- totalArtifactCount = Long.parseLong( properties.get( "totalArtifactCount" ) );
- totalArtifactFileSize = Long.parseLong( properties.get( "totalArtifactFileSize" ) );
- totalFileCount = Long.parseLong( properties.get( "totalFileCount" ) );
- totalGroupCount = Long.parseLong( properties.get( "totalGroupCount" ) );
- totalProjectCount = Long.parseLong( properties.get( "totalProjectCount" ) );
- newFileCount = Long.parseLong( properties.get( "newFileCount" ) );
- repositoryId = properties.get( "repositoryId" );
- totalCountForType.clear();
- for ( Map.Entry<String, String> entry : properties.entrySet() )
- {
- if ( entry.getKey().startsWith( "count-" ) )
- {
- totalCountForType.put( entry.getKey().substring( 6 ), Long.valueOf( entry.getValue() ) );
- }
- }
- }
-
- @Override
- public boolean equals( Object o )
- {
- if ( this == o )
- {
- return true;
- }
- if ( o == null || getClass() != o.getClass() )
- {
- return false;
- }
-
- RepositoryStatistics that = (RepositoryStatistics) o;
-
- if ( newFileCount != that.newFileCount )
- {
- return false;
- }
- if ( totalArtifactCount != that.totalArtifactCount )
- {
- return false;
- }
- if ( totalArtifactFileSize != that.totalArtifactFileSize )
- {
- return false;
- }
- if ( totalFileCount != that.totalFileCount )
- {
- return false;
- }
- if ( totalGroupCount != that.totalGroupCount )
- {
- return false;
- }
- if ( totalProjectCount != that.totalProjectCount )
- {
- return false;
- }
- if ( !scanEndTime.equals( that.scanEndTime ) )
- {
- return false;
- }
- if ( !scanStartTime.equals( that.scanStartTime ) )
- {
- return false;
- }
- if ( !totalCountForType.equals( that.totalCountForType ) )
- {
- return false;
- }
- if ( !repositoryId.equals( that.repositoryId ) )
- {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode()
- {
- int result = scanEndTime.hashCode();
- result = 31 * result + scanStartTime.hashCode();
- result = 31 * result + (int) ( totalArtifactCount ^ ( totalArtifactCount >>> 32 ) );
- result = 31 * result + (int) ( totalArtifactFileSize ^ ( totalArtifactFileSize >>> 32 ) );
- result = 31 * result + (int) ( totalFileCount ^ ( totalFileCount >>> 32 ) );
- result = 31 * result + (int) ( totalGroupCount ^ ( totalGroupCount >>> 32 ) );
- result = 31 * result + (int) ( totalProjectCount ^ ( totalProjectCount >>> 32 ) );
- result = 31 * result + (int) ( newFileCount ^ ( newFileCount >>> 32 ) );
- result = 31 * result + totalCountForType.hashCode();
- result = 31 * result + repositoryId.hashCode();
- return result;
- }
-
- @Override
- public String toString()
- {
- return "RepositoryStatistics{" + "scanEndTime=" + scanEndTime + ", scanStartTime=" + scanStartTime +
- ", totalArtifactCount=" + totalArtifactCount + ", totalArtifactFileSize=" + totalArtifactFileSize +
- ", totalFileCount=" + totalFileCount + ", totalGroupCount=" + totalGroupCount + ", totalProjectCount=" +
- totalProjectCount + ", newFileCount=" + newFileCount + ", totalCountForType=" + totalCountForType + ", " +
- "repositoryId=" + repositoryId + '}';
- }
-
- public Map<String, Long> getTotalCountForType()
- {
- return totalCountForType;
- }
-
- public long getTotalCountForType( String type )
- {
- return totalCountForType.get( type );
- }
-
- public void setTotalCountForType( String type, long count )
- {
- totalCountForType.put( type.replaceAll( "-", "_" ).replaceAll( "\\.", "_" ), count );
- }
-
- private static final class ZeroForNullHashMap<K, V extends Long> extends HashMap<K, V>
- {
- @Override
- public V get(Object key) {
- V value = super.get( key );
-
- return value != null ? value : ( V ) Long.valueOf( 0L );
- }
- }
-}
import org.apache.archiva.metadata.model.MetadataFacet;
import org.apache.archiva.metadata.model.MetadataFacetFactory;
+import org.apache.archiva.metadata.repository.stats.model.DefaultRepositoryStatistics;
import org.springframework.stereotype.Service;
/**
@Override
public MetadataFacet createMetadataFacet()
{
- return new RepositoryStatistics();
+ return new DefaultRepositoryStatistics();
}
@Override
public MetadataFacet createMetadataFacet( String repositoryId, String name )
{
- return new RepositoryStatistics();
+ return new DefaultRepositoryStatistics();
}
}
\ No newline at end of file
+++ /dev/null
-package org.apache.archiva.metadata.repository.stats;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import org.apache.archiva.metadata.repository.MetadataRepository;
-import org.apache.archiva.metadata.repository.MetadataRepositoryException;
-
-import java.util.Date;
-import java.util.List;
-
-public interface RepositoryStatisticsManager
-{
- RepositoryStatistics getLastStatistics( MetadataRepository metadataRepository, String repositoryId )
- throws MetadataRepositoryException;
-
- boolean hasStatistics( MetadataRepository metadataRepository, String repositoryId )
- throws MetadataRepositoryException;
-
- void addStatisticsAfterScan( MetadataRepository metadataRepository, String repositoryId, Date startTime,
- Date endTime, long totalFiles, long newFiles )
- throws MetadataRepositoryException;
-
- void deleteStatistics( MetadataRepository metadataRepository, String repositoryId )
- throws MetadataRepositoryException;
-
- List<RepositoryStatistics> getStatisticsInRange( MetadataRepository metadataRepository, String repositoryId,
- Date startTime, Date endTime )
- throws MetadataRepositoryException;
-}
+++ /dev/null
-package org.apache.archiva.metadata.repository.stats;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import junit.framework.TestCase;
-import org.apache.archiva.metadata.repository.MetadataRepository;
-import org.apache.archiva.metadata.repository.RepositorySessionFactory;
-import org.apache.commons.io.FileUtils;
-import org.apache.jackrabbit.commons.JcrUtils;
-import org.apache.jackrabbit.core.TransientRepository;
-
-import javax.inject.Inject;
-import javax.jcr.ImportUUIDBehavior;
-import javax.jcr.NamespaceRegistry;
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
-import javax.jcr.Workspace;
-import javax.jcr.nodetype.NodeTypeManager;
-import javax.jcr.nodetype.NodeTypeTemplate;
-import java.io.File;
-import java.io.IOException;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.zip.GZIPInputStream;
-
-import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.mockito.Mockito.*;
-
-@RunWith( ArchivaBlockJUnit4ClassRunner.class )
-public class JcrRepositoryStatisticsGatheringTest
- extends TestCase
-{
- private static final int TOTAL_FILE_COUNT = 1000;
-
- private static final int NEW_FILE_COUNT = 500;
-
- private static final String TEST_REPO = "test-repo";
-
- private RepositoryStatisticsManager repositoryStatisticsManager;
-
- private MetadataRepository metadataRepository;
-
- @Inject
- private RepositorySessionFactory repositorySessionFactory;
-
- private Session session;
-
- @Override
- @Before
- public void setUp()
- throws Exception
- {
- super.setUp();
-
- File confFile = new File( "src/test/repository.xml" );
- File dir = new File( "target/jcr" );
- FileUtils.deleteDirectory( dir );
-
- assertTrue( confFile.exists() );
- assertFalse( dir.exists() );
-
- TransientRepository repository = new TransientRepository( confFile, dir );
- session = repository.login( new SimpleCredentials( "username", "password".toCharArray() ) );
-
- // TODO: perhaps have an archiva-jcr-utils module shared by these plugins that does this and can contain
- // structure information
- Workspace workspace = session.getWorkspace();
- NamespaceRegistry registry = workspace.getNamespaceRegistry();
- registry.registerNamespace( "archiva", "http://archiva.apache.org/jcr/" );
-
- NodeTypeManager nodeTypeManager = workspace.getNodeTypeManager();
- registerMixinNodeType( nodeTypeManager, "archiva:namespace" );
- registerMixinNodeType( nodeTypeManager, "archiva:project" );
- registerMixinNodeType( nodeTypeManager, "archiva:projectVersion" );
- registerMixinNodeType( nodeTypeManager, "archiva:artifact" );
- registerMixinNodeType( nodeTypeManager, "archiva:facet" );
-
- metadataRepository = mock( MetadataRepository.class );
- when( metadataRepository.canObtainAccess( Session.class ) ).thenReturn( true );
- when( metadataRepository.obtainAccess( Session.class ) ).thenReturn( session );
-
- repositoryStatisticsManager = new DefaultRepositoryStatisticsManager();
- }
-
- private static void registerMixinNodeType( NodeTypeManager nodeTypeManager, String type )
- throws RepositoryException
- {
- NodeTypeTemplate nodeType = nodeTypeManager.createNodeTypeTemplate();
- nodeType.setMixin( true );
- nodeType.setName( type );
- nodeTypeManager.registerNodeType( nodeType, false );
- }
-
- @Override
- @After
- public void tearDown()
- throws Exception
- {
- if ( session != null )
- {
- session.logout();
- }
-
- super.tearDown();
- }
-
- @Test
- public void testJcrStatisticsQuery()
- throws Exception
- {
- Calendar cal = Calendar.getInstance();
- Date endTime = cal.getTime();
- cal.add( Calendar.HOUR, -1 );
- Date startTime = cal.getTime();
-
- loadContentIntoRepo( TEST_REPO );
- loadContentIntoRepo( "another-repo" );
-
- repositoryStatisticsManager.addStatisticsAfterScan( metadataRepository, TEST_REPO, startTime, endTime,
- TOTAL_FILE_COUNT, NEW_FILE_COUNT );
-
- RepositoryStatistics expectedStatistics = new RepositoryStatistics();
- expectedStatistics.setNewFileCount( NEW_FILE_COUNT );
- expectedStatistics.setTotalFileCount( TOTAL_FILE_COUNT );
- expectedStatistics.setScanEndTime( endTime );
- expectedStatistics.setScanStartTime( startTime );
- expectedStatistics.setTotalArtifactFileSize( 95954585 );
- expectedStatistics.setTotalArtifactCount( 269 );
- expectedStatistics.setTotalGroupCount( 1 );
- expectedStatistics.setTotalProjectCount( 43 );
- expectedStatistics.setTotalCountForType( "zip", 1 );
- expectedStatistics.setTotalCountForType( "gz", 1 ); // FIXME: should be tar.gz
- expectedStatistics.setTotalCountForType( "java-source", 10 );
- expectedStatistics.setTotalCountForType( "jar", 108 );
- expectedStatistics.setTotalCountForType( "xml", 3 );
- expectedStatistics.setTotalCountForType( "war", 2 );
- expectedStatistics.setTotalCountForType( "pom", 144 );
- expectedStatistics.setRepositoryId( TEST_REPO );
-
- verify( metadataRepository ).addMetadataFacet( TEST_REPO, expectedStatistics );
- }
-
- private void loadContentIntoRepo( String repoId )
- throws RepositoryException, IOException
- {
- Node n = JcrUtils.getOrAddNode( session.getRootNode(), "repositories" );
- n = JcrUtils.getOrAddNode( n, repoId );
- n = JcrUtils.getOrAddNode( n, "content" );
- n = JcrUtils.getOrAddNode( n, "org" );
- n = JcrUtils.getOrAddNode( n, "apache" );
-
- GZIPInputStream inputStream = new GZIPInputStream( getClass().getResourceAsStream( "/artifacts.xml.gz" ) );
- session.importXML( n.getPath(), inputStream, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW );
- session.save();
- }
-}
import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.model.maven2.MavenArtifactFacet;
import org.apache.archiva.metadata.repository.MetadataRepository;
+import org.apache.archiva.metadata.repository.stats.model.DefaultRepositoryStatistics;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatistics;
import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner;
import org.easymock.IMocksControl;
-
-import static org.easymock.EasyMock.*;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import javax.jcr.Session;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import java.util.TimeZone;
+import static org.easymock.EasyMock.createControl;
+import static org.easymock.EasyMock.expect;
+
@RunWith( ArchivaBlockJUnit4ClassRunner.class )
public class RepositoryStatisticsManagerTest
extends TestCase
private static SimpleDateFormat createTimestampFormat()
{
- SimpleDateFormat fmt = new SimpleDateFormat( RepositoryStatistics.SCAN_TIMESTAMP_FORMAT );
+ SimpleDateFormat fmt = new SimpleDateFormat( DefaultRepositoryStatistics.SCAN_TIMESTAMP_FORMAT );
fmt.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
return fmt;
}
Date startTime = TIMESTAMP_FORMAT.parse( SECOND_TEST_SCAN );
Date endTime = new Date( startTime.getTime() + 60000 );
- RepositoryStatistics stats = new RepositoryStatistics();
- stats.setScanStartTime( startTime );
- stats.setScanEndTime( endTime );
+ DefaultRepositoryStatistics defStats = new DefaultRepositoryStatistics();
+ defStats.setScanStartTime( startTime );
+ defStats.setScanEndTime( endTime );
+ RepositoryStatistics stats = defStats;
stats.setTotalArtifactFileSize( 1314527915L );
stats.setNewFileCount( 123 );
stats.setTotalArtifactCount( 10386 );
stats.setTotalFileCount( 56229 );
- expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, RepositoryStatistics.FACET_ID ) ).andReturn(
+ expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID ) ).andReturn(
Arrays.asList( FIRST_TEST_SCAN, SECOND_TEST_SCAN ) );
- expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, RepositoryStatistics.FACET_ID,
+ expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID,
SECOND_TEST_SCAN ) ).andReturn( stats );
metadataRepositoryControl.replay();
throws Exception
{
- expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, RepositoryStatistics.FACET_ID ) ).andReturn(
+ expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID ) ).andReturn(
Collections.<String>emptyList() );
metadataRepositoryControl.replay();
metadataRepository.addMetadataFacet( TEST_REPO_ID, stats );
- expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, RepositoryStatistics.FACET_ID ) ).andReturn(
+ expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID ) ).andReturn(
Arrays.asList( stats.getName() ) );
- expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, RepositoryStatistics.FACET_ID,
+ expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID,
stats.getName() ) ).andReturn( stats );
- expect( metadataRepository.canObtainAccess( Session.class ) ).andReturn( false );
-
metadataRepositoryControl.replay();
repositoryStatisticsManager.addStatisticsAfterScan( metadataRepository, TEST_REPO_ID, startTime, current, 56345,
Date current = new Date();
Date startTime1 = new Date( current.getTime() - 12345 );
- RepositoryStatistics stats1 = createTestStats( startTime1, new Date( current.getTime() - 6000 ) );
+ DefaultRepositoryStatistics stats1 = createTestStats( startTime1, new Date( current.getTime() - 6000 ) );
metadataRepository.addMetadataFacet( TEST_REPO_ID, stats1 );
Date startTime2 = new Date( current.getTime() - 3000 );
- RepositoryStatistics stats2 = createTestStats( startTime2, current );
+ DefaultRepositoryStatistics stats2 = createTestStats( startTime2, current );
metadataRepository.addMetadataFacet( TEST_REPO_ID, stats2 );
- expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, RepositoryStatistics.FACET_ID ) ).andReturn(
+ expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID ) ).andReturn(
Arrays.asList( stats1.getName(), stats2.getName() ) );
- expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, RepositoryStatistics.FACET_ID,
+ expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID,
stats2.getName() ) ).andReturn( stats2 );
- metadataRepository.removeMetadataFacets( TEST_REPO_ID, RepositoryStatistics.FACET_ID );
+ metadataRepository.removeMetadataFacets( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID );
- expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, RepositoryStatistics.FACET_ID ) ).andReturn(
+ expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID ) ).andReturn(
Collections.<String>emptyList() );
- expect( metadataRepository.canObtainAccess( Session.class ) ).andReturn( false ).times( 2 );
metadataRepositoryControl.replay();
repositoryStatisticsManager.addStatisticsAfterScan( metadataRepository, TEST_REPO_ID, startTime1,
throws Exception
{
- expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, RepositoryStatistics.FACET_ID ) ).andReturn(
+ expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID ) ).andReturn(
Collections.<String>emptyList() ).times( 2 );
- metadataRepository.removeMetadataFacets( TEST_REPO_ID, RepositoryStatistics.FACET_ID );
+ metadataRepository.removeMetadataFacets( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID );
metadataRepositoryControl.replay();
ArrayList<String> keys = new ArrayList<>( statsCreated.keySet() );
- expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, RepositoryStatistics.FACET_ID ) ).andReturn( keys );
+ expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID ) ).andReturn( keys );
// only match the middle one
String key = keys.get( 1 );
- expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, RepositoryStatistics.FACET_ID, key ) ).andReturn(
+ expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID, key ) ).andReturn(
statsCreated.get( key ) );
- expect( metadataRepository.canObtainAccess( Session.class ) ).andReturn( false ).times( 3 );
metadataRepositoryControl.replay();
List<String> keys = new ArrayList<>( statsCreated.keySet() );
- expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, RepositoryStatistics.FACET_ID ) ).andReturn( keys );
+ expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID ) ).andReturn( keys );
String key = keys.get( 1 );
- expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, RepositoryStatistics.FACET_ID, key ) ).andReturn(
+ expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID, key ) ).andReturn(
statsCreated.get( key ) );
key = keys.get( 2 );
- expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, RepositoryStatistics.FACET_ID, key ) ).andReturn(
+ expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID, key ) ).andReturn(
statsCreated.get( key ) );
- expect( metadataRepository.canObtainAccess( Session.class ) ).andReturn( false ).times( 3 );
metadataRepositoryControl.replay();
List<String> keys = new ArrayList<>( statsCreated.keySet() );
- expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, RepositoryStatistics.FACET_ID ) ).andReturn( keys );
+ expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID ) ).andReturn( keys );
String key = keys.get( 0 );
- expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, RepositoryStatistics.FACET_ID, key ) ).andReturn(
+ expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID, key ) ).andReturn(
statsCreated.get( key ) );
key = keys.get( 1 );
- expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, RepositoryStatistics.FACET_ID, key ) ).andReturn(
+ expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID, key ) ).andReturn(
statsCreated.get( key ) );
- expect( metadataRepository.canObtainAccess( Session.class ) ).andReturn( false ).times( 3 );
-
metadataRepositoryControl.replay();
for ( RepositoryStatistics stats : statsCreated.values() )
ArrayList<String> keys = new ArrayList<>( statsCreated.keySet() );
- expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, RepositoryStatistics.FACET_ID ) ).andReturn( keys );
+ expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID ) ).andReturn( keys );
String key = keys.get( 0 );
- expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, RepositoryStatistics.FACET_ID, key ) ).andReturn(
+ expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID, key ) ).andReturn(
statsCreated.get( key ) );
key = keys.get( 1 );
- expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, RepositoryStatistics.FACET_ID, key ) ).andReturn(
+ expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID, key ) ).andReturn(
statsCreated.get( key ) );
key = keys.get( 2 );
- expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, RepositoryStatistics.FACET_ID, key ) ).andReturn(
+ expect( metadataRepository.getMetadataFacet( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID, key ) ).andReturn(
statsCreated.get( key ) );
- expect( metadataRepository.canObtainAccess( Session.class ) ).andReturn( false ).times( 3 );
-
metadataRepositoryControl.replay();
for ( RepositoryStatistics stats : statsCreated.values() )
ArrayList<String> keys = new ArrayList<>( statsCreated.keySet() );
- expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, RepositoryStatistics.FACET_ID ) ).andReturn( keys );
-
- expect( metadataRepository.canObtainAccess( Session.class ) ).andReturn( false ).times( 3 );
+ expect( metadataRepository.getMetadataFacets( TEST_REPO_ID, DefaultRepositoryStatistics.FACET_ID ) ).andReturn( keys );
metadataRepositoryControl.replay();
private void addStats( Date startTime, Date endTime )
throws Exception
{
- RepositoryStatistics stats = createTestStats( startTime, endTime );
+ DefaultRepositoryStatistics stats = createTestStats( startTime, endTime );
metadataRepository.addMetadataFacet( TEST_REPO_ID, stats );
statsCreated.put( stats.getName(), stats );
}
return metadata;
}
- private RepositoryStatistics createTestStats( Date startTime, Date endTime )
+ private DefaultRepositoryStatistics createTestStats( Date startTime, Date endTime )
{
- RepositoryStatistics stats = new RepositoryStatistics();
+ DefaultRepositoryStatistics stats = new DefaultRepositoryStatistics();
stats.setRepositoryId( TEST_REPO_ID );
stats.setScanStartTime( startTime );
stats.setScanEndTime( endTime );
<artifactId>metadata-repository-api</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.archiva</groupId>
+ <artifactId>metadata-statistics-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>metadata-repository-api</artifactId>