Storages

Storages are rooted in the /v1/storages/{org_label}/{project_label} collection and are used to describe where files are physically stored.

Each storage…

  • belongs to a project identifier by the label {project_label}
  • inside an organization identifier by the label {org_label}
  • is validated against the storage schema.

Access to resources in the system depends on the access control list set for them. Depending on the access control list, a caller may need to prove its identity by means of an access token passed to the Authorization header (Authorization: Bearer {token}). Please visit Authentication to learn how to retrieve an access token.

Authorization notes

To read or modify storages, the caller must have respectively storages/read or storages/write permissions on the current path of the project or its ancestors.

Storage types

There are several types (or classes) of storages, that represent different kinds of backends.

Local disk storage

This is the most basic storage type. It is backed by the local file-system (i.e. where the Nexus deployment is running) and rooted in an arbitrary path.

Upon project creation, a default disk storage is initialized automatically, so that users can start uploading resource attachments right away. This resource has the @id nxv:diskStorageDefault.

Its behavior is similar to earlier versions of the Nexus API: files are stored and managed by the system in an opaque, internal way.

While typically not necessary, you can manage and create additional disk storages, provided you are aware of the local file-system structure and that Nexus has read and write access to the target folder.

Remote disk storage

This storage type relies on a remote HTTP service that exposes basic file operations on an underlying POSIX file-system. This is particularly handy if your organization is running some kind of distributed network storage (such as Ceph, Gluster, GPFS, Lustre, …) that you don’t want to mount directly on the system where Nexus runs.

While there’s no formal specification for this service, you can check out or deploy our own implementation: Nexus remote storage service.

Amazon S3 compatible storage

This storage type allows the use of an internal or external blob-store that is compatible with the Amazon S3 API.

Changing the default storage

The internal resource describing every storage has a boolean field called default. The selection mechanism when no storage id is provided picks the last created storage with default set to true.

Resource format

These tables summarize mandatory and optional fields for each storage type:

@type @id default volume readPermission writePermission
DiskStorage optional mandatory mandatory optional optional
@type @id default folder endpoint credentials readPermission writePermission
RemoteDiskStorage optional mandatory mandatory optional optional optional optional
@type @id default bucket endpoint accessKey secretKey readPermission writePermission
S3Storage optional mandatory mandatory optional optional optional optional optional
Note

The endpoint field is optional for the S3 storage type, as our internal implementation uses the official S3 client and defaults to s3.amazonaws.com. Relying on this behavior is discouraged.

Create a storage using POST

POST /v1/storages/{org_label}/{project_label}
  {...}

Json payload:

  • If an @id value is found in the payload, it will be used.
  • If an @id value is not found in the payload, one will be generated as follows: base:{UUID}. The base is the prefix defined on the storage’s project ({project_label}).

Example

Request
curl -XPOST -H "Content-Type: application/json" "https://nexus.example.com/v1/storages/myorg/myproj" -d \
'{
  "@id": "nxv:mys3storage",
  "@type": "S3Storage",
  "default": false,
  "bucket": "mybucket",
  "endpoint": "https://s3.us-west-1.amazonaws.com",
  "accessKey": "AKIAIOSFODNN7EXAMPLE",
  "secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}'
Full source at GitHub
Payload
{
    "@id": "nxv:mys3storage",
    "@type": "S3Storage",
    "default": false,
    "bucket": "mybucket",
    "endpoint": "https://s3.us-west-1.amazonaws.com",
    "accessKey": "AKIAIOSFODNN7EXAMPLE",
    "secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}
Full source at GitHub
Response
{
    "@context": "https://bluebrain.github.io/nexus/contexts/resource.json",
    "@id": "nxv:mys3storage",
    "@type": [
        "S3Storage",
        "Storage"
    ],
    "_self": "https://nexus.example.com/v1/storages/myorg/myproj/nxv:mys3storage",
    "_constrainedBy": "https://bluebrain.github.io/nexus/schemas/storage.json",
    "_project": "https://nexus.example.com/v1/projects/myorg/myproj",
    "_rev": 1,
    "_deprecated": false,
    "_createdAt": "2019-05-10T16:26:54.423Z",
    "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john",
    "_updatedAt": "2019-05-10T16:26:54.423Z",
    "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john"
}
Full source at GitHub

Create a storage using PUT

This alternative endpoint to create a storage is useful in case the json payload does not contain an @id but you want to specify one. The @id will be specified in the last segment of the endpoint URI.

PUT /v1/storages/{org_label}/{project_label}/{storage_id}
  {...}

Note that if the payload contains an @id different from the {storage_id}, the request will fail.

Example

Request
curl -XPUT -H "Content-Type: application/json" "https://nexus.example.com/v1/storages/myorg/myproj/nxv:mys3storage" -d \
'{
  "@type": "S3Storage",
  "default": false,
  "bucket": "mybucket",
  "endpoint": "https://s3.us-west-1.amazonaws.com",
  "accessKey": "AKIAIOSFODNN7EXAMPLE",
  "secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}'
Full source at GitHub
Payload
{
    "@type": "S3Storage",
    "default": false,
    "bucket": "mybucket",
    "endpoint": "https://s3.us-west-1.amazonaws.com",
    "accessKey": "AKIAIOSFODNN7EXAMPLE",
    "secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}
Full source at GitHub
Response
{
    "@context": "https://bluebrain.github.io/nexus/contexts/resource.json",
    "@id": "nxv:mys3storage",
    "@type": [
        "S3Storage",
        "Storage"
    ],
    "_self": "https://nexus.example.com/v1/storages/myorg/myproj/nxv:mys3storage",
    "_constrainedBy": "https://bluebrain.github.io/nexus/schemas/storage.json",
    "_project": "https://nexus.example.com/v1/projects/myorg/myproj",
    "_rev": 1,
    "_deprecated": false,
    "_createdAt": "2019-05-10T16:26:54.423Z",
    "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john",
    "_updatedAt": "2019-05-10T16:26:54.423Z",
    "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john"
}
Full source at GitHub

Update a storage

This operation overrides the payload.

In order to ensure a client does not perform any changes to a storage without having had seen the previous revision of the storage, the last revision needs to be passed as a query parameter.

PUT /v1/storages/{org_label}/{project_label}/{storage_id}?rev={previous_rev}
  {...}

… where {previous_rev} is the last known revision number for the storage.

Example

Request
curl -XPUT -H "Content-Type: application/json" "https://nexus.example.com/v1/storages/myorg/myproj/nxv:mys3storage" -d \
'{
  "@type": "S3Storage",
  "default": true,
  "bucket": "mybucket",
  "endpoint": "https://s3.us-west-1.amazonaws.com",
  "accessKey": "AKIAIOSFODNN7EXAMPLE",
  "secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}'
Full source at GitHub
Payload
{
    "@type": "S3Storage",
    "default": true,
    "bucket": "mybucket",
    "endpoint": "https://s3.us-west-1.amazonaws.com",
    "accessKey": "AKIAIOSFODNN7EXAMPLE",
    "secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}
Full source at GitHub
Response
{
    "@context": "https://bluebrain.github.io/nexus/contexts/resource.json",
    "@id": "nxv:mys3storage",
    "@type": [
        "S3Storage",
        "Storage"
    ],
    "_self": "https://nexus.example.com/v1/storages/myorg/myproj/nxv:mys3storage",
    "_constrainedBy": "https://bluebrain.github.io/nexus/schemas/storage.json",
    "_project": "https://nexus.example.com/v1/projects/myorg/myproj",
    "_rev": 2,
    "_deprecated": false,
    "_createdAt": "2019-05-10T16:26:54.423Z",
    "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john",
    "_updatedAt": "2019-05-10T16:26:54.423Z",
    "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john"
}
Full source at GitHub

Tag a storage

Links a storage revision to a specific name.

Tagging a storage is considered to be an update as well.

POST /v1/storages/{org_label}/{project_label}/{storage_id}/tags?rev={previous_rev}
  {
    "tag": "{name}",
    "rev": {rev}
  }

… where

  • {previous_rev}: Number - the last known revision for the storage.
  • {name}: String - label given to the storage at specific revision.
  • {rev}: Number - the revision to link the provided {name}.

Example

Request
curl -XPOST -H "Content-Type: application/json" "https://nexus.example.com/v1/storages/myorg/myproj/nxv:mys3storage/tags?rev=2" -d \
'{
  "tag": "mytag",
  "rev": 1
}'
Full source at GitHub
Payload
{
  "tag": "mytag",
  "rev": 1
}
Full source at GitHub
Response
{
    "@context": "https://bluebrain.github.io/nexus/contexts/resource.json",
    "@id": "nxv:mys3storage",
    "@type": [
        "S3Storage",
        "Storage"
    ],
    "_self": "https://nexus.example.com/v1/storages/myorg/myproj/nxv:mys3storage",
    "_constrainedBy": "https://bluebrain.github.io/nexus/schemas/storage.json",
    "_project": "https://nexus.example.com/v1/projects/myorg/myproj",
    "_rev": 3,
    "_deprecated": false,
    "_createdAt": "2019-05-10T16:26:54.423Z",
    "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john",
    "_updatedAt": "2019-05-10T16:26:54.423Z",
    "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john"
}
Full source at GitHub

Deprecate a storage

Locks the storage, so no further operations can be performed. It will also not be taken into account by the default storage selection mechanism.

Deprecating a storage is considered to be an update as well.

DELETE /v1/storages/{org_label}/{project_label}/{storage_id}?rev={previous_rev}

… where {previous_rev} is the last known revision number for the storage.

Example

Request
curl -XDELETE -H "Content-Type: application/json" "https://nexus.example.com/v1/storages/myorg/myproj/nxv:mys3storage"
Full source at GitHub
Response
{
    "@context": "https://bluebrain.github.io/nexus/contexts/resource.json",
    "@id": "nxv:mys3storage",
    "@type": [
        "S3Storage",
        "Storage"
    ],
    "_self": "https://nexus.example.com/v1/storages/myorg/myproj/nxv:mys3storage",
    "_constrainedBy": "https://bluebrain.github.io/nexus/schemas/storage.json",
    "_project": "https://nexus.example.com/v1/projects/myorg/myproj",
    "_rev": 4,
    "_deprecated": true,
    "_createdAt": "2019-05-13T14:31:24.661Z",
    "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john",
    "_updatedAt": "2019-05-13T14:32:03.287Z",
    "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john"
}
Full source at GitHub

Fetch a storage (current version)

GET /v1/storages/{org_label}/{project_label}/{storage_id}

Example

Request
curl "https://nexus.example.com/v1/storages/myorg/myproj/nxv:mys3storage"
Full source at GitHub
Response
{
    "@context": [
        "https://bluebrain.github.io/nexus/contexts/storage.json",
        "https://bluebrain.github.io/nexus/contexts/resource.json"
    ],
    "@id": "nxv:mys3storage",
    "@type": [
        "S3Storage",
        "Storage"
    ],
    "bucket": "mybucket",
    "default": true,
    "endpoint": "https://s3.us-west-1.amazonaws.com",
    "readPermission": "resources/read",
    "writePermission": "files/write",
    "_algorithm": "SHA-256",
    "_self": "https://nexus.example.com/v1/storages/myorg/myproj/nxv:mys3storage",
    "_constrainedBy": "https://bluebrain.github.io/nexus/schemas/storage.json",
    "_project": "https://nexus.example.com/v1/projects/myorg/myproj",
    "_rev": 3,
    "_deprecated": false,
    "_createdAt": "2019-05-13T14:38:51.190Z",
    "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john",
    "_updatedAt": "2019-05-13T14:38:51.190Z",
    "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john"
}
Full source at GitHub

Fetch a storage (specific version)

GET /v1/storages/{org_label}/{project_label}/{storage_id}?rev={rev}

… where {rev} is the revision number of the storage to be retrieved.

Example

Request
curl "https://nexus.example.com/v1/storages/myorg/myproj/nxv:mys3storage?rev=1"
Full source at GitHub
Response
{
    "@context": [
        "https://bluebrain.github.io/nexus/contexts/storage.json",
        "https://bluebrain.github.io/nexus/contexts/resource.json"
    ],
    "@id": "nxv:mys3storage",
    "@type": [
        "S3Storage",
        "Storage"
    ],
    "bucket": "mybucket",
    "default": false,
    "endpoint": "https://s3.us-west-1.amazonaws.com",
    "readPermission": "resources/read",
    "writePermission": "files/write",
    "_algorithm": "SHA-256",
    "_self": "https://nexus.example.com/v1/storages/myorg/myproj/nxv:mys3storage",
    "_constrainedBy": "https://bluebrain.github.io/nexus/schemas/storage.json",
    "_project": "https://nexus.example.com/v1/projects/myorg/myproj",
    "_rev": 1,
    "_deprecated": false,
    "_createdAt": "2019-05-13T14:38:51.190Z",
    "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john",
    "_updatedAt": "2019-05-13T14:38:51.190Z",
    "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john"
}
Full source at GitHub

Fetch a storage (specific tag)

GET /v1/storages/{org_label}/{project_label}/{storage_id}?tag={tag}

… where {tag} is the tag of the storage to be retrieved.

Example

Request
curl "https://nexus.example.com/v1/storages/myorg/myproj/nxv:mys3storage?tag=mytag"
Full source at GitHub
Response
{
    "@context": [
        "https://bluebrain.github.io/nexus/contexts/storage.json",
        "https://bluebrain.github.io/nexus/contexts/resource.json"
    ],
    "@id": "nxv:mys3storage",
    "@type": [
        "S3Storage",
        "Storage"
    ],
    "bucket": "mybucket",
    "default": false,
    "endpoint": "https://s3.us-west-1.amazonaws.com",
    "readPermission": "resources/read",
    "writePermission": "files/write",
    "_algorithm": "SHA-256",
    "_self": "https://nexus.example.com/v1/storages/myorg/myproj/nxv:mys3storage",
    "_constrainedBy": "https://bluebrain.github.io/nexus/schemas/storage.json",
    "_project": "https://nexus.example.com/v1/projects/myorg/myproj",
    "_rev": 1,
    "_deprecated": false,
    "_createdAt": "2019-05-13T14:38:51.190Z",
    "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john",
    "_updatedAt": "2019-05-13T14:38:51.190Z",
    "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john"
}
Full source at GitHub

List storages

GET /v1/storages/{org_label}/{project_label}?from={from}&size={size}&deprecated={deprecated}&rev={rev}&type={type}&createdBy={createdBy}&updatedBy={updatedBy}

where…

  • {from}: Number - is the parameter that describes the offset for the current query; defaults to 0
  • {size}: Number - is the parameter that limits the number of results; defaults to 20
  • {deprecated}: Boolean - can be used to filter the resulting storages based on their deprecation status
  • {rev}: Number - can be used to filter the resulting storages based on their revision value
  • {type}: Iri - can be used to filter the resulting storages based on their @type value. This parameter can appear multiple times, filtering further the @type value.
  • {createdBy}: Iri - can be used to filter the resulting storages based on their creator
  • {updatedBy}: Iri - can be used to filter the resulting storages based on the person which performed the last update

Example

Request
curl "https://nexus.example.com/v1/storages/myorg/myproj"
Full source at GitHub
Response
{
    "@context": [
        "https://bluebrain.github.io/nexus/contexts/search.json",
        "https://bluebrain.github.io/nexus/contexts/resource.json"
    ],
    "_total": 3,
    "_results": [
        {
            "@id": "https://bluebrain.github.io/nexus/vocabulary/diskStorageDefault",
            "@type": [
                "https://bluebrain.github.io/nexus/vocabulary/Storage",
                "https://bluebrain.github.io/nexus/vocabulary/DiskStorage"
            ],
            "_self": "https://nexus.example.com/v1/storages/myorg/myproj/https%3A%2F%2Fbluebrain.github.io%2Fnexus%2Fvocabulary%2FdiskStorageDefault",
            "_constrainedBy": "https://bluebrain.github.io/nexus/schemas/storage.json",
            "_project": "https://nexus.example.com/v1/projects/myorg/myproj",
            "_rev": 1,
            "_deprecated": false,
            "_createdAt": "2019-05-13T14:26:47.817Z",
            "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john",
            "_updatedAt": "2019-05-13T14:26:47.817Z",
            "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john"
        },
        {
            "@id": "https://bluebrain.github.io/nexus/vocabulary/myoldstorage",
            "@type": [
                "https://bluebrain.github.io/nexus/vocabulary/S3Storage",
                "https://bluebrain.github.io/nexus/vocabulary/Storage"
            ],
            "_self": "https://nexus.example.com/v1/storages/myorg/myproj/https%3A%2F%2Fbluebrain.github.io%2Fnexus%2Fvocabulary%myoldstorage",
            "_constrainedBy": "https://bluebrain.github.io/nexus/schemas/storage.json",
            "_project": "https://nexus.example.com/v1/projects/myorg/myproj",
            "_rev": 2,
            "_deprecated": true,
            "_createdAt": "2019-05-13T14:31:24.661Z",
            "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john",
            "_updatedAt": "2019-05-13T14:32:03.287Z",
            "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john"
        },
        {
            "@id": "https://bluebrain.github.io/nexus/vocabulary/mys3storage",
            "@type": [
                "https://bluebrain.github.io/nexus/vocabulary/S3Storage",
                "https://bluebrain.github.io/nexus/vocabulary/Storage"
            ],
            "_self": "https://nexus.example.com/v1/storages/myorg/myproj/https%3A%2F%2Fbluebrain.github.io%2Fnexus%2Fvocabulary%2Fmys3storage",
            "_constrainedBy": "https://bluebrain.github.io/nexus/schemas/storage.json",
            "_project": "https://nexus.example.com/v1/projects/myorg/myproj",
            "_rev": 3,
            "_deprecated": false,
            "_createdAt": "2019-05-13T14:38:51.190Z",
            "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john",
            "_updatedAt": "2019-05-13T16:07:27.859Z",
            "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john"
        }
    ],
    "_next": "https://nexus.example.com/v1/storages/myorg/myproj/?after=%5B1557758331190,%22https://bluebrain.github.io/nexus/vocabulary/mys3storage%22%5D"
}
Full source at GitHub