Storage
Brightspot's StorageItem API provides a unified interface for uploading, retrieving, and managing files across multiple storage back ends. Whether you're storing files on the local filesystem, Amazon S3, Azure Blob Storage, or Google Cloud Storage, the API remains the same.
Key capabilities
- Unified API—A single
StorageIteminterface for all storage operations regardless of the back end. - Multiple back ends—Built-in support for local filesystem, AWS S3, Azure Blob Storage, and Google Cloud Storage.
- Lifecycle hooks—Extensible before/after hooks for save and delete operations.
- CDN integration—Automatic file synchronization with content delivery networks, including multi-CDN hashing.
- Custom path generation—Pluggable path generators for controlling how uploaded files are named and organized.
Getting started
Installation
The core module provides the StorageItem interface and the local filesystem back end:
- Maven
- Gradle
- Gradle (Kotlin DSL)
<dependency>
<groupId>com.brightspot.storage</groupId>
<artifactId>storage</artifactId>
<version>__HIDDEN__</version>
</dependency>
implementation 'com.brightspot.storage:storage:__HIDDEN__'
implementation("com.brightspot.storage:storage:__HIDDEN__")
Add a back-end module based on your storage provider:
| Provider | Artifact |
|---|---|
| AWS S3 | com.brightspot.storage:aws |
| Azure Blob Storage | com.brightspot.storage:azure |
| Google Cloud Storage | com.brightspot.storage:gcp |
Using StorageItem in content types
To store files in a Brightspot content type, declare a field of type StorageItem:
1@Recordable.PreviewField("file")2public class GettingStarted extends Content {34private String name;56private StorageItem file;78public String getName() {9return name;10}1112public void setName(String name) {13this.name = name;14}1516public StorageItem getFile() {17return file;18}1920public void setFile(StorageItem file) {21this.file = file;22}23}
When editors upload a file through the CMS, Brightspot automatically persists it to the configured storage back end and serializes the StorageItem reference in the database.
Programmatic usage
Create and save a file to the default storage:
1public StorageItem uploadFile(String fileName, byte[] content, String contentType) throws IOException {2StorageItem item = StorageItem.Static.create();34item.setPath(fileName);5item.setContentType(contentType);6item.setData(new ByteArrayInputStream(content));7item.save();89return item;10}
Save to a specific named storage:
1public StorageItem uploadToSpecificStorage(String storageName, String fileName, InputStream data)2throws IOException {34StorageItem item = StorageItem.Static.createIn(storageName);56item.setPath(fileName);7item.setData(data);8item.save();910return item;11}
Read data back from a storage item:
1public byte[] downloadFile(StorageItem item) throws IOException {2try (InputStream data = item.getData()) {3return data.readAllBytes();4}5}
Copy a file between storage back ends:
1public StorageItem copyToStorage(StorageItem item, String targetStorage) throws IOException {2return StorageItem.Static.copy(item, targetStorage);3}
How it works
The storage system is built around the StorageItem interface, with AbstractStorageItem providing shared functionality like base URL construction and CDN hashing. Each back-end module extends AbstractStorageItem with provider-specific logic.
1StorageItem (interface)2└── AbstractStorageItem (abstract)3├── LocalStorageItem4├── S3StorageItem5├── AzureBlobStorageItem6└── GoogleCloudStorageItem
Storage back ends are configured via Dari settings under dari/storage/{name}, where {name} is an arbitrary identifier. The dari/defaultStorage setting determines which back end is used when no storage name is explicitly specified.
Who this documentation is for
- Storage back ends—For developers configuring a storage provider (local filesystem, S3, Azure, or GCS) for a Brightspot project.
- Extending—For developers implementing custom lifecycle hooks, path generators, CDN filters, or hashing strategies.