This project implements a REST API for an imaginary software package system called "Repsy", similar to how Maven or npm works but for a fictional "Repsy programming language". It allows deploying package versions (binary .rep
file + meta.json
metadata) and downloading specific package files.
The key feature is a pluggable storage layer using different strategies (Filesystem, Minio Object Storage) configured via application properties.
This project follows a modular design:
repsy-parent
: The parent POM defining common dependencies and properties for all modules.storage-api
: Defines the core interfaces (StorageService
,StorageProperties
) and exceptions for the storage layer. Other modules depend on this.storage-filesystem
: Contains theFileSystemStorageService
implementation, storing packages on the local filesystem.storage-minio
: Contains theMinioStorageService
implementation, storing packages in a Minio S3-compatible object storage bucket.repsy_api
: The main Spring Boot application containing the REST controllers, services (likePackageService
), JPA entities, repositories, and the auto-configuration (StorageAutoConfiguration
) to wire everything together. This is the runnable JAR.
Configuration is managed in repsy_api/src/main/resources/application.properties
.
Configure your PostgreSQL connection details:
spring.datasource.url=jdbc:postgresql://localhost:5432/repsy_db
spring.datasource.username=your_db_user
spring.datasource.password=your_db_password
- Ensure you have a PostgreSQL server running and the specified database (
repsy_db
by default) exists. - Update the username and password accordingly.
spring.jpa.hibernate.ddl-auto=update
is set for development (updates schema automatically). Change tovalidate
ornone
for production.
The storage backend is selected using the storage.strategy
property:
# Choose 'filesystem' or 'minio'
storage.strategy=filesystem
filesystem
(Default): Stores packages on the local filesystem.storage.location=upload-dir
: Specifies the directory (relative to the application's run location) where packages will be stored.
minio
: Stores packages in a Minio bucket. Requires additional configuration:storage.strategy=minio storage.minio.endpoint=http://your-minio-server:9000 storage.minio.access-key=your_minio_access_key storage.minio.secret-key=your_minio_secret_key storage.minio.bucket-name=repsy-packages # Or your preferred bucket name
- Ensure you have a Minio server running.
- Update the endpoint, keys, and bucket name. The specified bucket must exist or be creatable by the provided credentials.
Note: Both filesystem
and minio
storage strategies have been tested and confirmed to be working correctly for package deployment and download operations.
Navigate to the project's root directory (RepsyAPI
) in your terminal and run:
./mvnw clean install
This command will:
- Clean previous build artifacts.
- Compile all modules.
- Run tests (if any).
- Install the library modules (
storage-api
,storage-filesystem
,storage-minio
) into your local Maven repository (.m2
). - Package the main application (
repsy_api
) into a runnable JAR file inrepsy_api/target/
.
After a successful build, run the main application from the project's root directory:
./mvnw -pl repsy_api spring-boot:run
- The
-pl repsy_api
flag tells Maven to run thespring-boot:run
goal specifically on therepsy_api
module. - The application will start, using the configuration from
repsy_api/src/main/resources/application.properties
. - By default, it will listen on port
8080
.
This project includes a Dockerfile
for the main application (repsy_api/Dockerfile
) and a docker-compose.yml
file in the root directory to easily run the application along with its dependencies (PostgreSQL and Minio).
- Docker and Docker Compose installed.
-
Navigate to the project root directory (
RepsyAPI
) in your terminal. -
Build and start the services:
docker compose up --build
- The
--build
flag is needed the first time or if you make changes to therepsy_api
code orDockerfile
. - This command will:
- Build the Docker image for the
repsy-api
service usingrepsy_api/Dockerfile
. - Download the official images for PostgreSQL (
db
service) and Minio (minio
service). - Start all three containers.
- Show the combined logs in your terminal.
- Build the Docker image for the
- To run in detached mode (in the background), use
docker compose up -d --build
.
- The
-
(If using Minio) Create Minio Bucket:
- If you intend to use the
minio
storage strategy, you need to create the bucket specified indocker-compose.yml
(default:repsy-packages
). - Open your browser and go to the Minio console:
http://localhost:9001
. - Log in with the credentials defined in
docker-compose.yml
(default:minioadmin
/minioadmin
). - Create the bucket named
repsy-packages
.
- If you intend to use the
-
Access the API: The Repsy API will be available at
http://localhost:8080
.
- The
docker-compose.yml
file uses environment variables to configure therepsy-api
service, overriding settings inapplication.properties
. - Database and Minio hostnames are set to the service names (
db
andminio
). - Default Storage: The default storage strategy when running with Docker Compose is
filesystem
. Files will be stored inside therepsy-api
container at/app/upload-dir-in-container
. - Using Minio Strategy: To run with the Minio strategy, set the
STORAGE_STRATEGY
environment variable when starting:STORAGE_STRATEGY=minio docker compose up --build
- If running in the foreground, press
Ctrl+C
in the terminal wheredocker compose up
is running. - If running in detached mode, navigate to the project root and run:
This will stop and remove the containers. Add the
docker compose down
-v
flag (docker compose down -v
) to also remove the data volumes (postgres_data
,minio_data
).
- Method:
POST
- URL:
/packages/{packageName}/{version}
- Content-Type:
multipart/form-data
- Form Data:
metaFile
(File): Themeta.json
file for the package.repFile
(File): The binary.rep
file for the package.
- Success Response:
201 Created
(No body) - Error Responses:
409 Conflict
: If the package name and version already exist.400 Bad Request
: IfmetaFile
orrepFile
is empty, or ifmeta.json
content is invalid (e.g., name/version mismatch, invalid JSON).
- Method:
GET
- URL:
/packages/{packageName}/{version}/{fileName}
fileName
: Can be the.rep
file (e.g.,mypackage-1.0.0.rep
) ormeta.json
.
- Success Response:
200 OK
with the requested file content and appropriateContent-Type
header. - Error Responses:
404 Not Found
: If the package, version, or specific file does not exist in the configured storage.
This README provides a basic overview. Further enhancements could include Docker support, more detailed error handling, security considerations, etc.