From: Carlos Sanchez Date: Wed, 5 Nov 2014 19:11:08 +0000 (+0100) Subject: [MRM-1390] Add REST methods to search JCR store for generic metadata and properties X-Git-Tag: archiva-2.2.0~42 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=e4da1fa6f5a56bbf63bae1de7d1b7dd0ae0375aa;p=archiva.git [MRM-1390] Add REST methods to search JCR store for generic metadata and properties Added REST methods: artifactsByProjectVersionMetadata/{key}/{value} artifactsByMetadata/{key}/{value} artifactsByProperty/{key}/{value} searchArtifacts/{text} searchArtifacts/{key}/{text} In JCR implementation When searching into any property (key = nil) we can't do exact searchs --- diff --git a/archiva-docs/src/site/apt/adminguide/webservices/rest.apt.vm b/archiva-docs/src/site/apt/adminguide/webservices/rest.apt.vm index 91471710b..874c3eaf2 100644 --- a/archiva-docs/src/site/apt/adminguide/webservices/rest.apt.vm +++ b/archiva-docs/src/site/apt/adminguide/webservices/rest.apt.vm @@ -75,6 +75,39 @@ Using REST Services To know all the possible options, you can refer to the javadoc of SearchRequest class. +* Browse Service + + Get a Browse Service Client : + +%{snippet|id=cxf-browseservice-creation|ignoreDownloadError=true|url=https://raw.githubusercontent.com/apache/archiva/master/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/AbstractArchivaRestTest.java} + + Get artifacts based on project version metadata, generic metadata added previously in Archiva : + +%{snippet|id=get-artifacts-by-project-version-metadata|ignoreDownloadError=true|url=https://raw.githubusercontent.com/apache/archiva/master/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/BrowseServiceTest.java} + + Get artifacts based on the artifact properties : + +%{snippet|id=get-artifacts-by-metadata|ignoreDownloadError=true|url=https://raw.githubusercontent.com/apache/archiva/master/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/BrowseServiceTest.java} + + + Get artifacts based on the project properties from POM : + +%{snippet|id=get-artifacts-by-property|ignoreDownloadError=true|url=https://raw.githubusercontent.com/apache/archiva/master/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/BrowseServiceTest.java} + + + Searching by properties and metadata : + +%{snippet|id=search-artifacts-by-field|ignoreDownloadError=true|url=https://raw.githubusercontent.com/apache/archiva/master/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/BrowseServiceTest.java} + +%{snippet|id=search-artifacts|ignoreDownloadError=true|url=https://raw.githubusercontent.com/apache/archiva/master/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/BrowseServiceTest.java} + + + + Get Search + +%{snippet|id=quick-search|ignoreDownloadError=true|url=https://raw.githubusercontent.com/apache/archiva/master/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/SearchServiceTest.java} + + Dependencies to add in order to use those REST Services %{snippet|id=rest-dependencies|ignoreDownloadError=true|url=https://raw.githubusercontent.com/apache/archiva/master/pom.xml} diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/BrowseService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/BrowseService.java index 5cd0f50b9..777d15d90 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/BrowseService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/BrowseService.java @@ -231,4 +231,102 @@ public interface BrowseService @RedbackAuthorization(noPermission = true, noRestriction = true) List getArtifacts( @PathParam("r") String repositoryId ) throws ArchivaRestServiceException; + + /** + * Return List of artifacts from this repository with project version level metadata key matching value. If + * repository is not provided the search runs in all repositories. + * + * @param key + * @param value + * @param repositoryId + * @return + * @throws ArchivaRestServiceException + * @since 2.2 + */ + @Path( "artifactsByProjectVersionMetadata/{key}/{value}" ) + @GET + @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } ) + @RedbackAuthorization( noPermission = true, noRestriction = true ) + List getArtifactsByProjectVersionMetadata( @PathParam( "key" ) String key, @PathParam( "value" ) String value, + @QueryParam("repositoryId") String repositoryId ) + throws ArchivaRestServiceException; + + /** + * Return List of artifacts from this repository with artifact metadata key matching value. + * If repository is not provided the search runs in all repositories. + * + * @param key + * @param value + * @param repositoryId + * @return + * @throws ArchivaRestServiceException + * @since 2.2 + */ + @Path( "artifactsByMetadata/{key}/{value}" ) + @GET + @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } ) + @RedbackAuthorization( noPermission = true, noRestriction = true ) + List getArtifactsByMetadata( @PathParam( "key" ) String key, @PathParam( "value" ) String value, + @QueryParam("repositoryId") String repositoryId ) + throws ArchivaRestServiceException; + + /** + * Return List of artifacts from this repository with property key matching value. + * If repository is not provided the search runs in all repositories. + * + * @param key + * @param value + * @param repositoryId + * @return + * @throws ArchivaRestServiceException + * @since 2.2 + */ + @Path( "artifactsByProperty/{key}/{value}" ) + @GET + @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } ) + @RedbackAuthorization( noPermission = true, noRestriction = true ) + List getArtifactsByProperty( @PathParam( "key" ) String key, @PathParam( "value" ) String value, + @QueryParam("repositoryId") String repositoryId ) + throws ArchivaRestServiceException; + + /** + * Search artifacts with any property matching text. If repository is not provided the search runs in all + * repositories. If exact is true only the artifacts whose property match exactly are returned. + * + * @param text + * @param repositoryId + * @param exact + * @return + * @throws ArchivaRestServiceException + * @since 2.2 + */ + @Path( "searchArtifacts/{text}" ) + @GET + @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } ) + @RedbackAuthorization( noPermission = true, noRestriction = true ) + List searchArtifacts( @PathParam( "text" ) String text, + @QueryParam( "repositoryId" ) String repositoryId, + @QueryParam( "exact" ) Boolean exact ) + throws ArchivaRestServiceException; + + /** + * Search artifacts with the property specified by key matching text. If repository is not provided the search runs + * in all repositories. If exact is true only the artifacts whose property match exactly are returned. + * + * @param key + * @param text + * @param repositoryId + * @param exact + * @return + * @throws ArchivaRestServiceException + * @since 2.2 + */ + @Path( "searchArtifacts/{key}/{text}" ) + @GET + @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } ) + @RedbackAuthorization( noPermission = true, noRestriction = true ) + List searchArtifacts( @PathParam( "key" ) String key, @PathParam( "text" ) String text, + @QueryParam( "repositoryId" ) String repositoryId, + @QueryParam( "exact" ) Boolean exact ) + 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 b0107cc38..2282959b3 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 @@ -62,6 +62,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; + import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -322,9 +323,14 @@ public abstract class AbstractRestService for ( ArtifactMetadata artifact : artifactMetadatas ) { + String repoId = repositoryId != null ? repositoryId : artifact.getRepositoryId(); + if ( repoId == null ) { + throw new IllegalStateException( "Repository Id is null" ); + } + ArtifactBuilder builder = new ArtifactBuilder().forArtifactMetadata( artifact ).withManagedRepositoryContent( - repositoryContentFactory.getManagedRepositoryContent( repositoryId ) ); + repositoryContentFactory.getManagedRepositoryContent( repoId ) ); Artifact art = builder.build(); art.setUrl( getArtifactUrl( art, repositoryId ) ); artifacts.add( art ); diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java index c7af0fece..5e5a4654b 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java @@ -941,6 +941,66 @@ public class DefaultBrowseService } } + @Override + public List getArtifactsByProjectVersionMetadata( String key, String value, String repositoryId ) + throws ArchivaRestServiceException + { + RepositorySession repositorySession = repositorySessionFactory.createSession(); + try + { + List artifactMetadatas = repositorySession.getRepository().getArtifactsByProjectVersionMetadata( key, value, repositoryId ); + return buildArtifacts( artifactMetadatas, repositoryId ); + } + catch ( MetadataRepositoryException e ) + { + throw new ArchivaRestServiceException( e.getMessage(), e ); + } + finally + { + repositorySession.close(); + } + } + + @Override + public List getArtifactsByMetadata( String key, String value, String repositoryId ) + throws ArchivaRestServiceException + { + RepositorySession repositorySession = repositorySessionFactory.createSession(); + try + { + List artifactMetadatas = repositorySession.getRepository().getArtifactsByMetadata( key, value, repositoryId ); + return buildArtifacts( artifactMetadatas, repositoryId ); + } + catch ( MetadataRepositoryException e ) + { + throw new ArchivaRestServiceException( e.getMessage(), e ); + } + finally + { + repositorySession.close(); + } + } + + @Override + public List getArtifactsByProperty( String key, String value, String repositoryId ) + throws ArchivaRestServiceException + { + RepositorySession repositorySession = repositorySessionFactory.createSession(); + try + { + List artifactMetadatas = repositorySession.getRepository().getArtifactsByProperty( key, value, repositoryId ); + return buildArtifacts( artifactMetadatas, repositoryId ); + } + catch ( MetadataRepositoryException e ) + { + throw new ArchivaRestServiceException( e.getMessage(), e ); + } + finally + { + repositorySession.close(); + } + } + @Override public Boolean importMetadata( MetadataAddRequest metadataAddRequest, String repositoryId ) throws ArchivaRestServiceException @@ -959,6 +1019,48 @@ public class DefaultBrowseService return result; } + @Override + public List searchArtifacts( String text, String repositoryId, Boolean exact ) + throws ArchivaRestServiceException + { + RepositorySession repositorySession = repositorySessionFactory.createSession(); + try + { + List artifactMetadatas = + repositorySession.getRepository().searchArtifacts( text, repositoryId, exact == null ? false : exact ); + return buildArtifacts( artifactMetadatas, repositoryId ); + } + catch ( MetadataRepositoryException e ) + { + throw new ArchivaRestServiceException( e.getMessage(), e ); + } + finally + { + repositorySession.close(); + } + } + + @Override + public List searchArtifacts( String key, String text, String repositoryId, Boolean exact ) + throws ArchivaRestServiceException + { + RepositorySession repositorySession = repositorySessionFactory.createSession(); + try + { + List artifactMetadatas = + repositorySession.getRepository().searchArtifacts( key, text, repositoryId, exact == null ? false : exact ); + return buildArtifacts( artifactMetadatas, repositoryId ); + } + catch ( MetadataRepositoryException e ) + { + throw new ArchivaRestServiceException( e.getMessage(), e ); + } + finally + { + repositorySession.close(); + } + } + //--------------------------- // internals //--------------------------- diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/AbstractArchivaRestTest.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/AbstractArchivaRestTest.java index 310448015..2453e6af8 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/AbstractArchivaRestTest.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/AbstractArchivaRestTest.java @@ -252,6 +252,7 @@ public abstract class AbstractArchivaRestTest protected BrowseService getBrowseService( String authzHeader, boolean useXml ) { + // START SNIPPET: cxf-browseservice-creation BrowseService service = JAXRSClientFactory.create( getBaseUrl() + "/" + getRestServicesPath() + "/archivaServices/", BrowseService.class, @@ -274,6 +275,7 @@ public abstract class AbstractArchivaRestTest WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE ); } return service; + // END SNIPPET: cxf-browseservice-creation } diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/BrowseServiceTest.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/BrowseServiceTest.java index 99cb83b5d..9490cf6a6 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/BrowseServiceTest.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/BrowseServiceTest.java @@ -236,6 +236,92 @@ public class BrowseServiceTest } + @Test + public void getArtifactsByMetadata() + throws Exception + { + // START SNIPPET: get-artifacts-by-metadata + BrowseService browseService = getBrowseService( authorizationHeader, true ); + + List artifactDownloadInfos = browseService.getArtifactsByMetadata( "type", "pom", TEST_REPO_ID ); + + assertThat( artifactDownloadInfos ).isNotNull().isNotEmpty().hasSize( 11 ); + // END SNIPPET: get-artifacts-by-metadata + } + + + @Test + public void getArtifactsByProjectVersionMetadata() + throws Exception + { + // START SNIPPET: get-artifacts-by-project-version-metadata + BrowseService browseService = getBrowseService( authorizationHeader, true ); + + browseService.addMetadata( "commons-cli", "commons-cli", "1.0", "wine", "bordeaux", TEST_REPO_ID ); + + List artifactDownloadInfos = browseService.getArtifactsByProjectVersionMetadata( "wine", "bordeaux", TEST_REPO_ID ); + + assertThat( artifactDownloadInfos ).isNotNull().isNotEmpty().hasSize( 3 ); + // END SNIPPET: get-artifacts-by-project-version-metadata + } + + + @Test + public void getArtifactsByProjectVersionMetadataWithNoRepository() + throws Exception + { + BrowseService browseService = getBrowseService( authorizationHeader, true ); + + browseService.addMetadata( "commons-cli", "commons-cli", "1.0", "wine", "bordeaux", TEST_REPO_ID ); + + List artifactDownloadInfos = browseService.getArtifactsByProjectVersionMetadata( "wine", "bordeaux", null ); + + assertThat( artifactDownloadInfos ).isNotNull().isNotEmpty().hasSize( 3 ); + } + + + @Test + public void getArtifactsByProperty() + throws Exception + { + // START SNIPPET: get-artifacts-by-property + BrowseService browseService = getBrowseService( authorizationHeader, true ); + + List artifactDownloadInfos = browseService.getArtifactsByProperty( "org.name", "The Apache Software Foundation", TEST_REPO_ID ); + + assertThat( artifactDownloadInfos ).isNotNull().isNotEmpty().hasSize( 7 ); + // END SNIPPET: get-artifacts-by-property + } + + + @Test + public void searchArtifacts() + throws Exception + { + // START SNIPPET: search-artifacts + BrowseService browseService = getBrowseService( authorizationHeader, true ); + + List artifactDownloadInfos = browseService.searchArtifacts( "The Apache Software Foundation", TEST_REPO_ID, true ); + + assertThat( artifactDownloadInfos ).isNotNull().isNotEmpty().hasSize( 7 ); + // END SNIPPET: search-artifacts + } + + + @Test + public void searchArtifactsByField() + throws Exception + { + // START SNIPPET: search-artifacts-by-field + BrowseService browseService = getBrowseService( authorizationHeader, true ); + + List artifactDownloadInfos = browseService.searchArtifacts( "org.name", "The Apache Software Foundation", TEST_REPO_ID, true ); + + assertThat( artifactDownloadInfos ).isNotNull().isNotEmpty().hasSize( 7 ); + // END SNIPPET: search-artifacts-by-field + } + + @Test public void readArtifactContentText() throws Exception diff --git a/archiva-modules/metadata/metadata-repository-api/pom.xml b/archiva-modules/metadata/metadata-repository-api/pom.xml index 8cfd25d68..face82553 100644 --- a/archiva-modules/metadata/metadata-repository-api/pom.xml +++ b/archiva-modules/metadata/metadata-repository-api/pom.xml @@ -67,6 +67,11 @@ assertj-core test + + org.apache.archiva + generic-metadata-support + test + 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 7372229bd..8bec50167 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 @@ -124,6 +124,27 @@ public abstract class AbstractMetadataRepository throw new UnsupportedOperationException(); } + @Override + public List getArtifactsByProjectVersionMetadata( String key , String value , String repositoryId ) + throws MetadataRepositoryException + { + throw new UnsupportedOperationException(); + } + + @Override + public List getArtifactsByMetadata( String key , String value , String repositoryId ) + throws MetadataRepositoryException + { + throw new UnsupportedOperationException(); + } + + @Override + public List getArtifactsByProperty( String key, String value, String repositoryId ) + throws MetadataRepositoryException + { + throw new UnsupportedOperationException(); + } + @Override public void removeArtifact( String repositoryId, String namespace, String project, String version, String id ) throws MetadataRepositoryException @@ -277,4 +298,18 @@ public abstract class AbstractMetadataRepository throw new UnsupportedOperationException(); } + @Override + public List searchArtifacts( String text, String repositoryId, boolean exact ) + throws MetadataRepositoryException + { + throw new UnsupportedOperationException(); + } + + @Override + public List searchArtifacts( String key, String text, String repositoryId, boolean exact ) + throws MetadataRepositoryException + { + throw new UnsupportedOperationException(); + } + } 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 eb7648bdf..421eccd91 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 @@ -102,6 +102,43 @@ public interface MetadataRepository Collection getArtifactsByChecksum( String repositoryId, String checksum ) throws MetadataRepositoryException; + /** + * Get artifacts with a project version metadata key that matches the passed value. + * + * @param key + * @param value + * @param repositoryId can be null, meaning search in all repositories + * @return a list of artifacts + * @throws MetadataRepositoryException + */ + List getArtifactsByProjectVersionMetadata( String key, String value, String repositoryId ) + throws MetadataRepositoryException; + + /** + * Get artifacts with an artifact metadata key that matches the passed value. + * + * @param key + * @param value + * @param repositoryId can be null, meaning search in all repositories + * @return a list of artifacts + * @throws MetadataRepositoryException + */ + List getArtifactsByMetadata( String key, String value, String repositoryId ) + throws MetadataRepositoryException; + + /** + * Get artifacts with a property key that matches the passed value. + * Possible keys are 'scm.url', 'org.name', 'url', 'mailingList.0.name', 'license.0.name',... + * + * @param key + * @param value + * @param repositoryId can be null, meaning search in all repositories + * @return a list of artifacts + * @throws MetadataRepositoryException + */ + List getArtifactsByProperty( String key, String value, String repositoryId ) + throws MetadataRepositoryException; + void removeArtifact( String repositoryId, String namespace, String project, String version, String id ) throws MetadataRepositoryException; @@ -270,4 +307,30 @@ public interface MetadataRepository T obtainAccess( Class aClass ) throws MetadataRepositoryException; + + /** + * Full text artifacts search. + * + * @param text + * @param repositoryId can be null to search in all repositories + * @param exact running an exact search, the value must exactly match the text. + * @return a list of artifacts + * @throws MetadataRepositoryException + */ + List searchArtifacts( String text, String repositoryId, boolean exact ) + throws MetadataRepositoryException; + + /** + * Full text artifacts search inside the specified key. + * + * @param key search only inside this key + * @param text + * @param repositoryId can be null to search in all repositories + * @param exact running an exact search, the value must exactly match the text. + * @return a list of artifacts + * @throws MetadataRepositoryException + */ + List searchArtifacts( String key, String text, String repositoryId, boolean exact ) + 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 221eae279..75c961fbc 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 @@ -19,7 +19,26 @@ package org.apache.archiva.metadata.repository; * under the License. */ +import static org.assertj.core.api.Assertions.assertThat; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + import junit.framework.TestCase; + +import org.apache.archiva.metadata.generic.GenericMetadataFacet; +import org.apache.archiva.metadata.generic.GenericMetadataFacetFactory; import org.apache.archiva.metadata.model.ArtifactMetadata; import org.apache.archiva.metadata.model.CiManagement; import org.apache.archiva.metadata.model.Dependency; @@ -41,22 +60,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.test.context.ContextConfiguration; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.TimeZone; - -import static org.assertj.core.api.Assertions.assertThat; - @RunWith( ArchivaSpringJUnit4ClassRunner.class ) @ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context.xml" } ) public abstract class AbstractMetadataRepositoryTest @@ -76,6 +79,10 @@ public abstract class AbstractMetadataRepositoryTest private static final String TEST_PROJECT_VERSION_2_0 = "2.0"; + private static final String TEST_URL = "http://archiva.apache.org"; + + private static final Organization TEST_ORGANIZATION = new Organization( "Apache", "http://apache.org" ); + private static final String TEST_FACET_ID = "test-facet-id"; private static final String TEST_NAME = "test/name"; @@ -88,7 +95,9 @@ public abstract class AbstractMetadataRepositoryTest private static final String TEST_SHA1 = "2e5daf0201ddeb068a62d5e08da18657ab2c6be9"; - private static final String TEST_METADATA_VALUE = "test-metadata"; + private static final String TEST_METADATA_KEY = "testkey"; + + private static final String TEST_METADATA_VALUE = "testmetadata"; protected Logger log = LoggerFactory.getLogger( getClass() ); @@ -125,6 +134,10 @@ public abstract class AbstractMetadataRepositoryTest return new TestMetadataFacet( "", TEST_VALUE ); } } ); + + // for the getArtifactsByProjectVersionMetadata tests + factories.put( GenericMetadataFacet.FACET_ID, new GenericMetadataFacetFactory() ); + return factories; } @@ -301,10 +314,7 @@ public abstract class AbstractMetadataRepositoryTest tracker.setUrl( "issue tracker url" ); metadata.setIssueManagement( tracker ); - Organization org = new Organization(); - org.setName( "org name" ); - org.setUrl( "url" ); - metadata.setOrganization( org ); + metadata.setOrganization( TEST_ORGANIZATION ); License l = new License(); l.setName( "license name" ); @@ -341,8 +351,8 @@ public abstract class AbstractMetadataRepositoryTest assertEquals( "system", metadata.getIssueManagement().getSystem() ); assertEquals( "issue tracker url", metadata.getIssueManagement().getUrl() ); - assertEquals( "org name", metadata.getOrganization().getName() ); - assertEquals( "url", metadata.getOrganization().getUrl() ); + assertEquals( TEST_ORGANIZATION.getName(), metadata.getOrganization().getName() ); + assertEquals( TEST_ORGANIZATION.getUrl(), metadata.getOrganization().getUrl() ); assertEquals( 1, metadata.getMailingLists().size() ); MailingList retrievedMailingList = metadata.getMailingLists().get( 0 ); @@ -1192,6 +1202,72 @@ public abstract class AbstractMetadataRepositoryTest assertThat( artifactsByChecksum ).isNotNull().isEmpty(); } + @Test + public void testGetArtifactsByProjectVersionMetadata() + throws Exception + { + createArtifactWithGenericMetadataFacet( 10 ); + Collection artifactsByMetadata = + repository.getArtifactsByProjectVersionMetadata( TEST_METADATA_KEY, TEST_METADATA_VALUE, TEST_REPO_ID ); + assertThat( artifactsByMetadata ).hasSize( 1 ); + ArtifactMetadata artifactMetadata = artifactsByMetadata.iterator().next(); + assertThat( artifactMetadata.getId() ).isEqualTo( "projectId-1.0.jar" ); + assertThat( artifactMetadata.getSha1() ).isEqualTo( TEST_SHA1 ); + assertThat( artifactMetadata.getRepositoryId() ).isEqualTo( TEST_REPO_ID ); + } + + @Test + public void testGetArtifactsByProjectVersionMetadataNoRepository() + throws Exception + { + createArtifactWithGenericMetadataFacet(); + Collection artifactsByMetadata = + repository.getArtifactsByProjectVersionMetadata( TEST_METADATA_KEY, TEST_METADATA_VALUE, null ); + assertThat( artifactsByMetadata ).hasSize( 1 ); + assertThat( artifactsByMetadata.iterator().next().getRepositoryId() ).isNotNull().isNotEmpty(); + } + + @Test + public void testGetArtifactsByProjectVersionMetadataAllRepositories() + throws Exception + { + createArtifactWithGenericMetadataFacet(); + Collection artifactsByMetadata = + repository.getArtifactsByProjectVersionMetadata( TEST_METADATA_KEY, TEST_METADATA_VALUE, null ); + assertThat( artifactsByMetadata ).hasSize( 1 ); + } + + @Test + public void testGetArtifactsByMetadataAllRepositories() + throws Exception + { + createArtifactWithMavenArtifactFacet(); + Collection artifactsByMetadata = + repository.getArtifactsByMetadata( "foo", TEST_METADATA_VALUE, null ); + assertThat( artifactsByMetadata ).hasSize( 1 ); + ArtifactMetadata artifactMetadata = artifactsByMetadata.iterator().next(); + assertThat( artifactMetadata.getId() ).isEqualTo( "projectId-1.0.jar" ); + assertThat( artifactMetadata.getSha1() ).isEqualTo( TEST_SHA1 ); + assertThat( artifactMetadata.getRepositoryId() ).isEqualTo( TEST_REPO_ID ); + MetadataFacet facet = artifactMetadata.getFacet( TEST_FACET_ID ); + assertThat( facet ).isNotNull(); + assertThat( facet.toProperties() ).isEqualTo( Collections.singletonMap( "foo", TEST_METADATA_VALUE ) ); + } + + @Test + public void testGetArtifactsByPropertySingleResult() + throws Exception + { + createArtifactWithData(); + // only works on JCR implementation + // Collection artifactsByProperty = repository.getArtifactsByProperty( "org.name", TEST_ORGANIZATION.getName(), TEST_REPO_ID ); + Collection artifactsByProperty = repository.getArtifactsByProperty( "url", TEST_URL, TEST_REPO_ID ); + assertThat( artifactsByProperty ).hasSize( 1 ); + ArtifactMetadata artifactMetadata = artifactsByProperty.iterator().next(); + assertThat( artifactMetadata.getId() ).isEqualTo( "projectId-1.0.jar" ); + assertThat( artifactMetadata.getSha1() ).isEqualTo( TEST_SHA1 ); + assertThat( artifactMetadata.getRepositoryId() ).isEqualTo( TEST_REPO_ID ); + } @Test public void testDeleteRepository() @@ -1424,6 +1500,78 @@ public abstract class AbstractMetadataRepositoryTest } + @Test + public void testSearchArtifactsByKey() + throws Exception + { + createArtifactWithData(); + Collection artifactsByProperty = repository.searchArtifacts( "url", TEST_URL, TEST_REPO_ID, false ); + assertThat( artifactsByProperty ).isNotNull().isNotEmpty(); + } + + @Test + public void testSearchArtifactsByKeyExact() + throws Exception + { + createArtifactWithData(); + Collection artifactsByProperty = repository.searchArtifacts( "url", TEST_URL, TEST_REPO_ID, true ); + assertThat( artifactsByProperty ).isNotNull().isNotEmpty(); + artifactsByProperty = repository.searchArtifacts( "org.name", "pache", TEST_REPO_ID, true ); + assertThat( artifactsByProperty ).isNotNull().isEmpty(); + } + + @Test + public void testSearchArtifactsByFacetKey() + throws Exception + { + createArtifactWithGenericMetadataFacet(); + Collection artifactsByProperty = repository.searchArtifacts( TEST_METADATA_KEY, TEST_METADATA_VALUE, TEST_REPO_ID, false ); + assertThat( artifactsByProperty ).isNotNull().isNotEmpty(); + } + + @Test + public void testSearchArtifactsByFacetKeyAllRepos() + throws Exception + { + createArtifactWithGenericMetadataFacet(); + Collection artifactsByProperty = repository.searchArtifacts( TEST_METADATA_KEY, TEST_METADATA_VALUE, null, false ); + assertThat( artifactsByProperty ).isNotNull().isNotEmpty(); + } + + @Test + public void testSearchArtifactsFullText() + throws Exception + { + createArtifactWithGenericMetadataFacet(); + // only works in JCR + // Collection artifactsByProperty = repository.searchArtifacts( TEST_URL, TEST_REPO_ID, false ); + Collection artifactsByProperty = + repository.searchArtifacts( TEST_METADATA_VALUE, TEST_REPO_ID, false ); + assertThat( artifactsByProperty ).isNotNull().isNotEmpty(); + } + + @Test + public void testSearchArtifactsFullTextExact() + throws Exception + { + createArtifactWithGenericMetadataFacet(); + // only works in JCR + // Collection artifactsByProperty = repository.searchArtifacts( TEST_URL, TEST_REPO_ID, true ); + Collection artifactsByProperty = + repository.searchArtifacts( TEST_METADATA_VALUE, TEST_REPO_ID, true ); + assertThat( artifactsByProperty ).isNotNull().isNotEmpty(); + artifactsByProperty = repository.searchArtifacts( TEST_METADATA_VALUE.substring( 2 ), TEST_REPO_ID, true ); + assertThat( artifactsByProperty ).isNotNull().isEmpty(); + } + + @Test + public void testSearchArtifactsFullTextByFacet() + throws Exception + { + createArtifactWithGenericMetadataFacet(); + Collection artifactsByProperty = repository.searchArtifacts( TEST_METADATA_VALUE, TEST_REPO_ID, false ); + assertThat( artifactsByProperty ).isNotNull().isNotEmpty(); + } private static ProjectMetadata createProject() { @@ -1438,6 +1586,74 @@ public abstract class AbstractMetadataRepositoryTest return project; } + private void createArtifactWithGenericMetadataFacet() + throws MetadataRepositoryException, MetadataResolutionException + { + createArtifactWithGenericMetadataFacet( 1 ); + } + + private void createArtifactWithGenericMetadataFacet( int artifacts ) + throws MetadataRepositoryException, MetadataResolutionException + { + MetadataFacet metadataFacet = new GenericMetadataFacet(); + Map properties = new HashMap<>(); + properties.put( TEST_METADATA_KEY, TEST_METADATA_VALUE ); + metadataFacet.fromProperties( properties ); + createArtifactWithFacet( artifacts, null, metadataFacet ); + } + + private void createArtifactWithMavenArtifactFacet() + throws MetadataRepositoryException, MetadataResolutionException + { + createArtifactWithMavenArtifactFacet( 1 ); + } + + private void createArtifactWithMavenArtifactFacet( int artifacts ) + throws MetadataRepositoryException, MetadataResolutionException + { + TestMetadataFacet facet = new TestMetadataFacet( TEST_METADATA_VALUE ); + createArtifactWithFacet( artifacts, facet, null ); + } + + private void createArtifactWithFacet( int artifacts, MetadataFacet artifactFacet, + MetadataFacet projectVersionMetadataFacet ) + throws MetadataRepositoryException, MetadataResolutionException + { + for ( int i = 0; i < artifacts; i++ ) + { + ArtifactMetadata artifact = createArtifact(); + if ( artifactFacet != null ) + { + artifact.addFacet( artifactFacet ); + } + repository.updateArtifact( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION, artifact ); + } + if ( projectVersionMetadataFacet != null ) + { + ProjectVersionMetadata metadata = + repository.getProjectVersion( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION ); + metadata.addFacet( projectVersionMetadataFacet ); + metadata.setOrganization( TEST_ORGANIZATION ); + metadata.setUrl( TEST_URL ); + repository.updateProjectVersion( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, metadata ); + } + repository.save(); + } + + private void createArtifactWithData() + throws MetadataRepositoryException, MetadataResolutionException + { + ArtifactMetadata artifact = createArtifact(); + repository.updateArtifact( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION, artifact ); + ProjectVersionMetadata metadata = + repository.getProjectVersion( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION ); + metadata.setOrganization( TEST_ORGANIZATION ); + metadata.setUrl( TEST_URL ); + + repository.updateProjectVersion( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, metadata ); + repository.save(); + } + private static ArtifactMetadata createArtifact() { return createArtifact( "jar" ); diff --git a/archiva-modules/plugins/metadata-store-cassandra/pom.xml b/archiva-modules/plugins/metadata-store-cassandra/pom.xml index 6a8072c87..83a6b1710 100644 --- a/archiva-modules/plugins/metadata-store-cassandra/pom.xml +++ b/archiva-modules/plugins/metadata-store-cassandra/pom.xml @@ -130,6 +130,11 @@ spring-test test + + org.apache.archiva + generic-metadata-support + test + org.assertj assertj-core diff --git a/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java b/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java index f58b429b9..779c19f1c 100644 --- a/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java +++ b/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java @@ -21,6 +21,7 @@ package org.apache.archiva.metadata.repository.cassandra; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; + import me.prettyprint.cassandra.serializers.LongSerializer; import me.prettyprint.cassandra.serializers.StringSerializer; import me.prettyprint.cassandra.service.template.ColumnFamilyResult; @@ -37,6 +38,7 @@ import me.prettyprint.hector.api.mutation.MutationResult; 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.model.ArtifactMetadata; import org.apache.archiva.metadata.model.CiManagement; @@ -67,6 +69,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.persistence.PersistenceException; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -1823,6 +1826,26 @@ public class CassandraMetadataRepository return artifactMetadataMap.values(); } + @Override + public List getArtifactsByProjectVersionMetadata( String key, String value, String repositoryId ) + throws MetadataRepositoryException + { + throw new UnsupportedOperationException( "not yet implemented in Cassandra backend" ); + } + + @Override + public List getArtifactsByMetadata( String key, String value, String repositoryId ) + throws MetadataRepositoryException + { + throw new UnsupportedOperationException( "not yet implemented in Cassandra backend" ); + } + + @Override + public List getArtifactsByProperty( String key, String value, String repositoryId ) + throws MetadataRepositoryException + { + throw new UnsupportedOperationException( "getArtifactsByProperty not yet implemented in Cassandra backend" ); + } @Override public void removeArtifact( final String repositoryId, final String namespace, final String project, @@ -2174,4 +2197,18 @@ public class CassandraMetadataRepository { return ModelMapperHolder.MODEL_MAPPER; } + + @Override + public List searchArtifacts( String text, String repositoryId, boolean exact ) + throws MetadataRepositoryException + { + throw new UnsupportedOperationException( "searchArtifacts not yet implemented in Cassandra backend" ); + } + + @Override + public List searchArtifacts( String key, String text, String repositoryId, boolean exact ) + throws MetadataRepositoryException + { + throw new UnsupportedOperationException( "searchArtifacts not yet implemented in Cassandra backend" ); + } } diff --git a/archiva-modules/plugins/metadata-store-cassandra/src/test/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepositoryTest.java b/archiva-modules/plugins/metadata-store-cassandra/src/test/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepositoryTest.java index c26a660e8..97b3718f7 100644 --- a/archiva-modules/plugins/metadata-store-cassandra/src/test/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepositoryTest.java +++ b/archiva-modules/plugins/metadata-store-cassandra/src/test/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepositoryTest.java @@ -19,21 +19,19 @@ package org.apache.archiva.metadata.repository.cassandra; * under the License. */ -import org.apache.archiva.metadata.model.MailingList; import org.apache.archiva.metadata.model.MetadataFacetFactory; import org.apache.archiva.metadata.repository.AbstractMetadataRepositoryTest; import org.apache.archiva.metadata.repository.cassandra.model.ProjectVersionMetadataModel; import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import javax.inject.Inject; import javax.inject.Named; + import java.io.File; -import java.util.List; import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; @@ -44,8 +42,6 @@ import static org.assertj.core.api.Assertions.assertThat; public class CassandraMetadataRepositoryTest extends AbstractMetadataRepositoryTest { - private Logger logger = LoggerFactory.getLogger( getClass() ); - @Inject @Named(value = "archivaEntityManagerFactory#cassandra") CassandraArchivaManager cassandraArchivaManager; @@ -73,6 +69,103 @@ public class CassandraMetadataRepositoryTest clearReposAndNamespace( cassandraArchivaManager ); } + @Override + @Ignore + public void testGetArtifactsByProjectVersionMetadata() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testGetArtifactsByProjectVersionMetadataNoRepository() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testGetArtifactsByProjectVersionMetadataAllRepositories() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testGetArtifactsByMetadataAllRepositories() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testGetArtifactsByPropertySingleResult() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testSearchArtifactsByKey() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testSearchArtifactsByKeyExact() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testSearchArtifactsFullText() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testSearchArtifactsFullTextExact() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testSearchArtifactsByFacetKeyAllRepos() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testSearchArtifactsByFacetKey() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testSearchArtifactsFullTextByFacet() + throws Exception + { + // TODO not implemented + } + + /** * ensure all dependant tables are cleaned up (mailinglist, license, dependencies) * diff --git a/archiva-modules/plugins/metadata-store-file/pom.xml b/archiva-modules/plugins/metadata-store-file/pom.xml index ae161cd01..87b5c3e13 100644 --- a/archiva-modules/plugins/metadata-store-file/pom.xml +++ b/archiva-modules/plugins/metadata-store-file/pom.xml @@ -61,6 +61,11 @@ ${project.version} test + + org.apache.archiva + generic-metadata-support + test + org.apache.logging.log4j log4j-jcl diff --git a/archiva-modules/plugins/metadata-store-file/src/main/java/org/apache/archiva/metadata/repository/file/FileMetadataRepository.java b/archiva-modules/plugins/metadata-store-file/src/main/java/org/apache/archiva/metadata/repository/file/FileMetadataRepository.java index e04c7d3bf..cca21bcd4 100644 --- a/archiva-modules/plugins/metadata-store-file/src/main/java/org/apache/archiva/metadata/repository/file/FileMetadataRepository.java +++ b/archiva-modules/plugins/metadata-store-file/src/main/java/org/apache/archiva/metadata/repository/file/FileMetadataRepository.java @@ -778,6 +778,27 @@ public class FileMetadataRepository } } + @Override + public List getArtifactsByProjectVersionMetadata( String key, String value, String repositoryId ) + throws MetadataRepositoryException + { + throw new UnsupportedOperationException( "not yet implemented in File backend" ); + } + + @Override + public List getArtifactsByMetadata( String key, String value, String repositoryId ) + throws MetadataRepositoryException + { + throw new UnsupportedOperationException( "not yet implemented in File backend" ); + } + + @Override + public List getArtifactsByProperty( String key, String value, String repositoryId ) + throws MetadataRepositoryException + { + throw new UnsupportedOperationException( "getArtifactsByProperty not yet implemented in File backend" ); + } + private File getMetadataDirectory( String repoId, String facetId ) { return new File( getBaseDirectory( repoId ), "facets/" + facetId ); @@ -1296,4 +1317,18 @@ public class FileMetadataRepository } } } + + @Override + public List searchArtifacts( String text, String repositoryId, boolean exact ) + throws MetadataRepositoryException + { + throw new UnsupportedOperationException( "searchArtifacts not yet implemented in File backend" ); + } + + @Override + public List searchArtifacts( String key, String text, String repositoryId, boolean exact ) + throws MetadataRepositoryException + { + throw new UnsupportedOperationException( "searchArtifacts not yet implemented in File backend" ); + } } diff --git a/archiva-modules/plugins/metadata-store-file/src/test/java/org/apache/archiva/metadata/repository/file/FileMetadataRepositoryTest.java b/archiva-modules/plugins/metadata-store-file/src/test/java/org/apache/archiva/metadata/repository/file/FileMetadataRepositoryTest.java index df97f2e8c..aa589f3f2 100644 --- a/archiva-modules/plugins/metadata-store-file/src/test/java/org/apache/archiva/metadata/repository/file/FileMetadataRepositoryTest.java +++ b/archiva-modules/plugins/metadata-store-file/src/test/java/org/apache/archiva/metadata/repository/file/FileMetadataRepositoryTest.java @@ -26,6 +26,7 @@ import org.apache.archiva.configuration.ArchivaConfiguration; import org.apache.archiva.configuration.Configuration; import org.apache.archiva.configuration.ManagedRepositoryConfiguration; import org.junit.Before; +import org.junit.Ignore; import java.io.File; import java.util.Map; @@ -55,6 +56,102 @@ public class FileMetadataRepositoryTest this.repository = new FileMetadataRepository( factories, config ); } + @Override + @Ignore + public void testGetArtifactsByProjectVersionMetadata() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testGetArtifactsByProjectVersionMetadataNoRepository() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testGetArtifactsByProjectVersionMetadataAllRepositories() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testGetArtifactsByMetadataAllRepositories() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testGetArtifactsByPropertySingleResult() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testSearchArtifactsByKey() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testSearchArtifactsByKeyExact() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testSearchArtifactsFullText() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testSearchArtifactsFullTextExact() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testSearchArtifactsByFacetKeyAllRepos() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testSearchArtifactsByFacetKey() + throws Exception + { + // TODO not implemented + } + + @Override + @Ignore + public void testSearchArtifactsFullTextByFacet() + throws Exception + { + // TODO not implemented + } + protected static ArchivaConfiguration createTestConfiguration( File directory ) { ArchivaConfiguration config = mock( ArchivaConfiguration.class ); diff --git a/archiva-modules/plugins/metadata-store-jcr/pom.xml b/archiva-modules/plugins/metadata-store-jcr/pom.xml index e139e8a4d..910298258 100644 --- a/archiva-modules/plugins/metadata-store-jcr/pom.xml +++ b/archiva-modules/plugins/metadata-store-jcr/pom.xml @@ -78,6 +78,16 @@ spring-test test + + org.apache.archiva + generic-metadata-support + test + + + org.apache.archiva + maven2-repository + test + org.assertj assertj-core diff --git a/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepository.java b/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepository.java index fbfe37386..d4c79b603 100644 --- a/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepository.java +++ b/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepository.java @@ -40,6 +40,8 @@ import org.apache.jackrabbit.commons.JcrUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.collect.ImmutableMap; + import javax.jcr.NamespaceRegistry; import javax.jcr.Node; import javax.jcr.NodeIterator; @@ -55,6 +57,9 @@ import javax.jcr.nodetype.NodeTypeManager; import javax.jcr.nodetype.NodeTypeTemplate; import javax.jcr.query.Query; import javax.jcr.query.QueryResult; +import javax.jcr.query.Row; +import javax.jcr.query.RowIterator; + import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -66,6 +71,7 @@ import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; /** @@ -711,6 +717,83 @@ public class JcrMetadataRepository return artifacts; } + private List runJcrQuery( String repositoryId, String q, Map bindings ) + throws MetadataRepositoryException + { + List artifacts; + if ( repositoryId != null ) + { + q += " AND ISDESCENDANTNODE(artifact,'/" + getRepositoryContentPath( repositoryId ) + "')"; + } + + log.info( "Running JCR Query: {}", q ); + + try + { + Query query = getJcrSession().getWorkspace().getQueryManager().createQuery( q, Query.JCR_SQL2 ); + ValueFactory valueFactory = getJcrSession().getValueFactory(); + for ( Entry entry : bindings.entrySet() ) + { + query.bindValue( entry.getKey(), valueFactory.createValue( entry.getValue() ) ); + } + long start = Calendar.getInstance().getTimeInMillis(); + QueryResult result = query.execute(); + long end = Calendar.getInstance().getTimeInMillis(); + log.info( "JCR Query ran in {} milliseconds: {}", end - start , q ); + + artifacts = new ArrayList<>(); + RowIterator rows = result.getRows(); + while ( rows.hasNext() ) + { + Row row = rows.nextRow(); + Node node = row.getNode( "artifact" ); + artifacts.add( getArtifactFromNode( repositoryId, node ) ); + } + } + catch ( RepositoryException e ) + { + throw new MetadataRepositoryException( e.getMessage(), e ); + } + return artifacts; + } + + @Override + public List getArtifactsByProjectVersionMetadata( String key, String value, String repositoryId ) + throws MetadataRepositoryException + { + String q = + "SELECT * FROM [" + PROJECT_VERSION_NODE_TYPE + "] AS projectVersion INNER JOIN [" + ARTIFACT_NODE_TYPE + + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) INNER JOIN [" + FACET_NODE_TYPE + + "] AS facet ON ISCHILDNODE(facet, projectVersion) WHERE ([facet].[" + key + "] = $value)"; + + return runJcrQuery( repositoryId, q, ImmutableMap.of( "value", value ) ); + } + + + @Override + public List getArtifactsByMetadata( String key, String value, String repositoryId ) + throws MetadataRepositoryException + { + String q = + "SELECT * FROM [" + ARTIFACT_NODE_TYPE + "] AS artifact INNER JOIN [" + FACET_NODE_TYPE + + "] AS facet ON ISCHILDNODE(facet, artifact) WHERE ([facet].[" + key + "] = $value)"; + + return runJcrQuery( repositoryId, q, ImmutableMap.of( "value", value ) ); + } + + + @Override + public List getArtifactsByProperty( String key, String value, String repositoryId ) + throws MetadataRepositoryException + { + String q = + "SELECT * FROM [" + PROJECT_VERSION_NODE_TYPE + "] AS projectVersion INNER JOIN [" + ARTIFACT_NODE_TYPE + + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) WHERE ([projectVersion].[" + key + + "] = $value)"; + + return runJcrQuery( repositoryId, q, ImmutableMap.of( "value", value ) ); + } + @Override public void removeRepository( String repositoryId ) @@ -1319,6 +1402,33 @@ public class JcrMetadataRepository } } + + @Override + public List searchArtifacts( String text, String repositoryId, boolean exact ) + throws MetadataRepositoryException + { + return searchArtifacts( null, text, repositoryId, exact ); + } + + @Override + public List searchArtifacts( String key, String text, String repositoryId, boolean exact ) + throws MetadataRepositoryException + { + // we can't do exact search in any property (*), we need a key + boolean e = exact && key != null; + String theKey = key == null ? "*" : "[" + key + "]"; + String projectVersionCondition = + e ? "(projectVersion." + theKey + " = $value)" : "contains([projectVersion]." + theKey + ", $value)"; + String facetCondition = e ? "(facet." + theKey + " = $value)" : "contains([facet]." + theKey + ", $value)"; + String q = + "SELECT * FROM [" + PROJECT_VERSION_NODE_TYPE + "] AS projectVersion LEFT OUTER JOIN [" + + ARTIFACT_NODE_TYPE + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) LEFT OUTER JOIN [" + + FACET_NODE_TYPE + "] AS facet ON ISCHILDNODE(facet, projectVersion) WHERE (" + + projectVersionCondition + " OR " + facetCondition + ")"; + + return runJcrQuery( repositoryId, q, ImmutableMap.of( "value", text ) ); + } + private ArtifactMetadata getArtifactFromNode( String repositoryId, Node artifactNode ) throws RepositoryException { @@ -1326,7 +1436,7 @@ public class JcrMetadataRepository ArtifactMetadata artifact = new ArtifactMetadata(); artifact.setId( id ); - artifact.setRepositoryId( repositoryId ); + artifact.setRepositoryId( repositoryId == null ? artifactNode.getAncestor(2).getName() : repositoryId ); Node projectVersionNode = artifactNode.getParent(); Node projectNode = projectVersionNode.getParent();