From 61c83ff3d94c6e2e7a26319992a4ce7398562977 Mon Sep 17 00:00:00 2001 From: Olivier Lamy Date: Mon, 12 Jan 2015 17:07:54 +1100 Subject: [PATCH] [MRM-1867] Adding a find jar by checksum functionality to the REST api --- .../functors/ConsumerProcessFileClosure.java | 1 - .../repository/model/RepositoryTask.java | 18 ++++- .../rest/api/model/ChecksumSearch.java | 74 +++++++++++++++++++ .../rest/api/services/SearchService.java | 34 ++++++--- .../rest/services/AbstractRestService.java | 6 +- .../services/DefaultRepositoriesService.java | 3 + .../rest/services/DefaultSearchService.java | 58 +++++++++++++-- .../rest/services/SearchServiceTest.java | 46 ++++++++++-- 8 files changed, 207 insertions(+), 33 deletions(-) create mode 100644 archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/ChecksumSearch.java diff --git a/archiva-modules/archiva-base/archiva-repository-scanner/src/main/java/org/apache/archiva/repository/scanner/functors/ConsumerProcessFileClosure.java b/archiva-modules/archiva-base/archiva-repository-scanner/src/main/java/org/apache/archiva/repository/scanner/functors/ConsumerProcessFileClosure.java index 69db9b786..ca44dd9ba 100644 --- a/archiva-modules/archiva-base/archiva-repository-scanner/src/main/java/org/apache/archiva/repository/scanner/functors/ConsumerProcessFileClosure.java +++ b/archiva-modules/archiva-base/archiva-repository-scanner/src/main/java/org/apache/archiva/repository/scanner/functors/ConsumerProcessFileClosure.java @@ -30,7 +30,6 @@ import java.util.Map; /** * ConsumerProcessFileClosure * - * */ public class ConsumerProcessFileClosure implements Closure diff --git a/archiva-modules/archiva-scheduler/archiva-scheduler-repository-api/src/main/java/org/apache/archiva/scheduler/repository/model/RepositoryTask.java b/archiva-modules/archiva-scheduler/archiva-scheduler-repository-api/src/main/java/org/apache/archiva/scheduler/repository/model/RepositoryTask.java index e4a562075..c665a79a9 100644 --- a/archiva-modules/archiva-scheduler/archiva-scheduler-repository-api/src/main/java/org/apache/archiva/scheduler/repository/model/RepositoryTask.java +++ b/archiva-modules/archiva-scheduler/archiva-scheduler-repository-api/src/main/java/org/apache/archiva/scheduler/repository/model/RepositoryTask.java @@ -26,8 +26,6 @@ import java.io.File; /** * DataRefreshTask - task for discovering changes in the repository * and updating all associated data. - * - * */ public class RepositoryTask implements Task @@ -40,6 +38,22 @@ public class RepositoryTask 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() { return scanAll; diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/ChecksumSearch.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/ChecksumSearch.java new file mode 100644 index 000000000..9f22de6fd --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/ChecksumSearch.java @@ -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 repositories; + + private String checksum; + + public ChecksumSearch() + { + // nope + } + + public ChecksumSearch( List repositories, String checksum ) + { + this.repositories = repositories; + this.checksum = checksum; + } + + public List getRepositories() + { + return repositories; + } + + public void setRepositories( List 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 + '\'' + + '}'; + } +} diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/SearchService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/SearchService.java index 319abdfeb..1b3fa08b5 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/SearchService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/SearchService.java @@ -22,6 +22,7 @@ package org.apache.archiva.rest.api.services; import org.apache.archiva.maven2.model.Artifact; 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.SearchRequest; import org.apache.archiva.rest.api.model.StringList; @@ -82,8 +83,8 @@ public interface SearchService @GET @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } ) @RedbackAuthorization( noPermission = true, noRestriction = true ) - List getArtifactVersions( @QueryParam( "groupId" ) String groupId, - @QueryParam( "artifactId" ) String artifactId, + List getArtifactVersions( @QueryParam( "groupId" ) String groupId, // + @QueryParam( "artifactId" ) String artifactId, // @QueryParam( "packaging" ) String packaging ) throws ArchivaRestServiceException; @@ -117,23 +118,32 @@ public interface SearchService @QueryParam( "artifactId" ) String artifactId, @QueryParam( "version" ) String version ) throws ArchivaRestServiceException; + */ - @Path( "getArtifactByChecksum" ) @GET - @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } ) + @Path( "/artifact" ) + @Produces( "text/html" ) @RedbackAuthorization( noPermission = true, noRestriction = true ) - List getArtifactByChecksum( @QueryParam( "checksum" ) String checksum ) + Response redirectToArtifactFile( @QueryParam( "r" ) String repositoryId, // + @QueryParam( "g" ) String groupId, // + @QueryParam( "a" ) String artifactId, // + @QueryParam( "v" ) String version, // + @QueryParam( "p" ) String packaging, // + @QueryParam( "c" ) String classifier ) throws ArchivaRestServiceException; - */ - @GET - @Path( "/artifact" ) - @Produces( "text/html" ) + + /** + * If searchRequest contains repositories, the search will be done only on those repositories. + * if no repositories, the search will be apply on all repositories the current user has karma + */ + @Path( "artifactsByChecksum" ) + @POST + @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } ) @RedbackAuthorization( noPermission = true, noRestriction = true ) - Response redirectToArtifactFile( @QueryParam( "r" ) String repositoryId, @QueryParam( "g" ) String groupId, - @QueryParam( "a" ) String artifactId, @QueryParam( "v" ) String version, - @QueryParam( "p" ) String packaging, @QueryParam( "c" ) String classifier ) + List getArtifactByChecksum( ChecksumSearch checksumSearch ) throws ArchivaRestServiceException; + } diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/AbstractRestService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/AbstractRestService.java index 2282959b3..90e3cdad9 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/AbstractRestService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/AbstractRestService.java @@ -43,6 +43,7 @@ import org.apache.archiva.repository.RepositoryException; import org.apache.archiva.rest.api.services.ArchivaRestServiceException; import org.apache.archiva.rest.services.utils.ArtifactBuilder; 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.security.AccessDeniedException; import org.apache.archiva.security.ArchivaSecurityException; @@ -64,6 +65,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -108,7 +110,7 @@ public abstract class AbstractRestService @Inject @Named(value = "archivaTaskScheduler#repository") - protected DefaultRepositoryArchivaTaskScheduler repositoryTaskScheduler; + protected RepositoryArchivaTaskScheduler repositoryTaskScheduler; @Inject @@ -312,7 +314,7 @@ public abstract class AbstractRestService } } - protected List buildArtifacts( List artifactMetadatas, String repositoryId ) + protected List buildArtifacts( Collection artifactMetadatas, String repositoryId ) throws ArchivaRestServiceException { try diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java index dae631306..348f5d065 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultRepositoriesService.java @@ -219,6 +219,9 @@ public class DefaultRepositoriesService task.setOnlyUpdate( !fullScan ); archivaIndexingTaskExecutor.executeTask( task ); + + scheduler.queueTask( new RepositoryTask( repositoryId, fullScan ) ); + return Boolean.TRUE; } catch ( Exception e ) diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultSearchService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultSearchService.java index 62d0df2d3..68631041e 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultSearchService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultSearchService.java @@ -27,7 +27,12 @@ import org.apache.archiva.indexer.search.SearchResultHit; import org.apache.archiva.indexer.search.SearchResultLimits; import org.apache.archiva.indexer.search.SearchResults; 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.SearchRequest; import org.apache.archiva.rest.api.model.StringList; @@ -42,8 +47,11 @@ import javax.ws.rs.core.Response; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.TreeMap; /** @@ -60,6 +68,9 @@ public class DefaultSearchService @Inject private RepositorySearch repositorySearch; + @Inject + private RepositorySessionFactory repositorySessionFactory; + @Override public List quickSearch( String queryString ) throws ArchivaRestServiceException @@ -193,16 +204,46 @@ public class DefaultSearchService } - public List getDependencies( String groupId, String artifactId, String version ) - throws ArchivaRestServiceException - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - public List getArtifactByChecksum( String checksum ) + public List getArtifactByChecksum( ChecksumSearch checksumSearch ) 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 artifactSet = new HashSet<>(); + + try + { + for ( String repoId : checksumSearch.getRepositories() ) + { + Collection 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 @@ -399,6 +440,7 @@ public class DefaultSearchService } } + //------------------------------------- // internal //------------------------------------- diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/SearchServiceTest.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/SearchServiceTest.java index d9e751b7f..d694701f7 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/SearchServiceTest.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/SearchServiceTest.java @@ -20,6 +20,7 @@ package org.apache.archiva.rest.services; import org.apache.archiva.admin.model.beans.UiConfiguration; 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.services.SearchService; import org.assertj.core.api.Assertions; @@ -145,8 +146,7 @@ public class SearchServiceTest assertNotNull( artifacts ); assertTrue( " not 1 results for Bundle Symbolic Name org.apache.karaf.features.command but " + artifacts.size() + ":" - + artifacts, artifacts.size() == 1 - ); + + artifacts, artifacts.size() == 1 ); } @Test @@ -201,8 +201,7 @@ public class SearchServiceTest @Test /** * ensure we don't return response for an unknown repo - */ - public void searchWithSearchUnknwownRepoId() + */ public void searchWithSearchUnknwownRepoId() throws Exception { SearchService searchService = getSearchService( authorizationHeader ); @@ -221,8 +220,7 @@ public class SearchServiceTest @Test /** * ensure we revert to all observable repos in case of no repo in the request - */ - public void searchWithSearchNoRepos() + */ public void searchWithSearchNoRepos() throws Exception { SearchService searchService = getSearchService( authorizationHeader ); @@ -255,8 +253,7 @@ public class SearchServiceTest @Test /** * test we don't return 2 artifacts pom + zip one - */ - public void getSearchArtifactsWithOnlyClassifier() + */ public void getSearchArtifactsWithOnlyClassifier() throws Exception { // force guest user creation if not exists @@ -277,6 +274,39 @@ public class SearchServiceTest assertEquals( 1, artifacts.size() ); } + /** + * sha1 commons-logging 1.1 ba24d5de831911b684c92cd289ed5ff826271824 + */ + @Test + public void search_with_sha1() + throws Exception + { + SearchService searchService = getSearchService( authorizationHeader ); + + List 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 artifacts = searchService.getArtifactByChecksum( + new ChecksumSearch( null, "6b62417e77b000a87de66ee3935edbf5" ) ); + + Assertions.assertThat( artifacts ).isNotNull().isNotEmpty().hasSize( 1 ); + + } + @Before public void createRepo() throws Exception -- 2.39.5