Documentation Nexus Repository Manager 3.0

Chapter 14. REST and Integration API

Available in Nexus Repository OSS and Nexus Repository Pro

14.1. Introduction

Automation via scripts is a common scenario. The Nexus Repository Manager provides APIs that simplify provisioning and other tasks in the repository manager. These APIs can be invoked from scripts that are published to the repository manager and executed there.

14.2. Writing Scripts

The scripting language used on the repository manager is Groovy. Any editor can be used to author the scripts.

The available APIs are contained in a number of JAR files. All these files, including JavaDoc and Sources archives, are available from the Central Repository. They can be manually downloaded and extracted. E.g. the different versions and the specific JAR files for org.sonatype.nexus:nexus-core are available in versioned directories at http://repo1.maven.org/maven2/org/sonatype/nexus/nexus-core/.

This manual process can be simplified and improved by the usage of a Maven project declaring the relevant components as dependencies. An example project with this setup called nexus-script-example and a few scripts are available in the documentation examples project.

Maven Project pom.xml Declaring the API Dependencies for Scripting. 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example.automation</groupId>
  <artifactId>nexus-script-demo</artifactId>
  <version>1.0-SNAPSHOT</version>

  <properties>
    <nx-version>3.0.2-02</nx-version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.sonatype.nexus</groupId>
      <artifactId>nexus-core</artifactId>
      <version>${nx-version}</version>
    </dependency>
    <dependency>
      <groupId>org.sonatype.nexus</groupId>
      <artifactId>nexus-script</artifactId>
      <version>${nx-version}</version>
    </dependency>
    <dependency>
      <groupId>org.sonatype.nexus</groupId>
      <artifactId>nexus-security</artifactId>
      <version>${nx-version}</version>
    </dependency>
    <dependency>
      <groupId>org.sonatype.nexus.plugins</groupId>
      <artifactId>nexus-script-plugin</artifactId>
      <version>${nx-version}</version>
    </dependency>
  </dependencies>
</project>

Development environments such as IntelliJ IDEA or Eclipse IDE can download the relevant JavaDoc and Sources JAR files to ease your development. Typically you would create your scripts in src/main/groovy or src/main/scripts.

The scripting API exposes specific tooling for IntelliJ IDEA that allows you to get access to code completion and similar convenience features, while writing your scripts in this Maven project. Currently the API exposes four main providers with numerous convenient methods:

  • core
  • repository
  • blobStore
  • security

The API is deliberately designed to be simple to use. It encapsulates complex configuration in single method invocations. Many of the included methods use default values that can be omitted. For example, the method to create a hosted repository using the Maven format in the simplest usage simply requires a name.

repository.createMavenHosted("private")

This method simply uses the default values for the rest of the parameters and is therefore equivalent to

repository.createMavenHosted("private", BlobStoreManager.DEFAULT_BLOBSTORE_NAME, VersionPolicy.RELEASE,
        WritePolicy.ALLOW_ONCE, LayoutPolicy.STRICT)

You can inspect the default values in the API documentation available by inspecting the declaration of the specific methods in your IDE or by viewing the JavaDoc.

In terms of overall complexity of the scripts created, it is best to break large tasks up into multiple scripts and therefore invocations.

14.3. Managing and Running Scripts

Once you have completed the creation of your script, you need to publish it to the repository manager for execution. This is done by REST API invocations against the endpoint:

http://localhost:8081/service/siesta/rest/v1/script

This endpoint accepts JSON-formatted payloads with your script as the content.

Example JSON formatted file maven.json with a simple repository creation script. 

{
  "name": "maven",
  "type": "groovy",
  "content": "repository.createMavenHosted('private')"
}

The JSON file maven.json located in the current directory can be published to the repository manager with an HTTP POST like

curl -v -X POST -u admin:admin123 --header "Content-Type: application/json" 'http://localhost:8081/service/siesta/rest/v1/script' -d @maven.json

A list of scripts stored on the repository manager can be accessed with

curl -v -X GET -u admin:admin123 'http://localhost:8081/service/siesta/rest/v1/script'

The same call with a script name appended returns the actual script content.

A script can be executed by sending a POST to the run method of the specific script

curl -v -X POST -u admin:admin123 --header "Content-Type: text/plain" 'http://localhost:8081/service/siesta/rest/v1/script/maven/run'

A successful execution should result in a HTTP/1.1 200 OK result.

Scripts can be removed with a HTTP DELETE operation to the specific script:

curl -v -X DELETE -u admin:admin123 'http://localhost:8081/service/siesta/rest/v1/script/maven'

Scripts can receive run-time parameters via the REST API

curl -v -X POST -u admin:admin123 --header "Content-Type: text/plain" 'http://localhost:8081/service/siesta/rest/v1/script/updateAnonymousAccess/run' -d 'false'

and receive them as arguments that have to be parsed by the script as desired

security.setAnonymousAccess(Boolean.valueOf(args))

Interaction with the REST API for scripts can be done with any scripting language capable of HTTP calls as mentioned above. In the following section you can find some further detailed examples.

14.4. Examples

The API for scripts is capable of a number of different tasks. This section provides examples for script writing, publishing and executing them.

The simple-shell-example project in the scripting section of the documentation examples project includes a number of JSON file with simple scripts:

maven.json
simplest script to create a hosted Maven repository
npm.json
simple script to create a hosted and proxy repository as well as a repository group for npm usage
bower.json
simple script to create a hosted and proxy repository as well as a repository group for bower usage
anonymous:json
parameterized script to enable or disable anonymous access

Simple shell scripts are added to contain the curl invocations to manage scripts via the REST API:

create.sh
Upload a specified JSON file
delete.sh
Delete a script specified by its name
list:sh
List all deployed scripts
run.sh
Run a script specified by its name
setAnonymous.sh
Run the anonymous script on the server with the parameter true or false
update.sh
Update an existing script by specifying the name and the JSON file to use for the update

And example sequence of creating and running a script is:

./create.sh maven.json
./run.sh maven

Subsequently you could list all scripts and delete the maven script with

./list.sh
./delete.sh maven

Since scripts are typically longer than a single line and creating them in a separate file in the IDE is recommended, using a helper script that formats a .groovy file into a JSON file and submits it to the repository manager can be a convenient approach.

The complex-script project in the scripting section of the documentation examples project includes an example implementation using Groovy invoked from a shell script. All scripts in this folder can be published and executed via the provision.sh file. This results in the download of all required dependencies and the upload and execution of the referenced script. Alternative you can provision the scripts individually:

groovy addUpdateScript.groovy -u "admin" -p "admin123" -n "raw" -f "rawRepositories.groovy" -h "http://localhost:8081"
curl -v -X POST -u admin:admin123 --header "Content-Type: text/plain" "http://localhost:8081/service/siesta/rest/v1/script/raw/run"

The following scripts are available:

npmAndBowerRepositories.groovy
configures a set of proxy and hosted repositories as well as repository groups for NPM and Bower repositories suitable for server-side and client JavaScript-based development
rawRepositories.groovy
creates a new blob store and uses it for a hosted raw repository
security.groovy
disables anonymous access, creates a new administrator account, creates a new role with a simple expansion to anonymous user role and a user, creates a new role with publishing access to all repositories and a user
core.groovy
configures the base URL capability and a proxy server

Logging from your scripts into the repository manager logs is automatically available and performed with the usual calls

log.info('User jane.doe created')

The result of the last script line is by default returned as a string. This can be a message as simple as Success! or more complex structured data. For instance, you can easily return JSON using built-in Groovy classes like:

return groovy.json.JsonOutput.toJson([result: 'Success!'])

which looks like

{
    "result": "Success!"
}

Passing parameters to the script can use JSON encoded arguments like

{
  "id": "foo",
  "name": "bar",
  "description": "baz",
  "privilegeIds": ["nx-all"],
  "roleIds": ["nx-admin"]
}

which in turn can be parsed using the JsonSlurper class in the script:

import groovy.json.JsonSlurper

//expects json string with appropriate content to be passed in
def role = new JsonSlurper().parseText(args)

security.addRole(role.id, role.name, role.description, role.privilegeIds, role.roleIds)

You can read more about how to work with XML and JSON with Groovy on http://groovy-lang.org/processing-xml.html and http://groovy-lang.org/json.html.