Reactive File Server using Quarkus
Reactive File Server provides REST API for accessing and writing files to the storage. The utilization of asynchronous I/O along with asynchronous programming provides a robust technological framework to achieve these objectives.
File Server supports two scenarios:
- writing files by applications
- reading files by users
For the sake of simplicity, the File Server does not store any information about either the user or the files themselves. But for accessing or writing the file on the file system we need the path of the file. Where this data come from?
To access a file, the user must provide both the resource ID, a unique identifier for the file, and an authentication token as part of the request. This token is employed to verify the user's identity and permissions via a separate service that manages the Access Control List (ACL). By utilizing the token and resource ID to call this service, all the necessary data for determining the file's path can be retrieved.
In another scenario involving writing a file, an application sends the payload in Base64 format within the request body, along with an API key. This key is employed to authenticate the request and ensure that only authorized users or applications with the necessary privileges can write files to the File Server.
There are various types of files and documents that can be treated differently. For instance, applications can generate reports, payrolls, or messages for individual users, which should only be accessible by the designated user. Alternatively, organizations may send messages with attachments to specific users, and these attachments are kept in file storage that can only be accessed by a certain user group. Another scenario is when administrators of the organizations upload files such as performance reports or exam results, where the file ID is the same as the user ID. As a result, different types of files and documents are kept in different folders.
Every user belongs to an organization, and each organization has its own file directory located within the root folder. When the ACL service is contacted with the token and resource ID parameters, the response retrieved could be in the following format:
{
"userId": "2234521",
"organizationId": "sampleOrg",
"fileName": "34543534543867856"
}
then the full path of the file is DOCUMENT_TYPE_ROOT/sampleorg/21/34543534543867856
Note: The file name is generated by a separate service and is unique. Additionally, it's important to note that only the final segment of the user ID is used to create a subfolder under the organization that can provide a better file read performance.
If an organization sends a newsletter to a group of users, they may include attachments that are stored on the File Server. In this scenario when the ACL service is contacted with the token and resource ID parameters, the response retrieved could be in the following format:
{
"userId": "",
"organizationId": "sampleOrg",
"fileName": "12345"
}
then the full path of the file is DOCUMENT_TYPE_ROOT/sampleorg/12345
Note: User ID is not needed to resolve the path.
In order for a given user to access a report that is specific to them (such as an exam result), they only need to provide the token to the caller. In this scenario, the ACL service will provide the user ID, and the file name for the document can be identical.
{
"userId": "3456345",
"organizationId": "sampleOrg",
"fileName": "3456345"
}
then the full path of the file is DOCUMENT_TYPE_ROOT/sampleorg/3456345
Each time a write request is received, the request body not only contains the file content but also the user ID, organization, and file name. In this situation, the request header contains an ApiKey, which serves as a token for authorizing the application.
- Java 17+
- Maven
Execute the following command
mvn clean package
Execute the following command
mvn quarkus:dev
Any command-line HTTP client, for example httpie, can be utilized for retrieving or sending document files to the Reactive File Server.
The json-server can be used as a means to simulate/mock the Access Control service.
The routes.json
defines the ACL service REST API, and the db.json
contains the mocked responses.
You can start the mock server from command line: json-server db.json --routes routes.json
.
How about we create a document on the Reactive File Server and then retrieve it?
Let's call our organization sampleOrg
, our user ID 1234567
and our document file name is hello-doc
.
Firstly encode the file content in the following way:
echo -n 'Hello Reactive File Server!' | base64
then send the document
http POST localhost:8888/api/document organizationId=sampleOrg userId=1234567 fileName=hello-doc content='SGVsbG8gUmVhY3RpdmUgRmlsZSBTZXJ2ZXIh' ApiKey:abcd
In case of success you get HTTP 201
response.
How you can fetch the document? From command line type http localhost:8888/api/document/1 Token:mytoken
and upon retrieval, the document that was previously written will be returned.