 ------
 Guide to use XML-RPC with Continuum
 ------
 Emmanuel Venisse
 ------
 Nov 12 2007
 ------

~~ 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.

Guide to use XML-RPC with Continuum

~~%{toc|section=0}

* {Introduction}

    In this section, you'll learn how to connect to a Continuum instance and how to do some action on projects.

* {Requirements}

    To connect to a Continuum instance, you must use the {{{http://repo1.maven.org/maven2/org/apache/continuum/continuum-xmlrpc-client/}continuum-xmlrpc-client}} jar.

    This library have some others jars as dependencies, so the best way to start the development of a Continuum xmlrpc client is to create a maven2 project with the following dependencies:

+--------------------------+
    <dependency>
      <groupId>org.apache.continuum</groupId>
      <artifactId>continuum-xmlrpc-client</artifactId>
      <version>YOUR_CONTINUUM_VERSION</version>
    </dependency>
+--------------------------+

* {Connection to Continuum}

    To connect to your Continuum with the client API, you must use the
    {{{http://continuum.apache.org/ref/latest/apidocs/org/apache/maven/continuum/xmlrpc/client/ContinuumXmlRpcClient.html}ContinuumXmlRpcClient}} class.

    The constructor use 3 parameters:
    
    * url, the url of the xmlrpc listener that is http://host:port/continuum/xmlrpc

    * user, a Continuum user

    * password, the user's password

+--------------------------+
URL url = new URL( "http://localhost:8080/continuum/xmlrpc" );
ContinuumXmlRpcClient client = new ContinuumXmlRpcClient( url, username, password );
+--------------------------+

* {Getting project groups list}

    You have two ways to get the project groups list. The first is to get only a summary of groups and the second returns groups with details.
    If you don't need all informations, we recommend to use the first way, so you'll save time to get datas and memory on the server.
    
+--------------------------+
List<ProjectGroupSummary> pgs = client.getAllProjectGroups();
List<ProjectGroup> pgs = client.getAllProjectGroupsWithProjects();
+--------------------------+

* {Getting projects in a group}

+--------------------------+
List<ProjectSummary> ps = client.getProjects( projectGroupId );
+--------------------------+

    If you already have a ProjectGroup or ProjectGroupSummary object, you can access to the project group id with this:

+--------------------------+
int projectGroupId = pg.getId();
+--------------------------+

* {Building all projects in a group}

    * With the default build definition

+--------------------------+
client.buildGroup( projectGroupId );
+--------------------------+

    * With a build definition

+--------------------------+
client.buildGroup( projectGroupId, buildDefinitionId );
+--------------------------+

* {Building a project}

    * With the default build definition

+--------------------------+
client.buildProject( project.getId() );
+--------------------------+

    * With a build definition

+--------------------------+
client.buildProject( project.getId(), buildDefinitionId );
+--------------------------+

    <<Note:>> When you start a build, the project is put in the Continuum queue and will be built when all projects added previously in the queue will be built.

* {Triggering a build}

    In some case, users want to use the push build technique with a hook in their SCM, so when a developer will commit some files, a build will be triggered.
    To do this, you can write a simple xmlrpc client that will use a project id as parameter and you'll use the <<<buildProject(...)>>> method described above.
    
    This method will start a forced build.

* {Removing a project}

    A project can be removed by supplying the project id.

+--------------------------+
List<ProjectSummary> projects = client.getProjects( projectGroupId );
...
  client.removeProject( ps.getId() );
+--------------------------+

* {Removing build results}

    Currently, to remove a build result, you need the entire build result (rather than just the summary).

+--------------------------+
List<BuildResultSummary> results = client.getBuildResultsForProject( ps.getId() );
...
  BuildResult br = client.getBuildResult( ps.getId(), brs.getId() );
  client.removeBuildResult( br );
+--------------------------+

* {Editing build queue}

    You can edit all projects which are in the build queue or check if one project is currently in the build queue.

+--------------------------+
List<BuildProjectTask> prjsInBuildQueue = client.getProjectsInBuildQueue();
client.isProjectInBuildingQueue( int projectId );
+--------------------------+

* {Backup}

    With the Continuum xmlrpc client, you can backup a full Continuum instance (without users database, for the moment).
