To run the examples in an IDE, you need to clone ActiveJ project:
And import it as a Maven project. Check out branch v4.1. Before running the example, build the project (Ctrl + F9 for IntelliJ IDEA).
Let’s have a closer look at Server Setup Example. To make setup and launching as simple as possible, there is a
an ActiveJ Launcher implementation (abstracted implementation of main
methods). It allows to simply set up applications, so all you need to set up an FS server is to override several Launcher
FileUploadExample also extends Launcher and thus implements the aforementioned Launcher methods.
In this example we will use a ActiveFs instance which depends on asynchronous ActiveJ Eventloop.
To simplify working with dependencies we will use ActiveJ Inject DI library. It is
lightning-fast, efficient and perfectly compatible with Launcher. So we simply @Inject
two instances and @Provides factory methods.
Just like in the previous example, we will also overwrite Launcher methods onInit, getOverrideModule, and run.
Also, this example utilizes ActiveJ CSP component, particularly ChannelFileReader class.
It allows to asynchronously read binary data from files.
You can see full example sources on GitHub,
here we will consider only the upload process that is defined in the overwritten method run.
has an implementation that is similar to the File Upload example. You can see full example sources on GitHub,
here we will consider only the download process that is defined in the overwritten method run.
Sometimes you may need to override/expand the default behavior of ActiveFs implementation. To do so, you may utilize a
demonstrates how to do just that. It decorates ActiveFs implementation by adding additional logging for file uploads and downloads.
DecoratedActiveFsExample extends ServerSetupExample so it inherits its DI bindings. First, we need to override
the binding for ActiveFsServer to pass decorated ActiveFs instead of the original one. To do so, we will override
Launcher#getOverrideModule method and provide a new binding for AsyncFsServer that uses decorated ActiveFs.
As you can see in decoratedActiveFs(ActiveFs fs) method, we request original ActiveFs and return the decorated one
(wrapped in LoggingActiveFs).
LoggingActiveFs extends ForwardingActiveFs which simply delegates all of the ActiveFs method calls to some underlying
ActiveFs instance. We override methods we want to decorate (download, upload) and add custom logging messages when
upload/download starts and finishes.
With ActiveJ FS you can simply create distributed cluster file storage with high fault tolerance. We will use Docker to
launch three virtual servers and one client. The storage will support file uploads with automatic
repartitioning according to the provided rule and replication count.
The first thing we need to do is to create a launcher class ClusterTcpServerLauncher for our server. Extend
to get all the required instances: ActiveFsServer,
for GUI that will simplify working with your storage, and other helper instances. In the ClusterTcpServerLauncher
we’ll only need to set up utils for repartitioning management like task schedulers, ClusterRepartitionController,
for tracking alive partitions and their statuses. The partitions will communicate via TCP protocol, while GUI server will
Now we can move on to creating a client launcher ClusterTcpClientLauncher. We need to provide ClusterRepartitionController and
a task scheduler to detect dead partitions. Similarly to the server launcher, we need to provide an AsyncHttpServer
for GUI and FsPartitions for managing partitions. We also need an instance of
class, an ActiveFs implementation that operates on other partitions as a cluster and contains some redundancy and
Here’s the architecture of our distributed P2P storage:
You can create as many partitions as you wish.
To launch the example, run the following scripts to create Docker images and build containers (run all the scripts under
The containers will be built with the following configurations:
Server1: TCP-connection port 9001, HTTP GUI port 8081
Server2: TCP-connection port 9002, HTTP GUI port 8082
Server3: TCP-connection port 9003, HTTP GUI port 8083