Starting version 1.4, you can use some REST Services to manage your Apache Archiva instance and Search artifacts. All samples here will use Apache CXF REST client API. By the way you can use some others REST client frameworks. NOTE: a wadl is available in your Archiva instance : http(s)://ip:port/../restServices/application.wadl
Starting with version 2.2.2 we added HTTP verification techniques to avoid cross site request forgery attacks. The updating services check Origin and Referer header and use a token provided by the login service. If you use the webservices with a native client that is no browser or want to allow requests from different origin URLs you have to change the configuration. For further information see the Redback REST documentation
Authentication headers for connect to your Archiva instance :
// guest with an empty password public static String guestAuthzHeader = "Basic " + org.apache.cxf.common.util.Base64Utility.encode( ( "guest" + ":" ).getBytes() ); // with an other login/password //public String authzHeader = // "Basic " + org.apache.cxf.common.util.Base64Utility.encode( ( "login" + ":password" ).getBytes() );
Get a Search Service Client :
SearchService service = JAXRSClientFactory.create( getBaseUrl() + "/" + getRestServicesPath() + "/archivaServices/", SearchService.class, Arrays.asList( new JacksonJaxbJsonProvider( ), new JacksonJaxbXMLProvider( ) ) ); // to add authentification if ( authzHeader != null ) { WebClient.client( service ).header( "Authorization", authzHeader ); } // Set the Referer header to your archiva server url WebClient.client(service).header("Referer","http://localhost:"+getServerPort()); // to configure read timeout WebClient.getConfig( service ).getHttpConduit().getClient().setReceiveTimeout( 100000000 ); // if you want to use json as exchange format xml is supported too WebClient.client( service ).accept( MediaType.APPLICATION_JSON_TYPE ); WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE ); return service;
Quick Search
List<Artifact> artifacts = searchService.quickSearch( "commons-logging" ); // return all artifacts with groupId OR artifactId OR version OR packaging OR className // NOTE : only artifacts with classifier empty are returned
Search Artifacts Version : to search all availables version with a groupId and artifactId and packaging (if empty jar is used)
SearchService searchService = getSearchService( authorizationHeader ); List<Artifact> artifacts = searchService.getArtifactVersions( "commons-logging", "commons-logging", "jar" );
Search Service with a classifier :
SearchRequest searchRequest = new SearchRequest(); searchRequest.setGroupId( "commons-logging" ); searchRequest.setArtifactId( "commons-logging" ); searchRequest.setClassifier( "sources" ); List<Artifact> artifacts = searchService.searchArtifacts( searchRequest );
Search Service with a classifier :
SearchRequest searchRequest = new SearchRequest(); searchRequest.setGroupId( "commons-logging" ); searchRequest.setArtifactId( "commons-logging" ); searchRequest.setClassifier( "sources" ); List<Artifact> artifacts = searchService.searchArtifacts( searchRequest );
Copy Artifact from a repository to an other one :
For some reasons you want to use a test repository before moving your artifacts to a repository used by final users. To achieve this, you can use a service which can copy an artifact from a repository to an other one
// configure the artifact you want to copy // if package ommited default will be jar ArtifactTransferRequest artifactTransferRequest = new ArtifactTransferRequest(); artifactTransferRequest.setGroupId( "org.apache.karaf.features" ); artifactTransferRequest.setArtifactId( "org.apache.karaf.features.core" ); artifactTransferRequest.setVersion( "2.2.2" ); artifactTransferRequest.setRepositoryId( SOURCE_REPO_ID ); artifactTransferRequest.setTargetRepositoryId( TARGET_REPO_ID ); // retrieve the service RepositoriesService repositoriesService = getRepositoriesService( authorizationHeader ); // copy the artifact Boolean res = repositoriesService.copyArtifact( artifactTransferRequest ).isSuccess();
To know all the possible options, you can refer to the javadoc of SearchRequest class.
Get a Browse Service Client :
BrowseService service = JAXRSClientFactory.create( getBaseUrl() + "/" + getRestServicesPath() + "/archivaServices/", BrowseService.class, Arrays.asList( new JacksonJaxbJsonProvider( ), new JacksonJaxbXMLProvider( ) ) ); // to add authentification if ( authzHeader != null ) { WebClient.client( service ).header( "Authorization", authzHeader ); } // Set the Referer header to your archiva server url WebClient.client(service).header("Referer","http://localhost:"+getServerPort()); WebClient.getConfig( service ).getHttpConduit().getClient().setReceiveTimeout( 100000000 ); if ( useXml ) { WebClient.client( service ).accept( MediaType.APPLICATION_XML_TYPE ); WebClient.client( service ).type( MediaType.APPLICATION_XML_TYPE ); } else { WebClient.client( service ).accept( MediaType.APPLICATION_JSON_TYPE ); WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE ); } return service;
Get artifacts based on project version metadata, generic metadata added previously in Archiva :
BrowseService browseService = getBrowseService( authorizationHeader, true ); browseService.addMetadata( "commons-cli", "commons-cli", "1.0", "wine", "bordeaux", TEST_REPO_ID ); tryAssert( ( ) -> { List<Artifact> artifactDownloadInfos = browseService.getArtifactsByProjectVersionMetadata( "wine", "bordeaux", TEST_REPO_ID ); assertThat( artifactDownloadInfos ).isNotNull( ).isNotEmpty( ).hasSize( 3 );
Get artifacts based on the artifact properties :
BrowseService browseService = getBrowseService( authorizationHeader, true ); List<Artifact> artifactDownloadInfos = browseService.getArtifactsByMetadata( "type", "pom", TEST_REPO_ID ); assertThat( artifactDownloadInfos ).isNotNull().isNotEmpty().hasSize( 11 );
Get artifacts based on the project properties from POM :
BrowseService browseService = getBrowseService( authorizationHeader, true ); tryAssert( ( ) -> { List<Artifact> artifactDownloadInfos = browseService.getArtifactsByProperty( "org.name", "The Apache Software Foundation", TEST_REPO_ID ); assertThat( artifactDownloadInfos ).isNotNull( ).isNotEmpty( ).hasSize( 7 );
Searching by properties and metadata :
BrowseService browseService = getBrowseService( authorizationHeader, true ); List<Artifact> artifactDownloadInfos = browseService.searchArtifacts( "org.name", "The Apache Software Foundation", TEST_REPO_ID, true ); assertThat( artifactDownloadInfos ).isNotNull().isNotEmpty().hasSize( 7 );
BrowseService browseService = getBrowseService( authorizationHeader, true ); tryAssert( ( ) -> { List<Artifact> artifactDownloadInfos = browseService.searchArtifacts( "The Apache Software Foundation", TEST_REPO_ID, true ); assertThat( artifactDownloadInfos ).isNotNull( ).isNotEmpty( ).hasSize( 7 ); } );
Get Search
List<Artifact> artifacts = searchService.quickSearch( "commons-logging" ); // return all artifacts with groupId OR artifactId OR version OR packaging OR className // NOTE : only artifacts with classifier empty are returned
Dependencies to add in order to use those REST Services
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.jaxrs</groupId> <artifactId>jackson-jaxrs-json-provider</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.jaxrs</groupId> <artifactId>jackson-jaxrs-xml-provider</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.jaxrs</groupId> <artifactId>jackson-jaxrs-base</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxrs</artifactId> <version>${cxf.version}</version> <exclusions> <exclusion> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-client</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-extension-providers</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-features-logging</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-service-description-openapi-v3</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-core</artifactId> <scope>compile</scope> <version>${io.swagger.version}</version> <exclusions> <exclusion> <groupId>javax.ws.rs</groupId> <artifactId>jsr311-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-jaxrs2</artifactId> <version>${io.swagger.version}</version> <exclusions> <exclusion> <groupId>javax.ws.rs</groupId> <artifactId>jsr311-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-annotations</artifactId> <version>${io.swagger.version}</version> <exclusions> <exclusion> <groupId>javax.ws.rs</groupId> <artifactId>jsr311-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.archiva</groupId> <artifactId>archiva-rest-api</artifactId> <version>${project.version}</version> </dependency>
Current versions use in Apache Archiva: