aboutsummaryrefslogtreecommitdiffstats
path: root/archiva-modules/metadata/metadata-repository-api
diff options
context:
space:
mode:
authorMartin Stockhammer <martin_s@apache.org>2019-08-21 22:44:40 +0200
committerMartin Stockhammer <martin_s@apache.org>2019-08-21 22:44:40 +0200
commit31e8442faddc796db59426a5749ecb64ad76acf5 (patch)
treea29d7343f31a000ec4b89a90881706a9a22e0ca2 /archiva-modules/metadata/metadata-repository-api
parent37a92817ef738ea0c0b82aff15605e65de7fc9dd (diff)
downloadarchiva-31e8442faddc796db59426a5749ecb64ad76acf5.tar.gz
archiva-31e8442faddc796db59426a5749ecb64ad76acf5.zip
Fixing TZ for time storage. Adding stream implementations.
Diffstat (limited to 'archiva-modules/metadata/metadata-repository-api')
-rw-r--r--archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/AbstractMetadataRepository.java46
-rw-r--r--archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/MetadataRepository.java116
-rw-r--r--archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java72
3 files changed, 207 insertions, 27 deletions
diff --git a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/AbstractMetadataRepository.java b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/AbstractMetadataRepository.java
index 7d7258645..c4e27103c 100644
--- a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/AbstractMetadataRepository.java
+++ b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/AbstractMetadataRepository.java
@@ -26,11 +26,10 @@ import org.apache.archiva.metadata.model.MetadataFacetFactory;
import org.apache.archiva.metadata.model.ProjectMetadata;
import org.apache.archiva.metadata.model.ProjectVersionMetadata;
import org.apache.archiva.metadata.model.ProjectVersionReference;
+import org.apache.commons.collections4.ComparatorUtils;
import java.time.ZonedDateTime;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
import java.util.stream.Stream;
public abstract class AbstractMetadataRepository
@@ -119,7 +118,7 @@ public abstract class AbstractMetadataRepository
}
@Override
- public Collection<ArtifactMetadata> getArtifactsByChecksum( RepositorySession session, String repositoryId, String checksum )
+ public List<ArtifactMetadata> getArtifactsByChecksum(RepositorySession session, String repositoryId, String checksum )
throws MetadataRepositoryException
{
throw new UnsupportedOperationException();
@@ -255,6 +254,45 @@ public abstract class AbstractMetadataRepository
throw new UnsupportedOperationException();
}
+ protected static Comparator<ArtifactMetadata> getArtifactMetadataComparator(final QueryParameter queryParameter, String defaultAttr) {
+ List<Comparator<ArtifactMetadata>> compList = new ArrayList<>();
+ List<String> sortFields = new ArrayList<>();
+ if (queryParameter.getSortFields().size() == 0) {
+ sortFields.add(defaultAttr);
+ } else {
+ sortFields = queryParameter.getSortFields();
+ }
+ for (String attribute : sortFields) {
+ switch (attribute) {
+ case "id":
+ compList.add(Comparator.comparing(ArtifactMetadata::getId));
+ break;
+ case "whenGathered":
+ compList.add(Comparator.comparing(ArtifactMetadata::getWhenGathered));
+ break;
+ case "fileLastModified":
+ compList.add(Comparator.comparing(ArtifactMetadata::getFileLastModified));
+ case "version":
+ compList.add(Comparator.comparing(ArtifactMetadata::getVersion));
+ break;
+ case "projectVersion":
+ compList.add(Comparator.comparing(ArtifactMetadata::getProjectVersion));
+ break;
+ case "project":
+ compList.add(Comparator.comparing(ArtifactMetadata::getProject));
+ break;
+ default:
+ //
+ }
+ }
+ Comparator<ArtifactMetadata> comp = ComparatorUtils.chainedComparator(compList);
+ if (queryParameter.isAscending()) {
+ return comp;
+ } else {
+ return comp.reversed();
+ }
+ }
+
@Override
public Collection<ArtifactMetadata> getArtifacts( RepositorySession session, String repoId, String namespace, String projectId,
String projectVersion )
diff --git a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/MetadataRepository.java b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/MetadataRepository.java
index b0849cd14..e679704c8 100644
--- a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/MetadataRepository.java
+++ b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/MetadataRepository.java
@@ -26,6 +26,7 @@ import org.apache.archiva.metadata.model.ProjectMetadata;
import org.apache.archiva.metadata.model.ProjectVersionMetadata;
import org.apache.archiva.metadata.model.ProjectVersionReference;
+import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.List;
@@ -87,9 +88,16 @@ import java.util.stream.Stream;
*
* Facets can be stored on repository, project, version and artifact level.
*
+ * For retrieving artifacts there are methods that return lists and streaming based methods. Some implementations (e.g. JCR) use
+ * lazy loading for the retrieved objects. So the streaming methods may be faster and use less memory than the list based methods.
+ * But for some backends there is no difference.
+ *
*/
public interface MetadataRepository
{
+
+
+
/**
* Update metadata for a particular project in the metadata repository, or create it, if it does not already exist.
*
@@ -155,15 +163,46 @@ public interface MetadataRepository
List<String> getMetadataFacets( RepositorySession session, String repositoryId, String facetId )
throws MetadataRepositoryException;
+
+ /**
+ *
+ * The same as
+ * @see #getMetadataFacetStream(RepositorySession, String, Class, QueryParameter queryParameter)
+ * but uses default query parameters.
+ *
+ * There is no limitation of the number of result objects returned, but implementations may have a hard upper bound for
+ * the number of results.
+ *
+ * @param session
+ * @param repositoryId
+ * @param facetClazz
+ * @param <T>
+ * @return
+ * @throws MetadataRepositoryException
+ * @since 3.0
+ */
<T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz)
throws MetadataRepositoryException;
+ /**
+ * Returns a stream of MetadataFacet elements that match the given facet class.
+ * Implementations should order the resulting stream by facet name.
+ *
+ *
+ * @param session The repository session
+ * @param repositoryId The repository id
+ * @param facetClazz The class of the facet
+ * @param <T> The facet type
+ * @return
+ * @throws MetadataRepositoryException
+ * @since 3.0
+ */
<T extends MetadataFacet> Stream<T> getMetadataFacetStream(RepositorySession session, String repositoryId, Class<T> facetClazz, QueryParameter queryParameter)
throws MetadataRepositoryException;
/**
- * Returns true, if there is facet data stored for the given id on the repository. The facet data itself
- * may be empty. It's just checking if there is data stored for the given facet id.
+ * Returns true, if there is facet data stored for the given facet id on the repository on repository level. The facet data itself
+ * may be empty. It's just checking if there is an object stored for the given facet id.
*
* @param session The repository session
* @param repositoryId The repository id
@@ -200,13 +239,14 @@ public interface MetadataRepository
* @param name The name of the facet (name or path)
* @param <T> The type of the facet object
* @return The facet instance, if it exists.
- * @throws MetadataRepositoryException
+ * @throws MetadataRepositoryException if the data cannot be retrieved from the backend
+ * @since 3.0
*/
<T extends MetadataFacet> T getMetadataFacet(RepositorySession session, String repositoryId, Class<T> clazz, String name)
throws MetadataRepositoryException;
/**
- * Adss a facet to the repository level.
+ * Adds a facet to the repository level.
*
* @param session The repository session
* @param repositoryId The id of the repository
@@ -238,41 +278,79 @@ public interface MetadataRepository
void removeMetadataFacet( RepositorySession session, String repositoryId, String facetId, String name )
throws MetadataRepositoryException;
+
/**
- * if startTime or endTime are <code>null</code> they are not used for search
- *
+ * Is the same as {@link #getArtifactsByDateRange(RepositorySession, String, ZonedDateTime, ZonedDateTime, QueryParameter)}, but
+ * uses default query parameters.
*
- * @param session
- * @param repositoryId
- * @param startTime can be <code>null</code>
- * @param endTime can be <code>null</code>
- * @return
- * @throws MetadataRepositoryException
*/
List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime )
throws MetadataRepositoryException;
+ /**
+ *
+ * Searches for artifacts where the 'whenGathered' attribute value is between the given start and end time.
+ * If start or end time or both are <code>null</code>, the time range for the search is unbounded for this parameter.
+ *
+ *
+ * @param session The repository session
+ * @param repositoryId The repository id
+ * @param startTime The start time/date as zoned date, can be <code>null</code>
+ * @param endTime The end time/date as zoned date, can be <code>null</code>
+ * @param queryParameter Additional parameters for the query that affect ordering and returned results
+ * @return The list of metadata objects for the found instances.
+ * @throws MetadataRepositoryException if the query fails.
+ * @since 3.0
+ */
List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter )
throws MetadataRepositoryException;
/**
- * Returns all the artifacts
- * @param session
- * @param repositoryId
- * @param startTime
- * @param endTime
- * @return
+ * Returns all the artifacts who's 'whenGathered' attribute value is inside the given time range (inclusive) as stream of objects.
+ *
+ * Implementations should return a stream of sorted objects. The objects should be sorted by the 'whenGathered' date in ascending order.
+ *
+ * @param session The repository session
+ * @param repositoryId The repository id
+ * @param startTime The start time, can be <code>null</code>
+ * @param endTime The end time, can be <code>null</code>
+ * @return A stream of artifact metadata objects.
* @throws MetadataRepositoryException
+ * @since 3.0
*/
Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime )
throws MetadataRepositoryException;
+ /**
+ * Returns all the artifacts who's 'whenGathered' attribute value is inside the given time range (inclusive) as stream of objects.
+ *
+ * If no sort attributes are given by the queryParameter, the result is sorted by the 'whenGathered' date.
+ *
+ * @param session The repository session
+ * @param repositoryId The repository id
+ * @param startTime The start time, can be <code>null</code>
+ * @param endTime The end time, can be <code>null</code>
+ * @param queryParameter Additional parameters for the query that affect ordering and number of returned results.
+ * @return A stream of artifact metadata objects.
+ * @throws MetadataRepositoryException
+ * @since 3.0
+ */
Stream<ArtifactMetadata> getArtifactsByDateRangeStream(RepositorySession session, String repositoryId,
ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter)
throws MetadataRepositoryException;
- Collection<ArtifactMetadata> getArtifactsByChecksum( RepositorySession session, String repositoryId, String checksum )
+
+ /**
+ * Returns the artifacts that match the given checksum. All checksum types are searched.
+ *
+ * @param session The repository session
+ * @param repositoryId The repository id
+ * @param checksum The checksum as string of numbers
+ * @return The list of artifacts that match the given checksum.
+ * @throws MetadataRepositoryException
+ */
+ List<ArtifactMetadata> getArtifactsByChecksum(RepositorySession session, String repositoryId, String checksum )
throws MetadataRepositoryException;
/**
diff --git a/archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java b/archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java
index d34f8ab0c..a747b7f28 100644
--- a/archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java
+++ b/archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java
@@ -903,7 +903,7 @@ public abstract class AbstractMetadataRepositoryTest
{
for (int i = 0; i<500; i++)
{
- getRepository( ).addMetadataFacet( session, TEST_REPO_ID, new TestMetadataFacet( TEST_FACET_ID, TEST_VALUE, TEST_NAME+"/"+i ) );
+ getRepository( ).addMetadataFacet( session, TEST_REPO_ID, new TestMetadataFacet( TEST_FACET_ID, TEST_VALUE, TEST_NAME+"/"+String.format("%03d",i) ) );
}
}
@@ -916,15 +916,79 @@ public abstract class AbstractMetadataRepositoryTest
assertEquals( 100, result.size( ) );
assertNotNull( result.get( 0 ) );
for (int i=0; i<10; i++) {
- log.info( "Result {}", result.get( i ).getName( ) );
+ assertEquals(TEST_NAME + "/" + String.format("%03d",i), result.get(i).getName());
}
- assertEquals( TEST_NAME+"/"+0, result.get( 0 ).getName( ) );
- }, 2, 500 );
+ }, 3, 500 );
}
}
@Test
+ public void testGetMetadataFacetsStreamWithOffset( )
+ throws Exception
+ {
+ try ( RepositorySession session = getSessionFactory( ).createSession( ) )
+ {
+ for (int i = 0; i<100; i++)
+ {
+ getRepository( ).addMetadataFacet( session, TEST_REPO_ID, new TestMetadataFacet( TEST_FACET_ID, TEST_VALUE, TEST_NAME+"/"+String.format("%03d", i) ) );
+ }
+ }
+
+ try ( RepositorySession session = getSessionFactory( ).createSession( ) )
+ {
+ tryAssert( ( ) -> {
+ Stream<TestMetadataFacet> str = getRepository( ).getMetadataFacetStream( session, TEST_REPO_ID, TestMetadataFacet.class, new QueryParameter(5, 10));
+ assertNotNull( str );
+ List<TestMetadataFacet> result = str.collect( Collectors.toList( ) );
+ assertEquals( 10, result.size( ) );
+ assertNotNull( result.get( 0 ) );
+ for (int i=0; i<10; i++) {
+ assertEquals(TEST_NAME + "/" + String.format("%03d",i+5), result.get(i).getName());
+ }
+ }, 3, 500 );
+
+ }
+ }
+
+ @Test
+ public void testGetArtifactsByDateRangeStreamLowerAndUpperBound( )
+ throws Exception
+ {
+ try ( RepositorySession session = getSessionFactory( ).createSession( ) )
+ {
+ final ArtifactMetadata artifact1 = createArtifact( );
+ artifact1.setWhenGathered(ZonedDateTime.now().minusDays(1));
+ getRepository( ).updateArtifact( session, TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION, artifact1 );
+ final ArtifactMetadata artifact2 = createArtifact( );
+ artifact2.setId(artifact2.getId()+"-2");
+ artifact2.setVersion(TEST_PROJECT_VERSION+"-2");
+ artifact2.setWhenGathered(ZonedDateTime.now());
+ getRepository( ).updateArtifact( session, TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION, artifact2 );
+ final ArtifactMetadata artifact3 = createArtifact();
+ artifact3.setId(artifact3.getId()+"-3");
+ artifact3.setVersion(TEST_PROJECT_VERSION+"-3");
+ artifact3.setWhenGathered(ZonedDateTime.now().plusDays(1));
+ getRepository( ).updateArtifact( session, TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION, artifact3 );
+ session.save( );
+
+ ZonedDateTime lower = artifact2.getWhenGathered().minusSeconds(10);
+ ZonedDateTime upper = artifact2.getWhenGathered().plusSeconds(10);
+
+ tryAssert( ( ) -> {
+ Stream<ArtifactMetadata> stream = getRepository().getArtifactsByDateRangeStream(session, TEST_REPO_ID, lower, upper, new QueryParameter());
+ assertNotNull(stream);
+
+ List<ArtifactMetadata> artifacts = stream.collect(Collectors.toList());
+ assertEquals(1, artifacts.size());
+
+
+ assertEquals( Collections.singletonList( artifact2 ), artifacts );
+ } );
+ }
+ }
+
+ @Test
public void testGetMetadataFacetsWhenEmpty( )
throws Exception
{