This project has retired. For details please refer to its Attic page.
Archiva – REST Services Fork me on GitHub

Expose Rest Services

The Apache CXF is used to expose some classes/methods as REST Services.

Services use the standard interface/implementation pattern:

  • interfaces and beans are located in archiva-rest-api maven module
  • implementation are located in archiva-rest-services maven module

Steps to expose your class as a REST Service.

Here all the steps to expose a new class as a REST service.

Interface and data beans

All interfaces and data beans are added in the module archiva-rest-api:

  • interface in the package: org.apache.archiva.rest.api.services .
  • data beans in the package: org.apache.archiva.rest.api.model .
Beans

As we want to be able to expose result as json or xml type, all beans use javax.xml.bind.annotation root element :

@XmlRootElement( name = "artifact" )
public class Artifact
    implements Serializable

All services will be able to return json or xml
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
JAXRS annotations

As we use interfaces/implementations pattern jaxrs annotations are only in interfaces level.

@Path( "/managedRepositoriesService/" )
public interface ManagedRepositoriesService
{
    // simple GET method no parameter
    @Path( "getManagedRepositories" )
    @GET
    @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
    List<ManagedRepository> getManagedRepositories()
        throws ArchivaRestServiceException;

    // GET method with a path parameter
    @Path( "getManagedRepository/{repositoryId}" )
    @GET
    @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
    @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
    ManagedRepository getManagedRepository( @PathParam( "repositoryId" ) String repositoryId )
        throws ArchivaRestServiceException;

    // POST  method to pass a data bean
    @Path( "addManagedRepository" )
    @POST
    @Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
    @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
    @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
    ManagedRepository addManagedRepository( ManagedRepository managedRepository )
        throws ArchivaRestServiceException;

CXF/Spring configuration

REST services implementations are marked with the Spring annotation @Service

package org.apache.archiva.rest.services;
......
@Service( "managedRepositoriesService#rest" )
public class DefaultManagedRepositoriesService
    extends AbstractRestService
    implements ManagedRepositoriesService

Spring beans are declared as REST/CXF services in the Spring configuration

  <jaxrs:server id="archivaServices" address="/archivaServices">
    .....
    <jaxrs:serviceBeans>
      <ref bean="managedRepositoriesService#rest"/>
    </jaxrs:serviceBeans>
    .....
  </jaxrs:server>

  Note as we use @Service annotation package scanning must declared in spring configuration

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd ....">
...
  <context:annotation-config/>
  <context:component-scan
      base-package="org.apache.archiva.rest.services"/>

...
</beans>

CXF servlet is declared as:

  <servlet>
    <servlet-name>CXFServlet</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/restServices/*</url-pattern>
  </servlet-mapping>

So as it, REST services are availble in the following url restServices/archivaServices/.

Redback security annotation

Some REST methods need some karma, so to prevent anonymous access methods can be marked as it:

    @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
    ManagedRepository addManagedRepository( ManagedRepository managedRepository )
        throws ArchivaRestServiceException;

This method will need the current user to have the operation manage-configuration level.

For more details, have a look at Redback REST.