[MRM-1867] Adding a find jar by checksum functionality to the REST api

This commit is contained in:
Olivier Lamy 2015-01-12 17:07:54 +11:00
parent 775f7efbf3
commit 61c83ff3d9
8 changed files with 208 additions and 34 deletions

View File

@ -30,7 +30,6 @@ import java.util.Map;
/** /**
* ConsumerProcessFileClosure * ConsumerProcessFileClosure
* *
*
*/ */
public class ConsumerProcessFileClosure public class ConsumerProcessFileClosure
implements Closure implements Closure

View File

@ -26,8 +26,6 @@ import java.io.File;
/** /**
* DataRefreshTask - task for discovering changes in the repository * DataRefreshTask - task for discovering changes in the repository
* and updating all associated data. * and updating all associated data.
*
*
*/ */
public class RepositoryTask public class RepositoryTask
implements Task implements Task
@ -40,6 +38,22 @@ public class RepositoryTask
private boolean scanAll; private boolean scanAll;
public RepositoryTask()
{
// no op
}
public RepositoryTask( String repositoryId )
{
this.repositoryId = repositoryId;
}
public RepositoryTask( String repositoryId, boolean scanAll )
{
this.repositoryId = repositoryId;
this.scanAll = scanAll;
}
public boolean isScanAll() public boolean isScanAll()
{ {
return scanAll; return scanAll;

View File

@ -0,0 +1,74 @@
package org.apache.archiva.rest.api.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.io.Serializable;
import java.util.List;
/**
* @since 2.2.0
*/
public class ChecksumSearch
implements Serializable
{
private List<String> repositories;
private String checksum;
public ChecksumSearch()
{
// nope
}
public ChecksumSearch( List<String> repositories, String checksum )
{
this.repositories = repositories;
this.checksum = checksum;
}
public List<String> getRepositories()
{
return repositories;
}
public void setRepositories( List<String> repositories )
{
this.repositories = repositories;
}
public String getChecksum()
{
return checksum;
}
public void setChecksum( String checksum )
{
this.checksum = checksum;
}
@Override
public String toString()
{
return "ChecksumSearch{" +
"repositories=" + repositories +
", checksum='" + checksum + '\'' +
'}';
}
}

View File

@ -22,6 +22,7 @@ package org.apache.archiva.rest.api.services;
import org.apache.archiva.maven2.model.Artifact; import org.apache.archiva.maven2.model.Artifact;
import org.apache.archiva.redback.authorization.RedbackAuthorization; import org.apache.archiva.redback.authorization.RedbackAuthorization;
import org.apache.archiva.rest.api.model.ChecksumSearch;
import org.apache.archiva.rest.api.model.GroupIdList; import org.apache.archiva.rest.api.model.GroupIdList;
import org.apache.archiva.rest.api.model.SearchRequest; import org.apache.archiva.rest.api.model.SearchRequest;
import org.apache.archiva.rest.api.model.StringList; import org.apache.archiva.rest.api.model.StringList;
@ -82,8 +83,8 @@ public interface SearchService
@GET @GET
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } ) @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
@RedbackAuthorization( noPermission = true, noRestriction = true ) @RedbackAuthorization( noPermission = true, noRestriction = true )
List<Artifact> getArtifactVersions( @QueryParam( "groupId" ) String groupId, List<Artifact> getArtifactVersions( @QueryParam( "groupId" ) String groupId, //
@QueryParam( "artifactId" ) String artifactId, @QueryParam( "artifactId" ) String artifactId, //
@QueryParam( "packaging" ) String packaging ) @QueryParam( "packaging" ) String packaging )
throws ArchivaRestServiceException; throws ArchivaRestServiceException;
@ -117,23 +118,32 @@ public interface SearchService
@QueryParam( "artifactId" ) String artifactId, @QueryParam( "artifactId" ) String artifactId,
@QueryParam( "version" ) String version ) @QueryParam( "version" ) String version )
throws ArchivaRestServiceException; throws ArchivaRestServiceException;
@Path( "getArtifactByChecksum" )
@GET
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
@RedbackAuthorization( noPermission = true, noRestriction = true )
List<Artifact> getArtifactByChecksum( @QueryParam( "checksum" ) String checksum )
throws ArchivaRestServiceException;
*/ */
@GET @GET
@Path( "/artifact" ) @Path( "/artifact" )
@Produces( "text/html" ) @Produces( "text/html" )
@RedbackAuthorization( noPermission = true, noRestriction = true ) @RedbackAuthorization( noPermission = true, noRestriction = true )
Response redirectToArtifactFile( @QueryParam( "r" ) String repositoryId, @QueryParam( "g" ) String groupId, Response redirectToArtifactFile( @QueryParam( "r" ) String repositoryId, //
@QueryParam( "a" ) String artifactId, @QueryParam( "v" ) String version, @QueryParam( "g" ) String groupId, //
@QueryParam( "p" ) String packaging, @QueryParam( "c" ) String classifier ) @QueryParam( "a" ) String artifactId, //
@QueryParam( "v" ) String version, //
@QueryParam( "p" ) String packaging, //
@QueryParam( "c" ) String classifier )
throws ArchivaRestServiceException; throws ArchivaRestServiceException;
/**
* If searchRequest contains repositories, the search will be done only on those repositories.
* <b>if no repositories, the search will be apply on all repositories the current user has karma</b>
*/
@Path( "artifactsByChecksum" )
@POST
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
@RedbackAuthorization( noPermission = true, noRestriction = true )
List<Artifact> getArtifactByChecksum( ChecksumSearch checksumSearch )
throws ArchivaRestServiceException;
} }

View File

@ -43,6 +43,7 @@ import org.apache.archiva.repository.RepositoryException;
import org.apache.archiva.rest.api.services.ArchivaRestServiceException; import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
import org.apache.archiva.rest.services.utils.ArtifactBuilder; import org.apache.archiva.rest.services.utils.ArtifactBuilder;
import org.apache.archiva.scheduler.repository.DefaultRepositoryArchivaTaskScheduler; import org.apache.archiva.scheduler.repository.DefaultRepositoryArchivaTaskScheduler;
import org.apache.archiva.scheduler.repository.model.RepositoryArchivaTaskScheduler;
import org.apache.archiva.scheduler.repository.model.RepositoryTask; import org.apache.archiva.scheduler.repository.model.RepositoryTask;
import org.apache.archiva.security.AccessDeniedException; import org.apache.archiva.security.AccessDeniedException;
import org.apache.archiva.security.ArchivaSecurityException; import org.apache.archiva.security.ArchivaSecurityException;
@ -64,6 +65,7 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -108,7 +110,7 @@ public abstract class AbstractRestService
@Inject @Inject
@Named(value = "archivaTaskScheduler#repository") @Named(value = "archivaTaskScheduler#repository")
protected DefaultRepositoryArchivaTaskScheduler repositoryTaskScheduler; protected RepositoryArchivaTaskScheduler repositoryTaskScheduler;
@Inject @Inject
@ -312,7 +314,7 @@ public abstract class AbstractRestService
} }
} }
protected List<Artifact> buildArtifacts( List<ArtifactMetadata> artifactMetadatas, String repositoryId ) protected List<Artifact> buildArtifacts( Collection<ArtifactMetadata> artifactMetadatas, String repositoryId )
throws ArchivaRestServiceException throws ArchivaRestServiceException
{ {
try try

View File

@ -219,6 +219,9 @@ public class DefaultRepositoriesService
task.setOnlyUpdate( !fullScan ); task.setOnlyUpdate( !fullScan );
archivaIndexingTaskExecutor.executeTask( task ); archivaIndexingTaskExecutor.executeTask( task );
scheduler.queueTask( new RepositoryTask( repositoryId, fullScan ) );
return Boolean.TRUE; return Boolean.TRUE;
} }
catch ( Exception e ) catch ( Exception e )

View File

@ -27,7 +27,12 @@ import org.apache.archiva.indexer.search.SearchResultHit;
import org.apache.archiva.indexer.search.SearchResultLimits; import org.apache.archiva.indexer.search.SearchResultLimits;
import org.apache.archiva.indexer.search.SearchResults; import org.apache.archiva.indexer.search.SearchResults;
import org.apache.archiva.maven2.model.Artifact; import org.apache.archiva.maven2.model.Artifact;
import org.apache.archiva.rest.api.model.Dependency; import org.apache.archiva.metadata.model.ArtifactMetadata;
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.RepositorySessionFactory;
import org.apache.archiva.rest.api.model.ChecksumSearch;
import org.apache.archiva.rest.api.model.GroupIdList; import org.apache.archiva.rest.api.model.GroupIdList;
import org.apache.archiva.rest.api.model.SearchRequest; import org.apache.archiva.rest.api.model.SearchRequest;
import org.apache.archiva.rest.api.model.StringList; import org.apache.archiva.rest.api.model.StringList;
@ -42,8 +47,11 @@ import javax.ws.rs.core.Response;
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
/** /**
@ -60,6 +68,9 @@ public class DefaultSearchService
@Inject @Inject
private RepositorySearch repositorySearch; private RepositorySearch repositorySearch;
@Inject
private RepositorySessionFactory repositorySessionFactory;
@Override @Override
public List<Artifact> quickSearch( String queryString ) public List<Artifact> quickSearch( String queryString )
throws ArchivaRestServiceException throws ArchivaRestServiceException
@ -193,16 +204,46 @@ public class DefaultSearchService
} }
public List<Dependency> getDependencies( String groupId, String artifactId, String version )
throws ArchivaRestServiceException
{
return null; //To change body of implemented methods use File | Settings | File Templates.
}
public List<Artifact> getArtifactByChecksum( String checksum ) public List<Artifact> getArtifactByChecksum( ChecksumSearch checksumSearch )
throws ArchivaRestServiceException throws ArchivaRestServiceException
{ {
return null; //To change body of implemented methods use File | Settings | File Templates.
// if no repos set we use ones available for the user
if ( checksumSearch.getRepositories() == null || checksumSearch.getRepositories().isEmpty() )
{
checksumSearch.setRepositories( getObservableRepos() );
}
RepositorySession repositorySession = repositorySessionFactory.createSession();
MetadataRepository metadataRepository = repositorySession.getRepository();
Set<Artifact> artifactSet = new HashSet<>();
try
{
for ( String repoId : checksumSearch.getRepositories() )
{
Collection<ArtifactMetadata> artifactMetadatas =
metadataRepository.getArtifactsByChecksum( repoId, checksumSearch.getChecksum() );
artifactSet.addAll( buildArtifacts( artifactMetadatas, repoId ) );
}
return new ArrayList<>( artifactSet );
}
catch ( MetadataRepositoryException e )
{
log.error( e.getMessage(), e );
throw new ArchivaRestServiceException( e.getMessage(), e );
}
finally
{
repositorySession.closeQuietly();
}
} }
@Override @Override
@ -399,6 +440,7 @@ public class DefaultSearchService
} }
} }
//------------------------------------- //-------------------------------------
// internal // internal
//------------------------------------- //-------------------------------------

View File

@ -20,6 +20,7 @@ package org.apache.archiva.rest.services;
import org.apache.archiva.admin.model.beans.UiConfiguration; import org.apache.archiva.admin.model.beans.UiConfiguration;
import org.apache.archiva.maven2.model.Artifact; import org.apache.archiva.maven2.model.Artifact;
import org.apache.archiva.rest.api.model.ChecksumSearch;
import org.apache.archiva.rest.api.model.SearchRequest; import org.apache.archiva.rest.api.model.SearchRequest;
import org.apache.archiva.rest.api.services.SearchService; import org.apache.archiva.rest.api.services.SearchService;
import org.assertj.core.api.Assertions; import org.assertj.core.api.Assertions;
@ -145,8 +146,7 @@ public class SearchServiceTest
assertNotNull( artifacts ); assertNotNull( artifacts );
assertTrue( assertTrue(
" not 1 results for Bundle Symbolic Name org.apache.karaf.features.command but " + artifacts.size() + ":" " not 1 results for Bundle Symbolic Name org.apache.karaf.features.command but " + artifacts.size() + ":"
+ artifacts, artifacts.size() == 1 + artifacts, artifacts.size() == 1 );
);
} }
@Test @Test
@ -201,8 +201,7 @@ public class SearchServiceTest
@Test @Test
/** /**
* ensure we don't return response for an unknown repo * ensure we don't return response for an unknown repo
*/ */ public void searchWithSearchUnknwownRepoId()
public void searchWithSearchUnknwownRepoId()
throws Exception throws Exception
{ {
SearchService searchService = getSearchService( authorizationHeader ); SearchService searchService = getSearchService( authorizationHeader );
@ -221,8 +220,7 @@ public class SearchServiceTest
@Test @Test
/** /**
* ensure we revert to all observable repos in case of no repo in the request * ensure we revert to all observable repos in case of no repo in the request
*/ */ public void searchWithSearchNoRepos()
public void searchWithSearchNoRepos()
throws Exception throws Exception
{ {
SearchService searchService = getSearchService( authorizationHeader ); SearchService searchService = getSearchService( authorizationHeader );
@ -255,8 +253,7 @@ public class SearchServiceTest
@Test @Test
/** /**
* test we don't return 2 artifacts pom + zip one * test we don't return 2 artifacts pom + zip one
*/ */ public void getSearchArtifactsWithOnlyClassifier()
public void getSearchArtifactsWithOnlyClassifier()
throws Exception throws Exception
{ {
// force guest user creation if not exists // force guest user creation if not exists
@ -277,6 +274,39 @@ public class SearchServiceTest
assertEquals( 1, artifacts.size() ); assertEquals( 1, artifacts.size() );
} }
/**
* sha1 commons-logging 1.1 ba24d5de831911b684c92cd289ed5ff826271824
*/
@Test
public void search_with_sha1()
throws Exception
{
SearchService searchService = getSearchService( authorizationHeader );
List<Artifact> artifacts = searchService.getArtifactByChecksum(
new ChecksumSearch( null, "ba24d5de831911b684c92cd289ed5ff826271824" ) );
Assertions.assertThat( artifacts ).isNotNull().isNotEmpty().hasSize( 1 );
}
/**
* md5 commons-logging 1.1 6b62417e77b000a87de66ee3935edbf5
*/
@Test
public void search_with_md5()
throws Exception
{
SearchService searchService = getSearchService( authorizationHeader );
List<Artifact> artifacts = searchService.getArtifactByChecksum(
new ChecksumSearch( null, "6b62417e77b000a87de66ee3935edbf5" ) );
Assertions.assertThat( artifacts ).isNotNull().isNotEmpty().hasSize( 1 );
}
@Before @Before
public void createRepo() public void createRepo()
throws Exception throws Exception