docker build -t auszug-server .
Users and their roles are configured with run/application.conf
. Look for ktor.security.users
property.
Each user record is an object defined by 3 attributes:
name
role
which can be either"read-write"
or"read-only"
secret
containing base64-encoded sha256 hash of user's password. It can be produced by the following snippet:fun hash(password:String) = MessageDigest.getInstance("SHA-256").digest("auszug${password.length}${password}".encodeToByteArray()).encodeBase64()
For your convenience application.conf
already contains two commented out user records:
gooduser / foobar / read-write
baduser / barfoo / read-only
Uncomment them or use as an example.
Run container:
docker run -it --volume=$(pwd)/run:/run -w /run -p 8080:8080 auszug-server
Container expects you to mount /run
volume, containing application.conf
configuration file. This volume will be used as a working directory for running application.
Auszug client side consists of a single StorageClient
. It has a very straightforward API.
- First, initialize a client instance. Provide it API entry point, username and password:
val c = StorageClient("http://localhost:8080", "gooduser", "foobar")
- Start transaction. Depending on you user's role it can be read-write or read-only transaction.
val tx = c.startTransaction()
- Define a data class representing your data record. Annotate it with
@Serializable
annotation from kotlinx.serialization.@Serializable data class MyData(val name: String, val flag: Boolean, val value: Int)
- Use transaction instance to
put()
,get()
ordelete()
records in storage. All records are addressed bystore
(representing some namespace or collection) and uniquekey
:val data = MyData("somestring", true, 100) tx.put("store1", "mykey", data) val result: MyData? = tx.get("store1", "mykey") tx.delete("store1", "mykey")
- Use
commit()
orrollback()
to finalize transaction.tx.commit()
Complete example:
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.Serializable
@Serializable
data class MyData(val name: String, val flag: Boolean, val value: Int)
fun main() = runBlocking {
val c = StorageClient("http://localhost:8080", "gooduser", "foobar")
c.startTransaction().let { tx ->
val data = MyData("somestring", true, 100)
tx.put("store1", "mykey", data)
tx.commit()
}
c.startTransaction().let { tx ->
val result: MyData? = tx.get("store1", "mykey")
println(result)
}
}