Using REST Services

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

Security related information

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

Search Service

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,
                               Collections.singletonList( new JacksonJaxbJsonProvider() ) );
// 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:"+port);
// 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 );

To know all the possible options, you can refer to the javadoc of SearchRequest class.

Browse Service

Get a Browse Service Client :

        BrowseService service =
            JAXRSClientFactory.create( getBaseUrl() + "/" + getRestServicesPath() + "/archivaServices/",
                                       BrowseService.class,
                                       Collections.singletonList( new JacksonJaxbJsonProvider() ) );
        // 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:"+port);

        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 );

        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 );

        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 );

        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.jaxrs</groupId>
        <artifactId>jackson-jaxrs-json-provider</artifactId>
        <version>${jacksonVersion}</version>
      </dependency>
      <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-xml-provider</artifactId>
        <version>${jacksonVersion}</version>
      </dependency>
      <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>${jacksonVersion}</version>
      </dependency>
      <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-frontend-jaxrs</artifactId>
        <version>${cxf.version}</version>
      </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.archiva</groupId>
        <artifactId>archiva-rest-api</artifactId>
        <version>${project.version}</version>
      </dependency>

Current versions use in Apache Archiva:

  • ${project.version}: 3.0.0-SNAPSHOT
  • ${cxfVersion}: $cxf.version
  • ${jacksonVersion}: 2.3.0

Security Framework Services:

You can use Redback Rest Services to control user creation/modification and add/remove roles.

See http://archiva.apache.org/redback/integration/rest.html