ScalarDB Server Sample
This is a sample application that uses ScalarDB Server, a gRPC server that implements ScalarDB interface, as a backend. For using the native ScalarDB library, please refer to Getting Started. More information about ScalarDB Server can be found here.
Sample application​
The sample application is a simple electronic money application that has the following features:
- Charge an
amount
to auser_id
- Pay an
amount
from auser_id
to anotheruser_id
- Get a
balace
of auser_id
Prerequisites​
- Java (OpenJDK 8 or higher)
- Gradle
- Docker, Docker Compose
Set up​
ScalarDB Server​
In this sample, we will use Cassandra as storage for ScalarDB Server. The configuration of ScalarDB Server is shown below. (It is also stored in database.properties)
# Comma separated contact points
scalar.db.contact_points=cassandra
# Port number for all the contact points. Default port number for each database is used if empty.
scalar.db.contact_port=9042
# Credential information to access the database
scalar.db.username=cassandra
scalar.db.password=cassandra
# Storage implementation
scalar.db.storage=cassandra
Clone the ScalarDB samples repository​
Open Terminal, then clone the ScalarDB samples repository by running the following command:
$ git clone https://github.com/scalar-labs/scalardb-samples
Then, go to the directory with this sample by running the following command:
$ cd scalardb-samples/scalardb-server-sample
Start Cassandra​
To start Cassandra and ScalarDB Server, we use the following command. Please note that we should wait around a bit more than one minute because ScalarDB container has to wait for Cassandra container to be fully started.
$ docker-compose -f docker-compose-cassandra.yml up -d
For using other databases as the backend for ScalarDB Server, we can change the configuration of database.properties according to Getting Started with ScalarDB. After that we can start ScalarDB Server using docker-compose.yml instead.
ScalarDB client​
The sample application uses a client that implements ScalarDB interface.
Thus, you can configure the client in the same way as the server-side.
But, in this case, you need to specify the server as a contact point and grpc
for the storage and transaction_manager configuration as follows. (it is stored in scalardb-client.properties).
# Comma separated contact points
scalar.db.contact_points=localhost
# Port number for all the contact points. Default port number for each database is used if empty.
scalar.db.contact_port=60051
# Storage implementation
scalar.db.storage=grpc
# The type of the transaction manager
scalar.db.transaction_manager=grpc
Set up database schema​
Now you apply the database schema of the sample application as shown below. (It is stored in emoney.json).
{
"emoney.account": {
"transaction": true,
"partition-key": [
"id"
],
"clustering-key": [],
"columns": {
"id": "TEXT",
"balance": "INT"
}
}
}
You then apply the schema with the following command.
Please download the schema tool scalardb-schema-loader-<version>.jar
that can be found in releases of ScalarDB.
$ java -jar scalardb-schema-loader-<version>.jar --config scalardb-client.properties --schema-file emoney.json --coordinator
Note that --coordinator
is specified to create the coordinator table needed for transactions.
Run the sample​
- Charge
1000
touser1
:
$ ./gradlew run --args="-action charge -amount 1000 -to user1"
- Charge
0
tomerchant1
(Just create an account formerchant1
):
$ ./gradlew run --args="-action charge -amount 0 -to merchant1"
- Pay
100
fromuser1
tomerchant1
:
$ ./gradlew run --args="-action pay -amount 100 -from user1 -to merchant1"
- Get the balance of
user1
:
$ ./gradlew run --args="-action getBalance -id user1"
- Get the balance of
merchant1
:
$ ./gradlew run --args="-action getBalance -id merchant1"
Storage abstraction​
ScalarDB Server also supports Storage API. The following describes a sample of Storage API.
Set up database schema​
If you have created the tables for transactions, you can delete them with the -D
option as follows.
$ java -jar scalardb-schema-loader-<version>.jar --config scalardb-client.properties --schema-file emoney.json --coordinator -D
You can create a schema by setting transaction
to false. (The updated schema is stored in emoney-storage.json)
{
"emoney.account": {
"transaction": false,
"partition-key": [
"id"
],
"clustering-key": [],
"columns": {
"id": "TEXT",
"balance": "INT"
}
}
}
You then apply the schema with the following command.
$ java -jar scalardb-schema-loader-<version>.jar --config scalardb-client.properties --schema-file emoney-storage.json
Run the sample with Storage API​
- Charge
1000
touser1
:
$ ./gradlew -Pstorage run --args="-action charge -amount 1000 -to user1"
- Charge
0
tomerchant1
(Just create an account formerchant1
):
$ ./gradlew -Pstorage run --args="-action charge -amount 0 -to merchant1"
- Pay
100
fromuser1
tomerchant1
:
$ ./gradlew -Pstorage run --args="-action pay -amount 100 -from user1 -to merchant1"
- Get the balance of
user1
:
$ ./gradlew -Pstorage run --args="-action getBalance -id user1"
- Get the balance of
merchant1
:
$ ./gradlew -Pstorage run --args="-action getBalance -id merchant1"
Clean up​
To stop Cassandra and ScalarDB Server, run the following command:
$ docker-compose -f docker-compose-cassandra.yml down