Adding query param object for search queries

This commit is contained in:
Martin Stockhammer 2019-08-21 10:29:31 +02:00
parent f100559586
commit 37a92817ef
7 changed files with 174 additions and 47 deletions

View File

@ -0,0 +1,98 @@
package org.apache.archiva.metadata;
/*
* 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.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
*
* This class is used to provide additional query parameters to search queries.
* These parameters are hints for the metadata repository implementation, some parameters may be ignored.
*
* The defaults are:
* <li>
* <ul>Sort order: ascending</ul>
* <ul>Offset: 0</ul>
* <ul>Limit: Long.MAX_VALUE</ul>
* <ul>Sort fields: empty, which means it depends on the query</ul>
* </li>
*
* @author Martin Stockhammer <martin_s@apache.org>
*/
public class QueryParameter {
final boolean ascending;
final List<String> sortFields;
final long offset;
final long limit;
public QueryParameter(boolean isAscending, long offset, long limit, String... sortFields) {
this.ascending = isAscending;
this.offset = offset;
this.limit = limit;
this.sortFields = Arrays.asList(sortFields);
}
public QueryParameter(long offset, long limit) {
this.offset=offset;
this.limit = limit;
this.ascending = true;
this.sortFields = Collections.emptyList();
}
public QueryParameter(boolean isAscending, long offset, long limit) {
this.ascending = isAscending;
this.offset = offset;
this.limit = limit;
this.sortFields = Collections.emptyList();
}
public QueryParameter(long limit) {
this.offset=0;
this.ascending=true;
this.limit=limit;
this.sortFields = Collections.emptyList();
}
public QueryParameter() {
this.ascending = true;
this.sortFields = Collections.emptyList();
this.offset = 0;
this.limit = Long.MAX_VALUE;
}
public boolean isAscending() {
return ascending;
}
public List<String> getSortFields() {
return sortFields;
}
public long getOffset() {
return offset;
}
public long getLimit() {
return limit;
}
}

View File

@ -19,6 +19,7 @@ package org.apache.archiva.metadata.repository;
* under the License.
*/
import org.apache.archiva.metadata.QueryParameter;
import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.model.MetadataFacet;
import org.apache.archiva.metadata.model.MetadataFacetFactory;
@ -111,7 +112,7 @@ public abstract class AbstractMetadataRepository
}
@Override
public List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime )
public List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter )
throws MetadataRepositoryException
{
throw new UnsupportedOperationException();
@ -306,13 +307,13 @@ public abstract class AbstractMetadataRepository
@Override
public <T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz ) throws MetadataRepositoryException
{
return getMetadataFacetStream( session, repositoryId, facetClazz, 0, Long.MAX_VALUE );
return getMetadataFacetStream( session, repositoryId, facetClazz, new QueryParameter());
}
@Override
public Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime ) throws MetadataRepositoryException
{
return getArtifactsByDateRangeStream( session, repositoryId, startTime, endTime, 0, Long.MAX_VALUE );
return getArtifactsByDateRangeStream( session, repositoryId, startTime, endTime, new QueryParameter());
}
@Override
@ -323,7 +324,7 @@ public abstract class AbstractMetadataRepository
}
@Override
public <T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz, long offset, long maxEntries ) throws MetadataRepositoryException
public <T extends MetadataFacet> Stream<T> getMetadataFacetStream(RepositorySession session, String repositoryId, Class<T> facetClazz, QueryParameter queryParameter) throws MetadataRepositoryException
{
throw new UnsupportedOperationException();
}
@ -337,7 +338,7 @@ public abstract class AbstractMetadataRepository
@Override
public Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, long offset, long maxEntries ) throws MetadataRepositoryException
public Stream<ArtifactMetadata> getArtifactsByDateRangeStream(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter) throws MetadataRepositoryException
{
throw new UnsupportedOperationException();
}
@ -358,4 +359,13 @@ public abstract class AbstractMetadataRepository
protected Class<? extends MetadataFacet> getFactoryClassForId( String facetId ) {
return metadataService.getFactoryClassForId( facetId );
}
@Override
public List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repoId, ZonedDateTime startTime, ZonedDateTime endTime)
throws MetadataRepositoryException {
return getArtifactsByDateRange(session, repoId, startTime, endTime, new QueryParameter());
}
}

View File

@ -19,6 +19,7 @@ package org.apache.archiva.metadata.repository;
* under the License.
*/
import org.apache.archiva.metadata.QueryParameter;
import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.model.MetadataFacet;
import org.apache.archiva.metadata.model.ProjectMetadata;
@ -157,7 +158,7 @@ public interface MetadataRepository
<T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz)
throws MetadataRepositoryException;
<T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz, long offset, long maxEntries)
<T extends MetadataFacet> Stream<T> getMetadataFacetStream(RepositorySession session, String repositoryId, Class<T> facetClazz, QueryParameter queryParameter)
throws MetadataRepositoryException;
/**
@ -251,6 +252,10 @@ public interface MetadataRepository
List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime )
throws MetadataRepositoryException;
List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter )
throws MetadataRepositoryException;
/**
* Returns all the artifacts
* @param session
@ -263,8 +268,8 @@ public interface MetadataRepository
Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime )
throws MetadataRepositoryException;
Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId,
ZonedDateTime startTime, ZonedDateTime endTime, long offset, long maxEntries )
Stream<ArtifactMetadata> getArtifactsByDateRangeStream(RepositorySession session, String repositoryId,
ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter)
throws MetadataRepositoryException;
Collection<ArtifactMetadata> getArtifactsByChecksum( RepositorySession session, String repositoryId, String checksum )

View File

@ -20,26 +20,21 @@ package org.apache.archiva.metadata.repository;
*/
import junit.framework.TestCase;
import org.apache.archiva.metadata.QueryParameter;
import org.apache.archiva.metadata.generic.GenericMetadataFacet;
import org.apache.archiva.metadata.generic.GenericMetadataFacetFactory;
import org.apache.archiva.metadata.model.*;
import org.apache.archiva.metadata.model.facets.AbstractMetadataFacetFactory;
import org.apache.archiva.repository.Repository;
import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.format.annotation.NumberFormat;
import org.springframework.test.context.ContextConfiguration;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalUnit;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -915,7 +910,7 @@ public abstract class AbstractMetadataRepositoryTest
try ( RepositorySession session = getSessionFactory( ).createSession( ) )
{
tryAssert( ( ) -> {
Stream<TestMetadataFacet> str = getRepository( ).getMetadataFacetStream( session, TEST_REPO_ID, TestMetadataFacet.class, 0, 100 );
Stream<TestMetadataFacet> str = getRepository( ).getMetadataFacetStream( session, TEST_REPO_ID, TestMetadataFacet.class, new QueryParameter(0, 100));
assertNotNull( str );
List<TestMetadataFacet> result = str.collect( Collectors.toList( ) );
assertEquals( 100, result.size( ) );

View File

@ -38,6 +38,7 @@ import me.prettyprint.hector.api.mutation.Mutator;
import me.prettyprint.hector.api.query.QueryResult;
import me.prettyprint.hector.api.query.RangeSlicesQuery;
import org.apache.archiva.configuration.ArchivaConfiguration;
import org.apache.archiva.metadata.QueryParameter;
import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.model.CiManagement;
import org.apache.archiva.metadata.model.Dependency;
@ -70,13 +71,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@ -88,7 +87,6 @@ import java.util.Spliterator;
import java.util.UUID;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
@ -1590,17 +1588,16 @@ public class CassandraMetadataRepository
* Implementation is not very performant, because sorting is part of the stream. I do not know how to specify the sort
* in the query.
*
* @param <T>
* @param session
* @param repositoryId
* @param facetClazz
* @param offset
* @param maxEntries
* @param <T>
* @param queryParameter
* @return
* @throws MetadataRepositoryException
*/
@Override
public <T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz, long offset, long maxEntries ) throws MetadataRepositoryException
public <T extends MetadataFacet> Stream<T> getMetadataFacetStream(RepositorySession session, String repositoryId, Class<T> facetClazz, QueryParameter queryParameter) throws MetadataRepositoryException
{
final MetadataFacetFactory<T> metadataFacetFactory = getFacetFactory( facetClazz );
final String facetId = metadataFacetFactory.getFacetId( );
@ -1637,7 +1634,7 @@ public class CassandraMetadataRepository
}
return updateItem;
}), false ).sorted( (f1, f2) -> f1.getName()!=null ? f1.getName().compareTo( f2.getName() ) : 1 ).skip( offset ).limit( maxEntries );
}), false ).sorted( (f1, f2) -> f1.getName()!=null ? f1.getName().compareTo( f2.getName() ) : 1 ).skip( queryParameter.getOffset()).limit( queryParameter.getLimit());
}
@Override
@ -1835,7 +1832,7 @@ public class CassandraMetadataRepository
}
@Override
public Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, long offset, long maxEntries ) throws MetadataRepositoryException
public Stream<ArtifactMetadata> getArtifactsByDateRangeStream(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter) throws MetadataRepositoryException
{
return null;
}

View File

@ -21,6 +21,7 @@ package org.apache.archiva.metadata.repository.file;
import org.apache.archiva.configuration.ArchivaConfiguration;
import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.archiva.metadata.QueryParameter;
import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.model.CiManagement;
import org.apache.archiva.metadata.model.Dependency;
@ -60,7 +61,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
@ -352,7 +352,7 @@ public class FileMetadataRepository
}
@Override
public <T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz, long offset, long maxEntries ) throws MetadataRepositoryException
public <T extends MetadataFacet> Stream<T> getMetadataFacetStream(RepositorySession session, String repositoryId, Class<T> facetClazz, QueryParameter queryParameter) throws MetadataRepositoryException
{
final MetadataFacetFactory<T> metadataFacetFactory = getFacetFactory( facetClazz );
if (metadataFacetFactory==null) {
@ -367,8 +367,8 @@ public class FileMetadataRepository
.filter( path -> Files.exists( path.resolve( searchFile ) ) )
.map(path -> directory.relativize(path).toString())
.sorted()
.skip( offset )
.limit(maxEntries)
.skip( queryParameter.getOffset())
.limit(queryParameter.getLimit())
.map(name -> getMetadataFacet( session, repositoryId, facetClazz, name ));
} catch (IOException e) {
throw new MetadataRepositoryException( e.getMessage( ), e );
@ -517,7 +517,7 @@ public class FileMetadataRepository
}
@Override
public Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, long offset, long maxEntries ) throws MetadataRepositoryException
public Stream<ArtifactMetadata> getArtifactsByDateRangeStream(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter) throws MetadataRepositoryException
{
return null;
}

View File

@ -20,6 +20,7 @@ package org.apache.archiva.metadata.repository.jcr;
*/
import com.google.common.collect.ImmutableMap;
import org.apache.archiva.metadata.QueryParameter;
import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.model.CiManagement;
import org.apache.archiva.metadata.model.Dependency;
@ -49,7 +50,6 @@ import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.jackrabbit.commons.cnd.CndImporter;
import org.apache.jackrabbit.commons.cnd.ParseException;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -72,7 +72,6 @@ import javax.jcr.query.RowIterator;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.Map.Entry;
@ -528,9 +527,30 @@ public class JcrMetadataRepository
};
}
private StringBuilder appendQueryParams(StringBuilder query, String selector, String defaultProperty, QueryParameter queryParameter) {
if (queryParameter.getSortFields().size()==0) {
query.append(" ORDER BY [").append(selector).append("].[").append(defaultProperty).append("]");
if (queryParameter.isAscending()) {
query.append(" ASC");
} else {
query.append(" DESC");
}
} else {
query.append(" ORDER BY");
for (String property : queryParameter.getSortFields()) {
query.append(" [").append(selector).append("].[").append(property).append("]");
if (queryParameter.isAscending()) {
query.append(" ASC");
} else {
query.append(" DESC");
}
}
}
return query;
}
@Override
public <T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz,
long offset, long maxEntries) throws MetadataRepositoryException
public <T extends MetadataFacet> Stream<T> getMetadataFacetStream(RepositorySession session, String repositoryId, Class<T> facetClazz, QueryParameter queryParameter) throws MetadataRepositoryException
{
final Session jcrSession = getSession( session );
final MetadataFacetFactory<T> factory = metadataService.getFactory( facetClazz );
@ -538,10 +558,11 @@ public class JcrMetadataRepository
final String facetPath = '/'+getFacetPath( repositoryId, facetId );
StringBuilder query = new StringBuilder("SELECT * FROM [");
query.append(FACET_NODE_TYPE).append("] AS facet WHERE ISDESCENDANTNODE(facet, [")
.append(facetPath).append("]) ORDER BY [facet].[archiva:name]");
.append(facetPath).append("])");
appendQueryParams(query, "facet", "archiva:name", queryParameter);
String q = query.toString();
Map<String, String> params = new HashMap<>( );
QueryResult result = runNativeJcrQuery( jcrSession, q, params, offset, maxEntries );
Map<String, String> params = new HashMap<>( );
QueryResult result = runNativeJcrQuery( jcrSession, q, params, queryParameter.getOffset(), queryParameter.getLimit());
return StreamSupport.stream( createResultSpliterator( result, (Row row)-> {
try
{
@ -744,7 +765,8 @@ public class JcrMetadataRepository
}
}
private String buildArtifactByDateRangeQuery(String repoId, ZonedDateTime startTime, ZonedDateTime endTime) {
private StringBuilder buildArtifactByDateRangeQuery(String repoId, ZonedDateTime startTime, ZonedDateTime endTime,
QueryParameter queryParameter) {
StringBuilder q = getArtifactQuery( repoId );
if ( startTime != null )
@ -755,19 +777,19 @@ public class JcrMetadataRepository
{
q.append(" AND [artifact].[whenGathered] <= $end");
}
q.append(" ORDER BY [artifact].[whenGathered]");
return q.toString();
appendQueryParams(q, "artifact", "whenGathered", queryParameter);
return q;
}
private QueryResult queryArtifactByDateRange(Session jcrSession, String repositoryId,
ZonedDateTime startTime, ZonedDateTime endTime,
long offset, long maxEntries) throws MetadataRepositoryException {
String q = buildArtifactByDateRangeQuery(repositoryId, startTime, endTime);
QueryParameter queryParameter) throws MetadataRepositoryException {
String q = buildArtifactByDateRangeQuery(repositoryId, startTime, endTime, queryParameter).toString();
try {
Query query = jcrSession.getWorkspace().getQueryManager().createQuery(q, Query.JCR_SQL2);
query.setOffset(offset);
query.setLimit(maxEntries);
query.setOffset(queryParameter.getOffset());
query.setLimit(queryParameter.getLimit());
ValueFactory valueFactory = jcrSession.getValueFactory();
if (startTime != null) {
query.bindValue("start", valueFactory.createValue(createCalendar(startTime)));
@ -782,7 +804,7 @@ public class JcrMetadataRepository
}
@Override
public List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repoId, ZonedDateTime startTime, ZonedDateTime endTime )
public List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repoId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter )
throws MetadataRepositoryException
{
final Session jcrSession = getSession( session );
@ -790,7 +812,7 @@ public class JcrMetadataRepository
List<ArtifactMetadata> artifacts;
try
{
QueryResult result = queryArtifactByDateRange(jcrSession, repoId, startTime, endTime, 0, Long.MAX_VALUE);
QueryResult result = queryArtifactByDateRange(jcrSession, repoId, startTime, endTime, queryParameter);
artifacts = new ArrayList<>();
for ( Node n : JcrUtils.getNodes( result ) )
@ -806,10 +828,10 @@ public class JcrMetadataRepository
}
@Override
public Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, long offset, long maxEntries ) throws MetadataRepositoryException
public Stream<ArtifactMetadata> getArtifactsByDateRangeStream(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter) throws MetadataRepositoryException
{
final Session jcrSession = getSession( session );
QueryResult result = queryArtifactByDateRange(jcrSession, repositoryId, startTime, endTime, offset, maxEntries);
QueryResult result = queryArtifactByDateRange(jcrSession, repositoryId, startTime, endTime, queryParameter);
return StreamSupport.stream(createResultSpliterator(result, (row) -> {
try {
return getArtifactFromNode(repositoryId, row.getNode("artifact"));