# ScalarDL Documentation - Full Repository Context
# Generated by using GitIngest for AI/LLM consumption
# Scalable and practical Byzantine-fault detection middleware for transactional database systems
# Website: https://scalardl.scalar-labs.com
Directory: home/runner/work/docs-scalardl/docs-scalardl
Files analyzed: 152
Estimated tokens: 270.3k
Directory structure:
└── docs-scalardl/
├── docs/
│ ├── access-namespaces-in-a-restricted-manner.mdx
│ ├── authentication.mdx
│ ├── backup-restore.mdx
│ ├── compatibility.mdx
│ ├── configurations.mdx
│ ├── data-modeling.mdx
│ ├── deploy-local-environment-overview.mdx
│ ├── deploy-managed-kubernetes-environment-overview.mdx
│ ├── deploy-overview.mdx
│ ├── design.mdx
│ ├── develop-advanced-configurations-overview.mdx
│ ├── develop-overview.mdx
│ ├── develop-run-an-application-overview.mdx
│ ├── develop-samples-overview.mdx
│ ├── develop-write-an-application-overview.mdx
│ ├── develop-write-business-logic-overview.mdx
│ ├── generic-contracts-reference.mdx
│ ├── getting-started-hashstore.mdx
│ ├── getting-started-tablestore.mdx
│ ├── getting-started.mdx
│ ├── glossary.mdx
│ ├── how-to-run-applications-with-auditor.mdx
│ ├── how-to-run-applications.mdx
│ ├── how-to-write-applications-with-generic-contracts.mdx
│ ├── how-to-write-applications-with-hashstore.mdx
│ ├── how-to-write-applications-with-tablestore.mdx
│ ├── how-to-write-applications.mdx
│ ├── how-to-write-contract.mdx
│ ├── how-to-write-function.mdx
│ ├── implementation.mdx
│ ├── index.mdx
│ ├── installation-with-docker.mdx
│ ├── learning-paths.mdx
│ ├── libraries-and-tools.mdx
│ ├── manage-backup-and-restore-overview.mdx
│ ├── manage-contract-and-function-lifecycle.mdx
│ ├── manage-monitor-overview.mdx
│ ├── manage-namespaces.mdx
│ ├── manage-overview.mdx
│ ├── onboarding.mdx
│ ├── overview.mdx
│ ├── quickstart-overview.mdx
│ ├── requirements.mdx
│ ├── roadmap.mdx
│ ├── scalardl-auditor-status-codes.mdx
│ ├── scalardl-client-status-codes.mdx
│ ├── scalardl-command-reference.mdx
│ ├── scalardl-common-status-codes.mdx
│ ├── scalardl-hashstore-command-reference.mdx
│ ├── scalardl-hashstore-status-codes.mdx
│ ├── scalardl-ledger-status-codes.mdx
│ ├── scalardl-tablestore-command-reference.mdx
│ ├── scalardl-tablestore-status-codes.mdx
│ ├── schema-loader.mdx
│ ├── sql-grammar.mdx
│ ├── use-generic-contracts.mdx
│ ├── use-table-oriented-generic-contracts.mdx
│ ├── applications/
│ │ └── simple-bank-account/
│ │ ├── README.mdx
│ │ └── docs/
│ │ └── api_endpoints.mdx
│ ├── ca/
│ │ ├── caclient-getting-started.mdx
│ │ └── caserver-getting-started.mdx
│ ├── helm-charts/
│ │ ├── configure-custom-values-envoy.mdx
│ │ ├── configure-custom-values-file.mdx
│ │ ├── configure-custom-values-scalar-admin-for-kubernetes.mdx
│ │ ├── configure-custom-values-scalar-manager.mdx
│ │ ├── configure-custom-values-scalardb-analytics-server.mdx
│ │ ├── configure-custom-values-scalardb-cluster.mdx
│ │ ├── configure-custom-values-scalardb-graphql.mdx
│ │ ├── configure-custom-values-scalardb.mdx
│ │ ├── configure-custom-values-scalardl-auditor.mdx
│ │ ├── configure-custom-values-scalardl-ledger.mdx
│ │ ├── configure-custom-values-scalardl-schema-loader.mdx
│ │ ├── getting-started-logging.mdx
│ │ ├── getting-started-monitoring.mdx
│ │ ├── getting-started-scalar-helm-charts.mdx
│ │ ├── getting-started-scalar-manager.mdx
│ │ ├── getting-started-scalardb-cluster-tls-cert-manager.mdx
│ │ ├── getting-started-scalardb-cluster-tls.mdx
│ │ ├── getting-started-scalardb.mdx
│ │ ├── getting-started-scalardl-auditor-tls-cert-manager.mdx
│ │ ├── getting-started-scalardl-auditor-tls.mdx
│ │ ├── getting-started-scalardl-auditor.mdx
│ │ ├── getting-started-scalardl-ledger.mdx
│ │ ├── how-to-deploy-scalar-admin-for-kubernetes.mdx
│ │ ├── how-to-deploy-scalar-products.mdx
│ │ ├── how-to-deploy-scalardb-cluster.mdx
│ │ ├── how-to-deploy-scalardb-graphql.mdx
│ │ ├── how-to-deploy-scalardb.mdx
│ │ ├── how-to-deploy-scalardl-auditor.mdx
│ │ ├── how-to-deploy-scalardl-ledger.mdx
│ │ ├── mount-files-or-volumes-on-scalar-pods.mdx
│ │ └── use-secret-for-credentials.mdx
│ ├── javadoc/
│ │ └── index.mdx
│ ├── releases/
│ │ ├── release-notes.mdx
│ │ └── release-support-policy.mdx
│ ├── scalar-kubernetes/
│ │ ├── AccessScalarProducts.mdx
│ │ ├── AwsMarketplaceGuide.mdx
│ │ ├── BackupNoSQL.mdx
│ │ ├── BackupRDB.mdx
│ │ ├── BackupRestoreGuide.mdx
│ │ ├── CreateAKSClusterForScalarDB.mdx
│ │ ├── CreateAKSClusterForScalarDL.mdx
│ │ ├── CreateAKSClusterForScalarDLAuditor.mdx
│ │ ├── CreateAKSClusterForScalarProducts.mdx
│ │ ├── CreateBastionServer.mdx
│ │ ├── CreateEKSClusterForScalarDB.mdx
│ │ ├── CreateEKSClusterForScalarDBCluster.mdx
│ │ ├── CreateEKSClusterForScalarDL.mdx
│ │ ├── CreateEKSClusterForScalarDLAuditor.mdx
│ │ ├── CreateEKSClusterForScalarProducts.mdx
│ │ ├── HowToCreateKeyAndCertificateFiles.mdx
│ │ ├── HowToGetContainerImages.mdx
│ │ ├── HowToScaleScalarDB.mdx
│ │ ├── HowToScaleScalarDL.mdx
│ │ ├── HowToUpgradeScalarDB.mdx
│ │ ├── HowToUpgradeScalarDL.mdx
│ │ ├── HowToUseContainerImages.mdx
│ │ ├── K8sLogCollectionGuide.mdx
│ │ ├── K8sMonitorGuide.mdx
│ │ ├── ManualDeploymentGuideScalarDBClusterOnEKS.mdx
│ │ ├── ManualDeploymentGuideScalarDBServerOnAKS.mdx
│ │ ├── ManualDeploymentGuideScalarDBServerOnEKS.mdx
│ │ ├── ManualDeploymentGuideScalarDLAuditorOnAKS.mdx
│ │ ├── ManualDeploymentGuideScalarDLAuditorOnEKS.mdx
│ │ ├── ManualDeploymentGuideScalarDLOnAKS.mdx
│ │ ├── ManualDeploymentGuideScalarDLOnEKS.mdx
│ │ ├── NetworkPeeringForScalarDLAuditor.mdx
│ │ ├── ProductionChecklistForScalarDBCluster.mdx
│ │ ├── ProductionChecklistForScalarDLAuditor.mdx
│ │ ├── ProductionChecklistForScalarDLLedger.mdx
│ │ ├── ProductionChecklistForScalarProducts.mdx
│ │ ├── RegularCheck.mdx
│ │ ├── RestoreDatabase.mdx
│ │ ├── SetupDatabase.mdx
│ │ ├── SetupDatabaseForAWS.mdx
│ │ ├── SetupDatabaseForAzure.mdx
│ │ └── alerts/
│ │ ├── README.mdx
│ │ ├── Envoy.mdx
│ │ └── Ledger.mdx
│ ├── scalar-licensing/
│ │ ├── commercial.mdx
│ │ ├── index.mdx
│ │ └── trial.mdx
│ ├── scalar-manager/
│ │ ├── how-to-use-scalar-manager.mdx
│ │ ├── metrics-reference.mdx
│ │ └── overview.mdx
│ └── scalardl-benchmarks/
│ └── README.mdx
└── src/
└── components/
└── en-us/
├── _certificate-management.mdx
├── _getting-started-auditor-db-specific-steps.mdx
├── _getting-started-db-specific-steps.mdx
├── _getting-started-startup-ledger.mdx
├── _prerequisites-jdk-versions.mdx
└── _warning-license-key-contact.mdx
================================================
FILE: docs/access-namespaces-in-a-restricted-manner.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
import StartupLedger from '/src/components/en-us/_getting-started-startup-ledger.mdx';
# Access Namespaces in a Restricted Manner
:::warning
The namespace feature is currently in Public Preview. The feature and related documentation are subject to change.
:::
This document explains how to set up namespaces and access them in a restricted manner in a multi-tenant deployment of ScalarDL.
## What is restricted access to namespaces?
Restricting access to namespaces allows you to host multiple tenants on a single ScalarDL cluster while ensuring strict data isolation between them. Each tenant operates within its own namespace and can only access assets within that namespace.
### Security model
Restricted access to namespaces relies on port-based access control:
- **Privileged port:** Used by administrators for namespace management and credential registration. Only administrators should have access to this port.
- **Non-privileged port:** Used by tenant clients for contract registration and execution. Tenants access this port with their credentials registered to their specific namespace.
Because tenant credentials are registered to a specific namespace, all operations performed with those credentials are automatically scoped to that namespace. Tenants cannot register contracts or execute operations outside their assigned namespace.
:::note
This tutorial uses default ports and runs all commands from the same client machine for simplicity, assuming both the privileged and non-privileged ports are accessible. In a production environment, you should restrict access to the privileged port so that only administrators can reach it, while tenants connect only through the non-privileged port.
:::
## Download the Client SDK
Next, you'll use the ScalarDL client tools and samples to interact with ScalarDL.
Specify a version that is the same as the deployed ScalarDL version and is used for downloading the tools by running the following command:
```console
VERSION=$(grep SCALARDL_VERSION .env | awk -F= '{print $2}')
```
Then, download the tools by running the following command:
```console
curl -OL https://github.com/scalar-labs/scalardl/releases/download/v$VERSION/scalardl-java-client-sdk-$VERSION.zip
unzip scalardl-java-client-sdk-$VERSION.zip
mv scalardl-java-client-sdk-$VERSION client
```
## Set up a tenant namespace
This section walks you through the steps to set up a new tenant namespace.
### Configure the administrator client
You need to configure client properties for administrators to manage tenant namespaces and credentials. To create a configuration file with the minimum required properties for the administrator client, run the following command:
```console
cat << 'EOF' > admin.properties
# A host name for ScalarDL Ledger.
scalar.dl.client.server.host=localhost
# An entity ID. This must be configured for each private key and must be unique in a namespace.
scalar.dl.client.entity.id=admin
# A path to the certificate file.
scalar.dl.client.entity.identity.digital_signature.cert_path=./fixture/client.pem
# A path to the private key file.
scalar.dl.client.entity.identity.digital_signature.private_key_path=./fixture/client-key.pem
EOF
```
You can use `localhost` for the ScalarDL Ledger host name in this tutorial. For the private key and certificate, you can use the ones provided in the `fixture` directory of `scalardl-samples` (`client-key.pem` and `client.pem`, respectively). For the certificate holder, any unique ID can be specified.
:::warning
Do not use the sample private key and certificate in production environments. For details about getting your own certificate, see [How to Get a Certificate](ca/caclient-getting-started.mdx).
:::
### Create a tenant namespace
As an administrator, create a namespace for the tenant by running the following command. This operation requires access to the privileged port.
```console
client/bin/scalardl create-namespace --properties admin.properties --namespace tenant_a
```
### Register tenant credentials
Register the tenant's certificate to the newly created namespace by running the following commands. This associates the tenant's identity with their namespace.
```console
client/bin/scalardl register-cert --properties admin.properties --namespace tenant_a --entity-id foo --cert-path ./fixture/client.pem
```
:::note
This sample uses the same `client.pem` as the administrator client for simplicity. In an actual production environment with digital signature authentication, you should use a certificate issued by the tenant user.
:::
## Use a tenant namespace
This section explains how to set up the tenant client to interact with its assigned namespace.
### Configure the tenant client
You need to configure client properties for the tenant to register and execute contracts or validate assets on the assigned namespace. To create a configuration file with the minimum required properties for the tenant client, run the following command:
```console
cat << 'EOF' > tenant.properties
# A host name for ScalarDL Ledger.
scalar.dl.client.server.host=localhost
# An entity ID. This must match the entity ID registered to the namespace in the previous step.
scalar.dl.client.entity.id=foo
# A namespace where client requests are executed.
scalar.dl.client.context.namespace=tenant_a
# A path to the certificate file.
scalar.dl.client.entity.identity.digital_signature.cert_path=./fixture/client.pem
# A path to the private key file.
scalar.dl.client.entity.identity.digital_signature.private_key_path=./fixture/client-key.pem
EOF
```
### Register and execute contracts
The tenant can now register contracts and execute them within their namespace. You can use the same contracts introduced in [Get Started with ScalarDL Ledger](getting-started.mdx#create-a-contract) without needing to be aware of namespaces because all operations are automatically scoped to the namespace configured in the client properties.
First, compile the contracts in `scalardl-samples` by running the following command:
```console
./gradlew assemble
```
This will generate `build/classes/java/main/com/org1/contract/StateUpdater.class`. Then, register the contract by running the following command:
```console
client/bin/scalardl register-contract --properties tenant.properties --contract-id StateUpdater --contract-binary-name com.org1.contract.StateUpdater --contract-class-file build/classes/java/main/com/org1/contract/StateUpdater.class
```
Execute the contract by running the following command:
```console
client/bin/scalardl execute-contract --properties tenant.properties --contract-id StateUpdater --contract-argument '{"asset_id":"some_asset", "state":3}'
```
### Register and execute functions
By default, tenants can register contracts through the non-privileged port but cannot register functions. To allow tenants to register functions, administrators must set the following Ledger configuration options:
- `scalar.dl.ledger.function.non_privileged_port_registration.enabled`: Set to `true` to allow tenants to register functions through the non-privileged port. The default is `false`.
- `scalar.dl.ledger.function.non_privileged_port_registration.overwrite.enabled`: Set to `true` to allow tenants to overwrite existing functions through the non-privileged port. The default is `false`.
Once function registration is enabled, tenants can register and execute functions within their namespace in the same way as in the default namespace. For example, to register a function, run the following command:
```console
client/bin/scalardl register-function --properties tenant.properties --function-id test-function --function-binary-name com.example.function.TestFunction --function-class-file /path/to/TestFunction.class
```
To execute a function along with a contract, run the following command:
```console
client/bin/scalardl execute-contract --properties tenant.properties --contract-id StateUpdater --contract-argument '{"asset_id":"some_asset", "state":3}' --function-id test-function --function-argument '{}'
```
For details on updating contracts and functions, see [Manage Contract and Function Lifecycle](manage-contract-and-function-lifecycle.mdx).
### Validate assets
You can also validate assets as usual, like in the default namespace, by running the following command:
```console
client/bin/scalardl validate-ledger --properties tenant.properties --asset-id="some_asset"
```
## See also
To write your own contracts, see the following:
- [A Guide on How to Write a Good Contract](how-to-write-contract.mdx)
To interact with ScalarDL components in your Java applications, see the following:
- [Write a ScalarDL Application in Java](how-to-write-applications.mdx)
To learn more about namespaces and how to manage them, see the following:
- [Manage Namespaces](manage-namespaces.mdx)
- [ScalarDL Client Command Reference](scalardl-command-reference.mdx)
================================================
FILE: docs/authentication.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL Authentication Guide
This document explains the ScalarDL authentication mechanism and how to use it properly.
## Authentication in ScalarDL
Authentication is one of the key roles in ScalarDL and makes the protocol work as expected.
ScalarDL uses authentication in the following three situations:
* Client authentication (for Ledger and Auditor)
* Ledger and Auditor authenticate clients by using client-generated signatures attached to requests from the clients.
* Ledger authentication (for Auditor)
* Auditor authenticates Ledger by using Ledger-generated signatures attached to [asset proofs](how-to-write-applications.mdx#what-is-asset-proof).
* Auditor authentication (for Ledger)
* Ledger authenticates Auditor by using Auditor-generated signatures attached to client requests.
Note that Ledger authentication and Auditor authentication are only used in the Auditor mode. For more details about Auditor, see [Run a ScalarDL Application Through ScalarDL Ledger and Auditor](how-to-run-applications-with-auditor.mdx) and [ScalarDL Implementation](implementation.mdx).
Also, note that we use the term `signature` here to specify a byte array used for authentication.
## Authentication methods
ScalarDL supports two authentication methods: digital signatures and HMAC.
Both of these methods have advantages and disadvantages, as described below, but neither method sacrifices Byzantine fault detection capability.
### Digital signatures
* Advantages
* Client requests, asset records, and asset proofs have the nonrepudiation property. Specifically, a digital signature attached to a client request is stored with the corresponding asset records that the request produces so that a client request and the corresponding records have the nonrepudiation property, i.e., we can ensure that the owner of the private key that signed the request created the records. Moreover, digital signatures attached to asset proofs that are returned to a client as the result of execution ensure that Ledger and Auditor created the proofs, respectively. If a client (application) keeps the proofs, the client can verify the results with the proofs as necessary.
* Disadvantages
* Digital signatures are very slow. They will add nonnegligible performance overhead in exchange for the above benefits.
### HMAC
* Advantages
* HMAC is much faster than digital signatures.
* Disadvantages
* Client requests, asset records, and asset proofs do not have the nonrepudiation property.
### Which should I use?
If you do not require the nonrepudiation property, you should always use HMAC.
Technically, you could mix authentication methods, like using digital signatures for client authentication and HMAC for Ledger/Auditor authentication. However, because mixing methods can be very confusing, ScalarDL prohibits such usage.
Note that we plan to update ScalarDL to use only HMAC for Ledger and Auditor authentication for better performance. Similarly, we plan to unbundle Ledger and Auditor authentication from how we sign asset proofs. With the above changes, we will be able to return digitally signed asset proofs while using HMAC authentication between Ledger and Auditor.
## Configure
This section explains what variables you need to configure to use ScalarDL authentication properly. For details about each variable, see [Javadoc](javadoc/index.mdx).
### Digital signatures
* Client authentication
* Client-side properties
* `scalar.dl.client.auditor.enabled` (set to `true` if you use Auditor)
* `scalar.dl.client.authentication.method` (set to `digital-signature`)
* `scalar.dl.client.entity.id` (or `scalar.dl.client.cert_holder_id`, which is deprecated.)
* Used for identifying a client.
* `scalar.dl.client.entity.identity.digital_signature.cert_pem` or `scalar.dl.client.entity.identity.digital_signature.cert_path` (or `scalar.dl.client.cert_pem` or `scalar.dl.client.cert_path`, which are deprecated.)
* Used for registering a certificate for Ledger and Auditor to verify a client-generated signature.
* See [this](ca/caclient-getting-started.mdx#get-a-certificate-from-a-ca-server) for how to get a certificate.
* `scalar.dl.client.entity.identity.digital_signature.cert_version` (or `scalar.dl.client.cert_version`, which is deprecated.)
* `scalar.dl.client.entity.identity.digital_signature.private_key_pem` or `scalar.dl.client.entity.identity.digital_signature.private_key_path` (or `scalar.dl.client.private_key_pem` or `scalar.dl.client.private_key_path`, which are deprecated.)
* Used for signing a request.
* See [this](ca/caclient-getting-started.mdx#generate-a-private-key-and-a-csr) for how to get a private key.
* Ledger-side properties
* `scalar.dl.ledger.authentication.method` (set to `digital-signature`)
* Auditor-side properties
* `scalar.dl.auditor.authentication.method` (set to `digital-signature`)
* Ledger authentication
* Ledger-side properties
* `scalar.dl.ledger.proof.enabled` (set to `true`)
* Required because Ledger authentication uses the signatures of asset proofs.
* `scalar.dl.ledger.proof.private_key_pem` or `scalar.dl.ledger.proof.private_key_path`
* Used for signing asset proofs.
* See [this](ca/caclient-getting-started.mdx#generate-a-private-key-and-a-csr) for how to get a private key.
* Auditor-side properties
* `scalar.dl.auditor.ledger.cert_holder_id`
* `scalar.dl.auditor.ledger.cert_version`
* Used for verifying the signatures of asset proofs.
* Auditor authentication
* Ledger-side properties
* `scalar.dl.ledger.auditor.cert_holder_id`
* Used for verifying an Auditor-generated signature attached to a client request.
* `scalar.dl.ledger.auditor.cert_version`
* Used for verifying an Auditor-generated signature attached to a client request.
* Auditor-side properties
* `scalar.dl.auditor.cert_holder_id`
* Used for calling Ledger services directly by using the client library.
* `scalar.dl.auditor.cert_version`
* Used for calling Ledger services directly by using the client library.
* `scalar.dl.auditor.private_key_pem` or `scalar.dl.auditor.private_key_path`
* Used for signing a client request and a request from Auditor to Ledger.
* See [this](ca/caclient-getting-started.mdx#generate-a-private-key-and-a-csr) for how to get a private key.
### HMAC
* Client authentication
* Client-side properties
* `scalar.dl.client.authentication.method` (set to `hmac`)
* `scalar.dl.client.entity.id`
* Used for identifying a client.
* `scalar.dl.client.entity.identity.hmac.secret_key`
* Used for signing a request.
* A secret key should be a random, lengthy value (e.g., 32-character length hex string).
* `scalar.dl.client.entity.identity.hmac.secret_key_version`
* Ledger-side properties
* `scalar.dl.ledger.authentication.method` (set to `hmac`)
* Auditor-side properties
* `scalar.dl.auditor.authentication.method` (set to `hmac`)
* Ledger and Auditor authentication
* Ledger-side properties
* `scalar.dl.ledger.proof.enabled` (set to `true`)
* Required because Ledger authentication uses the signatures of asset proofs.
* `scalar.dl.ledger.servers.authentication.hmac.secret_key`
* Used for signing and verifying messages and requests between Ledger and Auditor.
* A secret key should be a random, lengthy value (e.g., 32-character length hex string).
* `scalar.dl.ledger.authentication.hmac.cipher_key`
* Used for encrypting and decrypting the secret keys of clients.
* A cipher key should be an unpredictable, lengthy value.
* Auditor-side properties
* `scalar.dl.auditor.servers.authentication.hmac.secret_key`
* Used for signing and verifying messages and requests between Ledger and Auditor. Must be the same key as `scalar.dl.ledger.servers.authentication.hmac.secret_key`.
* A secret key should be a random, lengthy value (e.g., 32-character length hex string).
* `scalar.dl.auditor.authentication.hmac.cipher_key`
* Used for encrypting and decrypting the secret keys of clients.
* A cipher key should be an unpredictable, lengthy value.
## Prepare before executing requests
After configuration, you must do the following to prepare for issuing execution requests.
### Digital signatures
* Register clients' certificates to Ledger (and Auditor, if enabled).
* Use the client library or the command-line tool (`register-cert`).
* Register Auditor's certificates to Ledger.
* Required only if Auditor is enabled.
* Register Ledger's certificates to Auditor.
* Required only if Auditor is enabled.
* Register contracts to Ledger (and Auditor, if enabled).
### HMAC
* Register clients' secret keys to Ledger (and Auditor, if enabled).
* Use the client library or the command-line tool (`register-secret`).
* Register contracts to Ledger (and Auditor).
================================================
FILE: docs/backup-restore.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# A Guide on How to Backup and Restore Data in ScalarDL
Since ScalarDL uses ScalarDB that provides transaction capability on top of non-transactional (possibly transactional) databases non-invasively,
you need to take special care of backing up and restoring the databases in a transactionally-consistent way.
This guide shows you how to create and restore transactionally-consistent ScalarDL backups.
We first describe how to backup and restore the databases of ScalarDL Ledger. Then, we will describe how the process is extended to cover a case where Auditor is used.
## Create Backups of Ledger Databases
### For Transactional Databases
#### JDBC databases
You can take a backup with your favorite way for JDBC databases.
One requirement for backup in ScalarDL on JDBC databases is that backups for all the ScalarDL managed tables (including the coordinator and scalardb tables) need to be transactionally-consistent or automatically recoverable to a transactionally-consistent state.
That means that you need to create a consistent snapshot by dumping all tables in a single transaction. For example, you can use `mysqldump` command with `--single-transaction` option in MySQL and `pg_dump` command in PostgreSQL to achieve that.
Or when you use Amazon RDS (Relational Database Service) or Azure Database for MySQL/PostgreSQL, you can restore to any point within the backup retention period with the automated backup feature, which satisfies the requirement.
### For Non-transactional Databases
#### Basic strategy to create a transactionally-consistent backup
One way to create a transactionally-consistent backup is to take a backup while ScalarDL cluster does not have outstanding transactions.
If an underlying database supports a point-in-time snapshot/backup mechanism, you can take a snapshot during the period.
If an underlying database supports a point-in-time restore/recovery mechanism, you can set a restore point to a specific time (preferably the mid-time) in the period.
To easily achieve this, ScalarDL exposes pause API to make ScalarDL drain outstanding transactions and stop accepting new transactions.
We also provide a simple client program called [scalar-admin](https://github.com/scalar-labs/scalar-admin) to make a pause request (and unpause request) to a ScalarDL cluster and obtain a paused duration.
Note that when you use a point-in-time-restore/recovery mechanism, it is recommended to minimize the clock drifts between nodes (ScalarDL nodes and a client node that requests a pause) by using clock synchronization such as NTP.
Otherwise, the time you get as a paused duration might be too different from the time in which the pause was actually conducted, which could restore to a point where ongoing transactions exist.
Also, it is recommended to pause a long enough time (for example, 5 seconds) and use the mid-time of the paused duration since clock synchronization cannot perfectly synchronize clocks between nodes.
#### Database-specific ways to create a transactionally-consistent backup
**Cassandra**
Cassandra has a built-in replication mechanism, so you do not always have to create a transactionally-consistent backup.
For example, if replication is set to 3 and only the data of one of the nodes in a cluster is lost, you do not need a transactionally-consistent backup because the node can be recovered with a normal (transactionally-inconsistent) snapshot and the repair mechanism.
However, if the quorum of nodes of a cluster loses their data, we need a transactionally-consistent backup to restore the cluster to a certain transactionally-consistent point.
If you want to create a transactionally-consistent cluster-wide backup, please follow [the basic strategy](#basic-strategy-to-create-a-transactionally-consistent-backup) section, or
stop the Cassandra cluster and take the copies of all the nodes of the cluster, and start the cluster.
**Cosmos DB**
You must create a Cosmos DB account with a Continuous backup policy enabled to use point-in-time restore (PITR) feature. Backups are created continuously after it is enabled.
To specify a transactionally-consistent restore point, please pause ScalarDL service as described in the [basic strategy](#basic-strategy-to-create-a-transactionally-consistent-backup).
**DynamoDB**
You must enable the point-in-time recovery (PITR) feature for DynamoDB tables. If you use [ScalarDL Schema Loader](https://github.com/scalar-labs/scalardl-schema-loader), it enables PITR by default.
To specify a transactionally-consistent restore point, please pause ScalarDL service as described in the [basic strategy](#basic-strategy-to-create-a-transactionally-consistent-backup).
## Restore Backups of Ledger Databases
To restore backups, you must follow the [Restore Backup](https://scalardb.scalar-labs.com/docs/latest/backup-restore#restore-a-backup) section.
You must stop ScalarDL Ledger services before restoring database backups and start the ScalarDL Ledger services after restoring the backups.
## Create/Restore Backups of Auditor Databases
When you use Auditor, you also need to take backups of Auditor databases in addition to Ledger databases.
To make the backups of Ledger and Auditor databases consistent, you always need to pause a Ledger cluster regardless of whether you use transactional databases or non-transactional databases for Ledger and Auditor.
Here is the steps to take backups:
1. Pause a Ledger cluster
1. Take backups of Ledger databases (as described above)
1. Take backups of Auditor databases (as described above)
1. Unpause the Ledger cluster
Note that, even if Ledger is paused, Auditor still accepts requests and updates its data (i.e., lock tables), however, the updated data is lazily recovered once Ledger is unpaused.
To reduce the lazy recovery overhead, it is always a good practice to take backups while there are no requests for ScalarDL.
We are planning to provide a more efficient scheme as future work.
When restoring backups, make sure you use the backups that are created in the same pause period.
You must stop ScalarDL Ledger and Auditor services before restoring database backups and start the ScalarDL Ledger and Auditor services after restoring the backups.
================================================
FILE: docs/compatibility.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL Compatibility Matrix
This document shows the compatibility of ScalarDL Ledger and Auditor versions among ScalarDL Java Client SDK versions and ScalarDB Cluster.
:::note
Versions are expressed as `x.y.z`, where `x` represents the major version, `y` represents the minor version, and `z` represents the patch version. This format follows [Semantic Versioning](https://semver.org/).
:::
## ScalarDL compatibility with client SDKs
| ScalarDL Ledger/Auditor version | ScalarDL Java Client SDK version |
|:--------------------------------|:---------------------------------|
| 3.13 | 3.10 - 3.13 |
| 3.12 | 3.10 - 3.12 |
| 3.11 | 3.10 - 3.11 |
| 3.10 | 3.10 |
:::note
- The client tools ([ScalarDL Client Command](./scalardl-command-reference.mdx) and [ScalarDL Schema Loader](./schema-loader.mdx)), and the Java Client SDKs for [ScalarDL HashStore](./getting-started-hashstore.mdx) and [ScalarDL TableStore](./getting-started-tablestore.mdx) are equivalent to the ScalarDL Java Client SDK, so the same compatibility rules apply to each of them.
- When you create a new deployment of ScalarDL, using the same version of ScalarDL Schema Loader as the version of ScalarDL is recommended.
- When you upgrade the minor or patch version of ScalarDL, basically, you don't need to update the existing schemas. In other words, basically, you don't need to re-run ScalarDL Schema Loader when you upgrade a minor or patch version of ScalarDL.
- If you use a new feature that ScalarDL provides in a new minor version, you may need to use the same or a later version of the client tools or re-create (or update) existing schemas. For details, please refer to the relevant documentation about each feature.
- For Scalar Admin and Scalar Admin for Kubernetes, using the latest versions of these tools is recommended to ensure compatibility with the version of ScalarDL that you are using.
:::
### Version skew policy
- If the **major** versions are different between ScalarDL and the client SDK, they are **not** compatible and are **not** supported.
- If the **major** versions are the same and the **minor** versions are different between ScalarDL and the client SDK, the version of ScalarDL must be greater than or equal to the client SDK version. For example:
- **Supported:** Combination of ScalarDL 3.13 and client SDK 3.11
- **Not supported:** Combination of ScalarDL 3.11 and client SDK 3.13
- If the **major** versions and the **minor** versions are the same, you can use different **patch** versions between ScalarDL and the client SDK. For example:
- **Supported:** Combination of ScalarDL 3.13.2 and client SDK 3.13.0
- **Supported:** Combination of ScalarDL 3.13.0 and client SDK 3.13.2
## ScalarDL compatibility with ScalarDB Cluster
If you use ScalarDB Cluster with ScalarDL, you can use the following combinations of versions.
| ScalarDL version | ScalarDB Cluster version |
|:-----------------|:--------------------------------------------------------------|
| 3.13 | 3.17 or later minor (3.X) version (like 3.17, 3.18, and 3.19) |
| 3.12 | 3.16 or later minor (3.X) version (like 3.16, 3.17, and 3.18) |
| 3.11 | 3.15 or later minor (3.X) version (like 3.15, 3.16, and 3.17) |
| 3.10 | 3.14 or later minor (3.X) version (like 3.14, 3.15, and 3.16) |
================================================
FILE: docs/configurations.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL Configurations
import JavadocLink from '/src/theme/JavadocLink.js';
This page describes the following available configurations for ScalarDL:
- [Ledger configurations](#ledger-configurations)
- [Auditor configurations](#auditor-configurations)
- [Client configurations](#client-configurations)
## Ledger configurations
You can configure several settings for the Ledger server, such as service port settings, authentication settings, and TLS settings.
### `auditor.cert_holder_id` (Deprecated)
- **Field:** `scalar.dl.ledger.auditor.cert_holder_id`
- **Description:** Auditor certificate holder ID. This field is used to identify the certificate holder for the Auditor.
- **Default value:** `auditor`
:::note
This configuration is deprecated and will be deleted in release 5.0.0 since Ledger-Auditor authentication will use HMAC only. For more details about authentication, see the [ScalarDL Authentication Guide](./authentication.mdx).
:::
### `auditor.cert_version` (Deprecated)
- **Field:** `scalar.dl.ledger.auditor.cert_version`
- **Description:** Auditor certificate version. This field specifies the version of the Auditor certificate.
- **Default value:** `1`
:::note
This configuration is deprecated and will be deleted in release 5.0.0 since Ledger-Auditor authentication will use HMAC only. For more details about authentication, see the [ScalarDL Authentication Guide](./authentication.mdx).
:::
### `auditor.enabled`
- **Field:** `scalar.dl.ledger.auditor.enabled`
- **Description:** A flag to enable Auditor. This field determines whether the Auditor is enabled.
- **Default value:** `false`
### `authentication.hmac.cipher_key`
- **Field:** `scalar.dl.ledger.authentication.hmac.cipher_key`
- **Description:** A cipher key used to encrypt and decrypt the HMAC secret keys of client entities. This field is used to specify the cipher key for HMAC authentication.
- **Default value:** empty (Optional)
### `authentication.method`
- **Field:** `scalar.dl.ledger.authentication.method`
- **Description:** The authentication method for clients and Ledger servers. `digital-signature` or `hmac` can be specified.
- **Default value:** `digital-signature` (Optional)
### `direct_asset_access.enabled`
- **Field:** `scalar.dl.ledger.direct_asset_access.enabled`
- **Description:** A flag to access the asset table directly without going through `asset_metadata`. This field determines whether direct access to the asset table is enabled.
- **Default value:** `false`
### `executable_contracts`
- **Field:** `scalar.dl.ledger.executable_contracts`
- **Description:** Binary names of contracts that can be executed. This field specifies the binary names of executable contracts.
- **Default value:** empty
### `function.enabled`
- **Field:** `scalar.dl.ledger.function.enabled`
- **Description:** A flag to enable function for mutable database. This field determines whether the function for mutable database is enabled.
- **Default value:** `true`
### `function.non_privileged_port_registration.enabled`
- **Field:** `scalar.dl.ledger.function.non_privileged_port_registration.enabled`
- **Description:** A flag to enable function registration via the non-privileged port. When set to `true`, tenants can register functions through the non-privileged port.
- **Default value:** `false`
### `function.non_privileged_port_registration.overwrite.enabled`
- **Field:** `scalar.dl.ledger.function.non_privileged_port_registration.overwrite.enabled`
- **Description:** A flag to allow overwriting an existing function when registering via the non-privileged port. When set to `true`, tenants can overwrite existing functions through the non-privileged port.
- **Default value:** `false`
### `name`
- **Field:** `scalar.dl.ledger.name`
- **Description:** Name of the ledger. This field specifies the name of the ledger.
- **Default value:** `Scalar Ledger` (Optional)
### `namespace`
- **Field:** `scalar.dl.ledger.namespace`
- **Description:** Namespace of ledger tables. This field specifies the namespace of the ledger tables.
- **Default value:** `scalar` (Optional)
### `proof.enabled`
- **Field:** `scalar.dl.ledger.proof.enabled`
- **Description:** A flag to enable asset proof that is used to verify assets. This field determines whether asset proof is enabled.
- **Default value:** `false`
### `proof.private_key_path`
- **Field:** `scalar.dl.ledger.proof.private_key_path`
- **Description:** The path of a private key file in PEM format. This field specifies the path of the private key file in PEM format.
- **Default value:** empty
### `proof.private_key_pem`
- **Field:** `scalar.dl.ledger.proof.private_key_pem`
- **Description:** PEM-encoded private key data. This field specifies the PEM-encoded private key data.
- **Default value:** empty
### `server.admin_port`
- **Field:** `scalar.dl.ledger.server.admin_port`
- **Description:** Server admin port. This field specifies the server admin port.
- **Default value:** `50053`
### `server.decommissioning_duration_secs`
- **Field:** `scalar.dl.ledger.server.decommissioning_duration_secs`
- **Description:** Decommissioning duration where the servers are running but returning `NOT_SERVING` to a gRPC health check request. This field specifies the decommissioning duration.
- **Default value:** `30 seconds` (Optional)
### `server.grpc.max_inbound_message_size`
- **Field:** `scalar.dl.ledger.server.grpc.max_inbound_message_size`
- **Description:** The maximum message size allowed for a single gRPC frame. This field specifies the maximum message size for a single gRPC frame.
- **Default value:** empty (Optional)
### `server.grpc.max_inbound_metadata_size`
- **Field:** `scalar.dl.ledger.server.grpc.max_inbound_metadata_size`
- **Description:** The maximum size of metadata allowed to be received. This field specifies the maximum size of metadata allowed to be received.
- **Default value:** `8 KiB` (Optional)
### `server.port`
- **Field:** `scalar.dl.ledger.server.port`
- **Description:** Server port. This field specifies the server port.
- **Default value:** `50051`
### `server.privileged_port`
- **Field:** `scalar.dl.ledger.server.privileged_port`
- **Description:** Server privileged port. This field specifies the server privileged port.
- **Default value:** `50052`
### `server.prometheus_exporter_port`
- **Field:** `scalar.dl.ledger.server.prometheus_exporter_port`
- **Description:** Prometheus exporter port. This field specifies the Prometheus exporter port.
- **Default value:** `8080`
### `server.tls.cert_chain_path`
- **Field:** `scalar.dl.ledger.server.tls.cert_chain_path`
- **Description:** Certificate chain file used for TLS communication. This field specifies the certificate chain file used for TLS communication.
- **Default value:** empty
### `server.tls.enabled`
- **Field:** `scalar.dl.ledger.server.tls.enabled`
- **Description:** A flag to enable TLS between clients and servers. This field determines whether TLS is enabled between clients and servers.
- **Default value:** `false`
### `server.tls.private_key_path`
- **Field:** `scalar.dl.ledger.server.tls.private_key_path`
- **Description:** Private key file used for TLS communication. This field specifies the private key file used for TLS communication.
- **Default value:** empty
### `servers.authentication.hmac.secret_key`
- **Field:** `scalar.dl.ledger.servers.authentication.hmac.secret_key`
- **Description:** A secret key of HMAC for the authentication of messages between (Ledger and Auditor) servers. This field specifies the secret key of HMAC for authentication between Ledger and Auditor servers.
- **Default value:** empty
### `tx_state_management.enabled`
- **Field:** `scalar.dl.ledger.tx_state_management.enabled`
- **Description:** A flag to manage transaction states by Ledger. This field determines whether transaction state management is enabled by the Ledger.
- **Default value:** `false`
## Auditor configurations
You can configure several settings for the Auditor server, such as service port settings, authentication settings, and TLS settings.
### `authentication.hmac.cipher_key`
- **Field:** `scalar.dl.auditor.authentication.hmac.cipher_key`
- **Description:** A cipher key used to encrypt and decrypt the HMAC secret keys of client entities. This is used only when `scalar.dl.auditor.authentication.method` is set to `hmac`.
- **Default value:** empty (Optional)
### `authentication.method`
- **Field:** `scalar.dl.auditor.authentication.method`
- **Description:** The authentication method for clients and Auditor servers. `digital-signature` or `hmac` can be specified. This must be consistent with the Ledger configuration.
- **Default value:** `digital-signature` (Optional)
### `authorization.credential`
- **Field:** `scalar.dl.auditor.authorization.credential`
- **Description:** An authorization credential (e.g., Bearer token).
- **Default value:** empty (Optional)
### `cert_holder_id` (Deprecated)
- **Field:** `scalar.dl.auditor.cert_holder_id`
- **Description:** The holder ID of a certificate. This field is used to identify the certificate holder for the Auditor.
- **Default value:** `auditor`
:::note
This configuration is deprecated and will be deleted in release 5.0.0 since Ledger-Auditor authentication will use HMAC only. For more details about authentication, see the [ScalarDL Authentication Guide](./authentication.mdx).
:::
### `cert_version` (Deprecated)
- **Field:** `scalar.dl.auditor.cert_version`
- **Description:** The version of the certificate. This field specifies the version of the Auditor certificate.
- **Default value:** `1`
:::note
This configuration is deprecated and will be deleted in release 5.0.0 since Ledger-Auditor authentication will use HMAC only. For more details about authentication, see the [ScalarDL Authentication Guide](./authentication.mdx).
:::
### `grpc.deadline_duration_millis`
- **Field:** `scalar.dl.auditor.grpc.deadline_duration_millis`
- **Description:** Deadline duration in milliseconds for each gRPC request.
- **Default value:** empty (Optional)
### `grpc.max_inbound_message_size`
- **Field:** `scalar.dl.auditor.grpc.max_inbound_message_size`
- **Description:** The maximum message size allowed for a single gRPC frame. If an inbound message larger than this limit is received, it will not be processed, and the RPC will fail with `RESOURCE_EXHAUSTED`.
- **Default value:** empty (Optional)
### `grpc.max_inbound_metadata_size`
- **Field:** `scalar.dl.auditor.grpc.max_inbound_metadata_size`
- **Description:** The maximum size of metadata allowed to be received. This is cumulative size of the entries with some overhead, as defined for HTTP/2's SETTINGS_MAX_HEADER_LIST_SIZE.
- **Default value:** `8 KiB` (Optional)
### `ledger.cert_holder_id` (Deprecated)
- **Field:** `scalar.dl.auditor.ledger.cert_holder_id`
- **Description:** The holder ID of the certificate of Ledger. This field is used to identify the certificate holder for the Ledger.
- **Default value:** `ledger`
:::note
This configuration is deprecated and will be deleted in release 5.0.0 since Ledger-Auditor authentication will use HMAC only. For more details about authentication, see the [ScalarDL Authentication Guide](./authentication.mdx).
:::
### `ledger.cert_version` (Deprecated)
- **Field:** `scalar.dl.auditor.ledger.cert_version`
- **Description:** The version of the certificate. This field specifies the version of the Ledger certificate.
- **Default value:** `1`
:::note
This configuration is deprecated and will be deleted in release 5.0.0 since Ledger-Auditor authentication will use HMAC only. For more details about authentication, see the [ScalarDL Authentication Guide](./authentication.mdx).
:::
### `ledger.host`
- **Field:** `scalar.dl.auditor.ledger.host`
- **Description:** Hostname or IP address of the Ledger server.
- **Default value:** `localhost`
### `ledger.port`
- **Field:** `scalar.dl.auditor.ledger.port`
- **Description:** Port number of the Ledger server.
- **Default value:** `50051`
### `ledger.privileged_port`
- **Field:** `scalar.dl.auditor.ledger.privileged_port`
- **Description:** Privileged port number of the Ledger server.
- **Default value:** `50052`
### `name`
- **Field:** `scalar.dl.auditor.name`
- **Description:** Name of the auditor.
- **Default value:** `Scalar Auditor` (Optional)
### `namespace`
- **Field:** `scalar.dl.auditor.namespace`
- **Description:** Namespace of auditor tables.
- **Default value:** `auditor` (Optional)
### `private_key_path`
- **Field:** `scalar.dl.auditor.private_key_path`
- **Description:** The path to the private key file in PEM format. This or `scalar.dl.auditor.private_key_pem` is used to sign certificates with a digital signature. When `scalar.dl.auditor.servers.authentication.hmac.secret_key` is empty, the signature is also used by Ledger to authenticate the corresponding certificate from Auditor.
- **Default value:** empty (Optional)
### `private_key_pem`
- **Field:** `scalar.dl.auditor.private_key_pem`
- **Description:** PEM-encoded private key data. This or `scalar.dl.auditor.private_key_path` is used to sign certificates with a digital signature. When `scalar.dl.auditor.servers.authentication.hmac.secret_key` is empty, the signature is also used by Ledger to authenticate the corresponding certificate from Auditor.
- **Default value:** empty (Optional)
### `server.admin_port`
- **Field:** `scalar.dl.auditor.server.admin_port`
- **Description:** Server admin port.
- **Default value:** `40053`
### `server.decommissioning_duration_secs`
- **Field:** `scalar.dl.auditor.server.decommissioning_duration_secs`
- **Description:** Decommissioning duration in seconds where the servers are running but returning `NOT_SERVING` to a gRPC health check request.
- **Default value:** `30`
### `server.grpc.max_inbound_message_size`
- **Field:** `scalar.dl.auditor.server.grpc.max_inbound_message_size`
- **Description:** The maximum message size allowed for a single gRPC frame.
- **Default value:** empty (Optional)
### `server.grpc.max_inbound_metadata_size`
- **Field:** `scalar.dl.auditor.server.grpc.max_inbound_metadata_size`
- **Description:** The maximum size of metadata allowed to be received.
- **Default value:** `8 KiB` (Optional)
### `server.port`
- **Field:** `scalar.dl.auditor.server.port`
- **Description:** Server port.
- **Default value:** `40051`
### `server.privileged_port`
- **Field:** `scalar.dl.auditor.server.privileged_port`
- **Description:** Server privileged port.
- **Default value:** `40052`
### `server.prometheus_exporter_port`
- **Field:** `scalar.dl.auditor.server.prometheus_exporter_port`
- **Description:** Prometheus exporter port.
- **Default value:** `8080`
### `server.tls.cert_chain_path`
- **Field:** `scalar.dl.auditor.server.tls.cert_chain_path`
- **Description:** Path to the certificate chain file used for TLS communication.
- **Default value:** empty
### `server.tls.enabled`
- **Field:** `scalar.dl.auditor.server.tls.enabled`
- **Description:** A flag to enable TLS communication between clients and servers.
- **Default value:** `false`
### `server.tls.private_key_path`
- **Field:** `scalar.dl.auditor.server.tls.private_key_path`
- **Description:** Path to the private key file used for TLS communication.
- **Default value:** empty
### `servers.authentication.hmac.secret_key`
- **Field:** `scalar.dl.auditor.servers.authentication.hmac.secret_key`
- **Description:** A secret key of HMAC for the authentication of messages between Ledger and Auditor servers.
- **Default value:** empty (Optional)
### `tls.ca_root_cert_path`
- **Field:** `scalar.dl.auditor.tls.ca_root_cert_path`
- **Description:** Path to the custom CA root certificate for TLS communication.
- **Default value:** empty
### `tls.ca_root_cert_pem`
- **Field:** `scalar.dl.auditor.tls.ca_root_cert_pem`
- **Description:** PEM-encoded custom CA root certificate for TLS communication.
- **Default value:** empty
### `tls.enabled`
- **Field:** `scalar.dl.auditor.tls.enabled`
- **Description:** A flag to enable TLS communication.
- **Default value:** `false`
### `tls.override_authority`
- **Field:** `scalar.dl.auditor.tls.override_authority`
- **Description:** Custom authority for TLS communication.
- **Default value:** empty
## Client configurations
You can configure several settings for clients, such as Ledger server and Auditor server settings, authentication settings, and TLS settings.
### `auditor.authorization.credential`
- **Field:** `scalar.dl.client.auditor.authorization.credential`
- **Description:** An authorization credential for Auditor.
- **Default value:** empty (Optional)
### `auditor.enabled`
- **Field:** `scalar.dl.client.auditor.enabled`
- **Description:** A flag to enable Auditor.
- **Default value:** `false`
### `auditor.host`
- **Field:** `scalar.dl.client.auditor.host`
- **Description:** A hostname or IP address of the Auditor.
- **Default value:** `localhost`
### `auditor.linearizable_validation.contract_id`
- **Field:** `scalar.dl.client.auditor.linearizable_validation.contract_id`
- **Description:** The ID of the ValidateLedger contract.
- **Default value:** `validate-ledger`
### `auditor.port`
- **Field:** `scalar.dl.client.auditor.port`
- **Description:** A port number of the Auditor.
- **Default value:** `40051`
### `auditor.privileged_port`
- **Field:** `scalar.dl.client.auditor.privileged_port`
- **Description:** A port number of the Auditor for privileged services.
- **Default value:** `40052`
### `auditor.tls.ca_root_cert_path`
- **Field:** `scalar.dl.client.auditor.tls.ca_root_cert_path`
- **Description:** A custom CA root certificate (file path) for TLS communication for Auditor.
- **Default value:** empty
### `auditor.tls.ca_root_cert_pem`
- **Field:** `scalar.dl.client.auditor.tls.ca_root_cert_pem`
- **Description:** A custom CA root certificate (PEM data) for TLS communication for Auditor.
- **Default value:** empty
### `auditor.tls.enabled`
- **Field:** `scalar.dl.client.auditor.tls.enabled`
- **Description:** A flag to enable TLS communication for Auditor.
- **Default value:** `false`
### `auditor.tls.override_authority`
- **Field:** `scalar.dl.client.auditor.tls.override_authority`
- **Description:** A custom authority for TLS communication for Auditor.
- **Default value:** empty
### `authentication.method`
- **Field:** `scalar.dl.client.authentication.method`
- **Description:** The authentication method for clients and Ledger/Auditor servers. `digital-signature` or `hmac` can be specified. This must be consistent with the Ledger/Auditor configuration.
- **Default value:** `digital-signature` (Optional)
### `authorization.credential`
- **Field:** `scalar.dl.client.authorization.credential`
- **Description:** An authorization credential for Ledger.
- **Default value:** empty (Optional)
### `cert_holder_id` (Deprecated)
- **Field:** `scalar.dl.client.cert_holder_id`
- **Description:** The holder ID of a certificate. This field is used to identify the certificate holder for the client.
- **Default value:** empty
:::note
This configuration is deprecated and will be deleted in release 5.0.0. Use `scalar.dl.client.entity.id` instead. If both configurations are specified, `scalar.dl.client.entity.id` will be used.
:::
### `cert_path` (Deprecated)
- **Field:** `scalar.dl.client.cert_path`
- **Description:** The path of a certificate file in PEM format. This field specifies the path to the client certificate file.
- **Default value:** empty
:::note
This configuration is deprecated and will be deleted in release 5.0.0. Use `scalar.dl.client.entity.identity.digital_signature.cert_path` instead.
:::
### `cert_pem` (Deprecated)
- **Field:** `scalar.dl.client.cert_pem`
- **Description:** PEM-encoded certificate data. This field specifies the PEM-encoded certificate data for the client.
- **Default value:** empty
:::note
This configuration is deprecated and will be deleted in release 5.0.0. Use `scalar.dl.client.entity.identity.digital_signature.cert_pem` instead.
:::
### `cert_version` (Deprecated)
- **Field:** `scalar.dl.client.cert_version`
- **Description:** The version of the certificate. This field specifies the version of the client certificate.
- **Default value:** `1`
:::note
This configuration is deprecated and will be deleted in release 5.0.0. Use `scalar.dl.client.entity.identity.digital_signature.cert_version` instead.
:::
### `entity.id`
- **Field:** `scalar.dl.client.entity.id`
- **Description:** A unique ID of a requester (e.g., a user or a device).
- **Default value:** empty
### `entity.identity.digital_signature.cert_path`
- **Field:** `scalar.dl.client.entity.identity.digital_signature.cert_path`
- **Description:** The path of a certificate file in PEM format, which is required if `scalar.dl.client.entity.identity.digital_signature.cert_pem` is empty.
- **Default value:** empty
### `entity.identity.digital_signature.cert_pem`
- **Field:** `scalar.dl.client.entity.identity.digital_signature.cert_pem`
- **Description:** PEM-encoded certificate data. Required if `scalar.dl.client.entity.identity.digital_signature.cert_path` is empty.
- **Default value:** empty
### `entity.identity.digital_signature.cert_version`
- **Field:** `scalar.dl.client.entity.identity.digital_signature.cert_version`
- **Description:** The version of the certificate.
- **Default value:** `1` (Optional)
### `entity.identity.digital_signature.private_key_path`
- **Field:** `scalar.dl.client.entity.identity.digital_signature.private_key_path`
- **Description:** The path of a private key file in PEM format, which corresponds to the specified certificate. Required if `scalar.dl.client.entity.identity.digital_signature.private_key_pem` is empty.
- **Default value:** empty
### `entity.identity.digital_signature.private_key_pem`
- **Field:** `scalar.dl.client.entity.identity.digital_signature.private_key_pem`
- **Description:** PEM-encoded private key data. Required if `scalar.dl.client.entity.identity.digital_signature.private_key_path` is empty.
- **Default value:** empty
### `entity.identity.hmac.secret_key`
- **Field:** `scalar.dl.client.entity.identity.hmac.secret_key`
- **Description:** A secret key for HMAC.
- **Default value:** empty
### `entity.identity.hmac.secret_key_version`
- **Field:** `scalar.dl.client.entity.identity.hmac.secret_key_version`
- **Description:** The version of the HMAC key.
- **Default value:** empty (Optional)
### `grpc.deadline_duration_millis`
- **Field:** `scalar.dl.client.grpc.deadline_duration_millis`
- **Description:** A deadline duration for each request.
- **Default value:** empty (Optional)
### `grpc.max_inbound_message_size`
- **Field:** `scalar.dl.client.grpc.max_inbound_message_size`
- **Description:** The maximum message size allowed for a single gRPC frame.
- **Default value:** empty (Optional)
### `grpc.max_inbound_metadata_size`
- **Field:** `scalar.dl.client.grpc.max_inbound_metadata_size`
- **Description:** The maximum size of metadata allowed to be received.
- **Default value:** empty (Optional)
### `mode`
- **Field:** `scalar.dl.client.mode`
- **Description:** A client mode (CLIENT or INTERMEDIARY).
- **Default value:** empty (Optional)
### `private_key_path` (Deprecated)
- **Field:** `scalar.dl.client.private_key_path`
- **Description:** The path of a private key file in PEM format. This field specifies the path to the client private key file.
- **Default value:** empty
:::note
This configuration is deprecated and will be deleted in release 5.0.0. Use `scalar.dl.client.entity.identity.digital_signature.private_key_path` instead.
:::
### `private_key_pem` (Deprecated)
- **Field:** `scalar.dl.client.private_key_pem`
- **Description:** PEM-encoded private key data. This field specifies the PEM-encoded private key data for the client.
- **Default value:** empty
:::note
This configuration is deprecated and will be deleted in release 5.0.0. Use `scalar.dl.client.entity.identity.digital_signature.private_key_pem` instead.
:::
### `server.host`
- **Field:** `scalar.dl.client.server.host`
- **Description:** A hostname or IP address of the server.
- **Default value:** `localhost`
### `server.port`
- **Field:** `scalar.dl.client.server.port`
- **Description:** A port number of the server.
- **Default value:** `50051`
### `server.privileged_port`
- **Field:** `scalar.dl.client.server.privileged_port`
- **Description:** A port number of the server for privileged services.
- **Default value:** `50052`
### `tls.ca_root_cert_path`
- **Field:** `scalar.dl.client.tls.ca_root_cert_path`
- **Description:** A custom CA root certificate (file path) for TLS communication for Ledger.
- **Default value:** empty
### `tls.ca_root_cert_pem`
- **Field:** `scalar.dl.client.tls.ca_root_cert_pem`
- **Description:** A custom CA root certificate (PEM data) for TLS communication for Ledger.
- **Default value:** empty
### `tls.enabled`
- **Field:** `scalar.dl.client.tls.enabled`
- **Description:** A flag to enable TLS communication for Ledger.
- **Default value:** `false`
### `tls.override_authority`
- **Field:** `scalar.dl.client.tls.override_authority`
- **Description:** A custom authority for TLS communication for Ledger.
- **Default value:** empty
================================================
FILE: docs/data-modeling.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Model Your Data
import JavadocLink from '/src/theme/JavadocLink.js';
Data modeling (or in other words, organizing your data) is the process of conceptualizing and visualizing how data will be stored and used by identifying the patterns used to access data and the types of queries to be performed within business operations.
This page first explains the ScalarDL data model and then describes how to organize your data based on the data model.
## ScalarDL data model
The data model of ScalarDL is a kind of key-value model that abstracts a ledger as a set of assets, where each key acts as a unique identifier for an asset, and the value represents the data of the asset. The following diagram shows the objects in ScalarDL with some examples of the assets. This section first explains what objects ScalarDL defines and then describes how to locate the objects.

### Objects in ScalarDL
The ScalarDL data model has several objects.
#### Ledger
The ledger in ScalarDL is abstracted as a set of assets.
#### Namespace
:::warning
The namespace feature is currently in Public Preview. The feature and related documentation are subject to change.
:::
A namespace is a logical grouping of assets within the ledger. Each namespace has a unique name and isolates the assets it contains from those in other namespaces.
ScalarDL provides a pre-configured default namespace named `default`. By default, assets are stored in and retrieved from this default namespace. You can also create other namespaces to organize assets based on your application requirements, such as separating assets by tenant, time period, or backend storage with different cost characteristics.
#### Asset
An asset can be arbitrary data but is more compatible to being viewed as a historical series of data. For example, assets can range from the tangible (real estate and hardware) to the intangible (contracts, intellectual property, and even audit trail logs as shown in the above diagram).
#### Asset record
An asset is composed of one or more asset records where each asset record is identified by an asset ID and an age. An asset record has data in any string format (typically JSON format) and several internal metadata to validate the authenticity of the record, such as a cryptographic hash. Asset records are read and written by a contract.
:::note
A contract is a Java program written for implementing single business logic and must be registered with the ledger in advance to be called. You can create, update, or get an asset by using a contract. When creating or updating the asset, a new age (that is, a new version) of the asset record is added in a tamper-evident manner.
:::
#### Mutable database
Assets managed by contracts are tamper evident and append only, so their data structure is limited in modeling various applications. Moreover, assets cannot be deleted to guarantee tamper evidence. To compensate for these limitations, you can use a mutable database abstraction for more powerful and easy-to-use modeling capabilities.
A mutable database corresponds to a ScalarDB namespace, which is a collection of tables. A table is a collection of partitions, and a partition is a collection of mutable records. For details on the ScalarDB data model, see [ScalarDB data model](https://scalardb.scalar-labs.com/docs/latest/data-modeling#scalardb-data-model).
#### Mutable record
A mutable record is a set of columns, which are fundamental data elements. Mutable records are read, written, or deleted by using a function.
:::note
A function is also a Java program written for implementing single business logic and must be registered with the ledger in advance to be called. You can create, update, get, or delete mutable records by using a subset of ScalarDB APIs through the function, which is atomically executed with a contract.
:::
### How to locate asset records
This section discusses how to locate asset records in the ledger.
#### Get the latest asset record
You can get the latest asset record by specifying an asset ID.
#### Scan asset records of an asset
You can scan multiple records of an asset (in other words, histories of an asset) by specifying an asset ID and age. Specifically, the asset ID and age can be specified in the `AssetFilter` class. For details about the specification, see the page in the Javadoc.
### How to locate mutable records
You can locate mutable records in ScalarDB tables by using keys like the partition key and clustering key. For details, see [How to locate records](https://scalardb.scalar-labs.com/docs/latest/data-modeling#how-to-locate-records) in the ScalarDB data model.
## How to organize your data
Since ScalarDL has a different data model compared to the relational data model, there is a basic principle and a few best practices for data modeling.
### Query-driven data modeling
In relational databases, data is organized in normalized tables, with foreign keys used to reference related data in other tables. The queries that the application will make are structured by the tables, and the related data is queried as table joins.
Since ScalarDL does not provide the join feature, data modeling should be more query driven, like NoSQL databases. The data access patterns and application queries should determine the structure and organization of assets.
### Best practices
This section describes a few best practices for modeling your data.
#### Add prefixes to asset IDs to deal with multiple entities
Since ScalarDL only provides a single asset ID space, you might need to manage several asset types by yourself, by adding prefixes to asset IDs if you want to deal with multiple entities.
For example, if you manage audit trail log files and users who can verify the authenticity of the files, you can deal with those two entities separately by adding prefixes into asset IDs like `log_` and `user_`.
#### Create indexes to query assets flexibly
You might often want to search for assets based on their various attributes. In those cases, you have two options to achieve such flexibility when searching:
- **Option 1:** Prepare a kind of index table as an asset so that each index asset has corresponding asset IDs as pointers. Although this approach introduces performance overheads to manage the index on the ledger, you can achieve strictly secure data management since the index information is also preserved in a tamper-evident manner.
- **Option 2:** Use a ScalarDB table as an index of assets. When putting an asset record in the ledger, you can atomically update a ScalarDB table with secondary indexes by using a function so that a record in the ScalarDB table points to the asset or asset record. Although this approach is more flexible and efficient than the first approach, you should note that the index information could be tampered with and consider whether this is acceptable in your use cases.
#### Determine the scope of tamper-evident assets
As described above, you can organize your data, both tamper evident and non-tamper evident, by using contracts and functions. How you choose to manage certain data depends on your use case and requirements. Thus, you should clarify what data you want to guarantee authenticity for.
For example, if you manage a list or index of assets in non-tamper-evident ScalarDB tables, you must understand the risks when those assets are tampered with. More specifically, suppose you have a list of IDs of audit trail log files whose contents are managed in ScalarDL in a tamper-evident manner. If losing the list due to malicious behavior is not acceptable, it should also be managed in ScalarDL.
#### Manage asset records efficiently
Depending on the characteristics of your data and its access patterns, there are a few options for how you store the data in asset records.
A simple way to store data in an asset is to always store the latest state of the data in its entirety. However, this approach is sometimes inefficient from a storage cost perspective because, if a small part of the data is updated frequently, almost all the parts of the data are stored as duplicates in the asset records.
In such a case, you can choose to put only the differential data when updating the asset and merge all the asset records when you want to get the whole image of the latest data. Although this approach is efficient from a storage cost perspective, it affects query performance since it requires scanning all asset records. To limit the effects of this trade-off, creating a snapshot at some point in time is also an option so that you do not have to scan all asset records every time. You can see how the predefined contracts used internally by HashStore for collection authenticity management follow this design pattern in the [source code](https://github.com/scalar-labs/scalardl/tree/master/generic-contracts/src/main/java/com/scalar/dl/genericcontracts/collection).
================================================
FILE: docs/deploy-local-environment-overview.mdx
================================================
---
tags:
- Enterprise
displayed_sidebar: docsEnglish
---
# Deploy ScalarDL in Your Local Kubernetes Environment
In this sub-category, you can follow guides to help you become more familiar with deploying ScalarDL in your local Kubernetes environment by using Helm Charts.
- **Using only ScalarDL Ledger?:** See [Deploy ScalarDL Ledger Locally](helm-charts/getting-started-scalardl-ledger.mdx).
- **Using both ScalarDL Ledger and ScalarDL Auditor?:** See [Deploy ScalarDL Auditor Locally](helm-charts/getting-started-scalardl-auditor.mdx).
================================================
FILE: docs/deploy-managed-kubernetes-environment-overview.mdx
================================================
---
tags:
- Enterprise
displayed_sidebar: docsEnglish
---
# Deploy ScalarDL in a Cloud-Based Kubernetes Environment
In this sub-category, you can follow guides to help you become more familiar with deploying ScalarDL in managed, cloud-based Kubernetes environments by using Helm Charts.
## Deploy ScalarDL on AWS
- **Using only ScalarDL Ledger?:** See [Deploy ScalarDL Ledger on Amazon EKS](scalar-kubernetes/ManualDeploymentGuideScalarDLOnEKS.mdx).
- **Using both ScalarDL Ledger and ScalarDL Auditor?:** See [Deploy ScalarDL Ledger and ScalarDL Auditor on Amazon EKS](scalar-kubernetes/ManualDeploymentGuideScalarDLAuditorOnEKS.mdx)
## Deploy ScalarDL on Azure
- **Using only ScalarDL Ledger?:** See [Deploy ScalarDL Ledger on Microsoft AKS](scalar-kubernetes/ManualDeploymentGuideScalarDLOnAKS.mdx).
- **Using both ScalarDL Ledger and ScalarDL Auditor?:** See [Deploy ScalarDL Ledger and ScalarDL Auditor on Microsoft AKS](scalar-kubernetes/ManualDeploymentGuideScalarDLAuditorOnAKS.mdx).
================================================
FILE: docs/deploy-overview.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Deploy Overview
In this category, you can follow guides to help you become more familiar with deploying ScalarDL in local and cloud-based Kubernetes environments.
## Deploy ScalarDL in your local Kubernetes environment
In this sub-category, you can learn how to deploy ScalarDL in your local Kubernetes environment. The primary focus of this sub-category is learning to use Scalar Helm Charts. Because of this, you will deploy a particular database (PostgreSQL) in your local environment.
## Deploy ScalarDL in a cloud-based Kubernetes environment
In this sub-category, you can learn how to deploy ScalarDL in a cloud-based Kubernetes environment. This sub-category describes how to use Scalar Helm Charts and other steps that are required to run ScalarDL in a cloud-based Kubernetes environment.
================================================
FILE: docs/design.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL Design Document
This design document briefly explains the design and implementation of ScalarDL. For the background and objectives of ScalarDL, see [ScalarDL Overview](overview.mdx).
## Design goals
The primary design goals of ScalarDL are to achieve both high tamper evidence of data and high performance scalability. ScalarDL provides ACID compliance, exact finality, linearizable consistency, and high availability. The performance of ScalarDL is highly dependent on the underlying database performance. However, the performance can be increased with minimal effort by replacing the underlying database with one that is suitable for your needs because of the loosely coupled architecture of ScalarDL. Ease of use and simplicity are also part of the primary design goals since they are the keys to making ScalarDL scalable.
## Fault model
ScalarDL inherits the standard assumptions of prior work that deals with Byzantine faults.[^1] As such, ScalarDL assumes that Byzantine-faulty nodes (for example, the ledger component) behave arbitrarily. In other words, there are no assumptions about the behavior of a fault.
## Data model
ScalarDL abstracts data as a set of assets. An asset can be arbitrary data but is more compatible to being viewed as a historical series of data. For example, assets can range from the tangible (real estate and hardware) to the intangible (contracts and intellectual property).
An asset is composed of one or more asset records where each asset record is identified by an asset ID and an age. An asset record with age `M` has a cryptographic hash of the previous asset record with age `M-1`, forming a hash-chain, so that removing or updating an intermediate asset record may be detected by traversing the chain.
In addition, a chain structure exists between multiple assets. This chain is a relationship constructed by business or application logic, which is referred to as a "contract" in ScalarDL. For example, in a banking application, a payment sent from one account to another account would update both accounts, which would create such a relationship between assets.
## Contract
ScalarDL manages contracts (also known as a smart contracts) as digitally signed business logic. A contract and its arguments are digitally signed with the contract owner's private key and passed to ScalarDL. This mechanism allows the contract to be executed only by the owner and makes it possible for the system to detect malicious activity, such as data tampering.
Users can define arbitrary business logic in a contract by using interfaces, such as for reading and writing assets to and from the ledger. For example, in a bank application, creating accounts, depositing, withdrawing, and making payments can be written as a contract. For more details, see the [simple bank account application sample](applications/simple-bank-account/README.mdx).
## How and when ScalarDL detects Byzantine faults
The key to the Byzantine fault detection protocol of ScalarDL is that Ledger (primary servers) and Auditor (secondary servers) make an agreement on the partial ordering of transactions in a decentralized and concurrent way. The protocol comprises three phases: the ordering phase, the commit phase, and the validation phase.
1. In the ordering phase, Auditor first pre-orders a transaction given by a client partially on the basis of conflicts.
2. Next, in the commit phase, Ledger executes and commits the transaction that is ordered by Auditor.
3. Then, in the validation phase, Auditor validates the ordering result given by Ledger and executes the transaction.
The three-phase protocol makes both databases derive the same correct (strict serializable) states and results as long as both Ledger and Auditor are honest. If either is Byzantine faulty, for example, the records have been tampered, their states or results would diverge. When the divergence is observable outside of the database system, correct ScalarDL clients can detect it. In other words, ScalarDL detects a Byzantine fault only when the clients observe the divergence in the response from the database system. Therefore, ScalarDL does not detect the fault instantly, but it does guarantee that the clients will detect the fault when the diverged states are about to be used, minimizing the validation overheads.
## Further reading
For more details about the design and implementation of ScalarDL, see the following documents:
- **Speaker Deck presentation:** [ScalarDL Technical Overview](https://speakerdeck.com/scalar/scalar-dl-technical-overview)
In addition, the following materials were presented at the VLDB 2022 conference:
- **Speaker Deck presentation:** [ScalarDL: Scalable and Practical Byzantine Fault Detection for Transactional Database Systems](https://speakerdeck.com/scalar/scalar-dl-scalable-and-practical-byzantine-fault-detection-for-transactional-database-systems-vldb22)
- **Detailed paper:** [ScalarDL: Scalable and Practical Byzantine Fault Detection for Transactional Database Systems](https://www.vldb.org/pvldb/vol15/p1324-yamada.pdf)
[^1]: Leslie Lamport, Robert Shostak, Marshall Pease, The Byzantine Generals Problem, ACM Transactions on Programming Languages and Systems (TOPLAS), v.4 n.3, p.382-401, July 1982.
================================================
FILE: docs/develop-advanced-configurations-overview.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Advanced Configurations and Operations Overview
In this sub-category, you can learn how to set advanced configurations and perform advanced operations for ScalarDL.
For details on advanced configurations and operations, see the following:
- [ScalarDL Authentication Guide](authentication.mdx)
- [ScalarDL Benchmarking Tools](scalardl-benchmarks/README.mdx)
================================================
FILE: docs/develop-overview.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Develop Overview
In this category, you can follow guides to help you become more familiar with ScalarDL, specifically with how to write and run ScalarDL applications.
## Write Business Logic
In this sub-category, you can learn how to write business logic for a ScalarDL application.
For an overview of this sub-category, see [Write Business Logic Overview](develop-write-business-logic-overview.mdx).
## Write an Application
In this sub-category, you can learn how to write a ScalarDL application.
For an overview of this sub-category, see [Write an Application Overview](develop-write-an-application-overview.mdx).
## Run an Application
In this sub-category, you can learn how to run an application through ScalarDL.
For an overview of this sub-category, see [Run an Application Overview](develop-run-an-application-overview.mdx).
## Run Sample Applications
In this sub-category, you can learn how to run sample applications that take advantage of ScalarDL.
For an overview of this sub-category, see [Run Sample Applications Overview](develop-samples-overview.mdx).
## Advanced Configurations and Operations
In this sub-category, you can learn how to set advanced configurations and perform advanced operations for ScalarDL.
For an overview of this sub-category, see [Advanced Configurations and Operations Overview](develop-advanced-configurations-overview.mdx).
================================================
FILE: docs/develop-run-an-application-overview.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Run an Application Overview
In this sub-category, you can learn how to run an application through ScalarDL.
For details on how to run an application, see the following guides:
- [Run a ScalarDL Application Through ScalarDL Ledger](how-to-run-applications.mdx)
- [Run a ScalarDL Application Through ScalarDL Ledger and Auditor](how-to-run-applications-with-auditor.mdx)
================================================
FILE: docs/develop-samples-overview.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Run Sample Applications Overview
In this sub-category, you can learn how to run sample applications that take advantage of ScalarDL.
To set up and run a sample application, see the following guide:
- [A simple bank account application](applications/simple-bank-account/README.mdx)
================================================
FILE: docs/develop-write-an-application-overview.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Write an Application Overview
In this sub-category, you can learn how to write a ScalarDL application.
For details on how to write an application, see the following guides:
- [Write a ScalarDL Application with the HashStore Abstraction](./how-to-write-applications-with-hashstore.mdx)
- [Write a ScalarDL Application with the TableStore Abstraction](./how-to-write-applications-with-tablestore.mdx)
- [Write a ScalarDL Application with the Ledger Abstraction](./how-to-write-applications.mdx)
================================================
FILE: docs/develop-write-business-logic-overview.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Write Business Logic Overview
In this sub-category, you can learn how to write business logic for a ScalarDL application.
For details on how to write business logic, see the following guides:
- [Model Your Data](data-modeling.mdx)
- [A Guide on How to Write a Good Contract for ScalarDL](how-to-write-contract.mdx)
- [A Guide on How to Write Function for ScalarDL](how-to-write-function.mdx)
- [Manage Contract and Function Lifecycle](manage-contract-and-function-lifecycle.mdx)
================================================
FILE: docs/generic-contracts-reference.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Generic Contracts and Functions Reference Guide
:::tip
Although generic contracts were introduced in ScalarDL 3.10, HashStore, released in ScalarDL 3.12, provides a higher-level abstraction that wraps generic contracts. For most use cases, using HashStore is simpler and more efficient than using generic contracts directly. For details, see [Get Started with ScalarDL HashStore](./getting-started-hashstore.mdx) in the latest version of ScalarDL.
:::
This guide describes the specifications for generic contracts and functions.
## List of generic contracts and functions
- **Object management**
- [`object.Put`](#objectput-contract) contract: Put an object with the hash value of the object.
- [`object.PutToMutableDatabase`](#objectputtomutabledatabase-function) function: Put a mutable record in conjunction with the `object.Put` contract.
- [`object.Get`](#objectget-contract) contract: Get an object.
- [`object.Validate`](#objectvalidate-contract) contract: Validate hash values of an object.
- **Collection management**
- [`collection.Create`](#collectioncreate-contract) contract: Create a collection.
- [`collection.Add`](#collectionadd-contract) contract: Add IDs to a collection.
- [`collection.Remove`](#collectionremove-contract) contract: Remove IDs from a collection.
- [`collection.Get`](#collectionget-contract) contract: Get a collection.
- [`collection.GetHistory`](#collectiongethistory-contract) contract: Get a history of collection modification.
- [`collection.GetCheckpointInterval`](#collectiongetcheckpointinterval-contract) contract: Get a checkpoint interval.
## `object.Put` contract
Put an object ID with the hash value of the object. If the object already exists, the asset record will be updated. If not, the new asset record will be added.
### Inputs
Specify a JSON object that has the following fields as inputs.
| Field | Description |
|:-------------|:-------------------------------------------------------------|
| `object_id` | An ID of an object to put. |
| `hash_value` | A hash value of the specified object. |
| `metadata` | (Optional) A JSON object for storing additional information. |
### Outputs
A null value is returned if it is successful.
### Examples
```console
scalardl generic-contracts execute-contract --properties client.properties \
--contract-id object.Put \
--contract-argument '{"objct_id": "a.txt", "hash_value": "a3ae11", "metadata": {"note": "something"}}'
```
## `object.PutToMutableDatabase` function
Put a mutable record into a ScalarDB table in conjunction with the `object.Put` contract. If the record already exists, the record will be updated. If not, the new record will be added. Calling this function is optional.
### Inputs
Specify a JSON object that has the following fields as inputs.
| Field | Description |
|:-----------------|:-----------------------------------------------------|
| `namespace` | A string value for the namespace name. |
| `table` | A string value for the table name. |
| `partition_key` | An array of JSON objects for partition key columns. |
| `clustering_key` | An array of JSON objects for clustering key columns. |
| `columns` | An array of JSON objects for regular columns. |
Each column is a JSON object that has the following fields.
| Field | Description |
|:--------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `column_name` | A string value for the column name. |
| `value` | A JSON value. |
| `data_type` | A case-insensitive string value for the [data type that is supported in ScalarDB](https://scalardb.scalar-labs.com/docs/latest/schema-loader/#data-type-mapping-between-scalardb-and-other-databases). |
### Outputs
A null value is returned if it is successful.
### Examples
```console
scalardl generic-contracts execute-contract --properties client.properties \
--contract-id object.Put \
--contract-argument '{"object_id": "a.txt", "hash_value": "a3ae11"}' \
--function-id object.PutToMutableDatabase \
--function-argument '{...}'
```
For the function argument, see the following JSON object example.
```json
{
"namespace": "myns",
"table": "objects",
"partition_key": [
{ "column_name": "object_id", "value": "a.txt", "data_type": "TEXT" }
],
"clustering_key": [
{ "column_name": "version", "value": "1234aef", "data_type": "TEXT" }
],
"columns": [
{ "column_name": "status", "value": 3, "data_type": "INT" },
{ "column_name": "size", "value": 10.000, "data_type": "DOUBLE" },
{ "column_name": "timestamp", "value": 123456789, "data_type": "BIGINT" },
{ "column_name": "comment", "value": "hash-registered", "data_type": "TEXT" }
]
}
```
## `object.Get` contract
Get an object with the specified ID. If the specified object does not exist, a null value will be returned.
### Inputs
Specify a JSON object that has the following field as an input.
| Field | Description |
|:------------|:--------------------------------|
| `object_id` | An ID of an object to get. |
### Outputs
A JSON object that has the following fields is returned.
| Field | Description |
|:-------------|:----------------------------|
| `object_id` | An ID of the object. |
| `hash_value` | A hash value of the object. |
| `metadata` | A JSON object if any. |
### Examples
```console
scalardl generic-contracts execute-contract --properties client.properties \
--contract-id object.Get \
--contract-argument '{"objct_id": "a.txt"}'
Contract result:
{
"object_id" : "a.txt",
"hash_value" : "a3ae11",
"metadata" : {
"note" : "something"
}
}
```
## `object.Validate` contract
Validate if the specified hash values of an object are the same as the stored hash values of the object. By default, only the specified number of hash values are validated from the latest ones. By specifying the `all` option, you can also verify if the number of given versions matches the number of versions stored in ScalarDL.
### Inputs
Specify a JSON object that has the following fields as inputs.
| Field | Description |
|:------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `object_id` | An ID of an object to validate. |
| `versions` | A list of JSON objects that describe versions to verify, with a descending order from the latest to the oldest. Each JSON object has three properties: version_id, hash_value, and metadata (optional). |
| `options` | (Optional) A json object for specifying options. Available options:
`all`: boolean value to specify whether to verify all the ages in the ScalarDL asset and the number of ages.`verbose`: boolean value to specify whether to show detailed information for faulty versions. |
### Outputs
A JSON object that has the following fields is returned.
| Field | Description |
|:-------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------|
| `status` | The status of the object, either "correct" or "faulty". |
| `details` | The detailed message for the status of the object. |
| `faulty_versions` | An array of faulty version IDs by default or JSON objects of faulty versions when the `verbose` option is specified. |
| `corresponding_given_versions` | An array of JSON objects of given versions that does not match the ones in ScalarDL (only when the `verbose` option is specified). |
:::note
Each JSON object for `faulty_versions` and `corresponding_given_versions` has the same fields for the input version.
:::
### Examples
If all specified hash values are the same as the ones in Ledger, the following result is returned.
```console
scalardl generic-contracts execute-contract --properties client.properties \
--contract-id object.Validate \
--contract-argument \
'{"object_id": "a.txt",
"versions": [
{"version_id": "v5", "hash_value": "a3ae11", "metadata":{...}},
{"version_id": "v4", "hash_value": "ea21f5", "metadata":{...}},
{"version_id": "v3", "hash_value": "440f28", "metadata":{...}}
]
}'
Contract result:
{
"status" : "correct",
"details" : "The status is correct.",
"faulty_versions" : [ ]
}
```
If a different hash values is found, the following result is returned.
```console
scalardl generic-contracts execute-contract --properties client.properties \
--contract-id object.Validate \
--contract-argument \
'{"object_id": "a.txt",
"versions": [
{"version_id": "v5", "hash_value": "xxxx11", "metadata":{...}},
{"version_id": "v4", "hash_value": "ea21f5", "metadata":{...}},
{"version_id": "v3", "hash_value": "xxxx28", "metadata":{...}}
]
}'
Contract result:
{
"status" : "faulty",
"details" : "A faulty version is found.",
"faulty_versions" : [ "v5", "v3" ]
}
```
If the `verbose` option is specified and a different hash value and metadata are found, the following result is returned.
```console
scalardl generic-contracts execute-contract --properties client.properties \
--contract-id object.Validate \
--contract-argument \
'{"object_id": "a.txt",
"versions": [
{"version_id": "v5", "hash_value": "xxxx11", "metadata": { "note": "foo" }},
{"version_id": "v4", "hash_value": "ea21f5", "metadata": { "note": "bar" }},
{"version_id": "v3", "hash_value": "440f28", "metadata": { "note": "bug" }}
],
"options": {"all": true}
}'
Contract result:
{
"status": "faulty",
"details": "A faulty version is found.",
"faulty_versions" : [
{"version_id": "v5", "hash_value": "a3ae11", "metadata": { "note": "foo" }},
{"version_id": "v3", "hash_value": "440f28", "metadata": { "note": "baz" }}
]
"corresponding_given_versions" : [
{"version_id": "v5", "hash_value": "xxxx11", "metadata": { "note": "foo" }},
{"version_id": "v3", "hash_value": "440f28", "metadata": { "note": "bug" }} ]
}
```
If the `all` option is specified and the number of given versions are different from the number of versions stored in ScalarDL, the following result is returned.
```console
scalardl generic-contracts execute-contract --properties client.properties \
--contract-id object.Validate \
--contract-argument \
'{"object_id": "a.txt",
"versions": [
{"version_id": "v5", "hash_value": "a3ae11", "metadata":{...}},
{"version_id": "v4", "hash_value": "ea21f5", "metadata":{...}},
{"version_id": "v3", "hash_value": "440f28", "metadata":{...}}
],
"options": {"all": true}
}'
Contract result:
{
"status" : "faulty",
"details" : "The number of versions is mismatched.",
"faulty_versions" : [ ]
}
```
## `collection.Create` contract
Create a collection, which is a set of IDs. You can manage arbitrary IDs, for example, a set of object IDs to be audited, a set of collection IDs, or a set of users.
### Inputs
Specify a JSON object that has the following fields as inputs.
| Field | Description |
|:----------------|:---------------------------------|
| `collection_id` | An ID of a collection to create. |
| `object_ids` | An array of string values. |
### Outputs
A null value is returned if it is successful.
### Examples
```console
scalardl generic-contracts execute-contract --properties client.properties \
--contract-id collection.Create \
--contract-argument '{"collection_id": "audit_set", "object_ids": ["a.txt"]}'
```
## `collection.Add` contract
Add IDs to a collection. Typically, the IDs are for objects and collections managed by the generic contracts.
### Inputs
Specify a JSON object that has the following fields as inputs.
| Field | Description |
|:----------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `collection_id` | An ID of a collection. |
| `object_ids` | An array of string values. |
| `options` | (Optional) A JSON object for specifying options. Available options:
`force`: A boolean value to specify whether the contract adds IDs even if the IDs exist. The default value is `false`. |
### Outputs
A null value is returned if it is successful.
### Examples
```console
scalardl generic-contracts execute-contract --properties client.properties \
--contract-id collection.Add \
--contract-argument '{"collection_id": "audit_set", "object_ids": ["a.txt"], "options": {"force": true}}'
```
## `collection.Remove` contract
Remove IDs from a collection. Typically, the IDs are for objects and collections managed by the generic contracts.
### Inputs
Specify a JSON object that has the following fields as inputs.
| Field | Description |
|:----------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `collection_id` | An ID of a collection to remove. |
| `object_ids` | An array of string values. |
| `options` | (Optional) A JSON object for specifying options. Available options: `force`: A boolean value to specify whether the contract continue to remove IDs even if a specified ID does not exist. The default value is `false`. |
### Outputs
A null value is returned if it is successful.
### Examples
```console
scalardl generic-contracts execute-contract --properties client.properties \
--contract-id collection.Remove \
--contract-argument '{"collection_id": "audit_set", "object_ids": ["a.txt"], "options": {"force": true}}'
```
## `collection.Get` contract
Get a collection with the specified ID. If the specified collection does not exist, a null value will be returned.
### Inputs
Specify a JSON object that has the following field as an input.
| Field | Description |
|:----------------|:------------------------------|
| `collection_id` | An ID of a collection to get. |
### Outputs
A JSON object that has the following field is returned.
| Field | Description |
|:-------------|:---------------------------|
| `object_ids` | An array of string values. |
### Examples
```console
scalardl generic-contracts execute-contract --properties client.properties \
--contract-id collection.Get \
--contract-argument '{"collection_id": "audit_set"}'
Contract result:
{"object_ids": ["a.txt", "b.txt"]}
```
## `collection.GetHistory` contract
Get a modification event history of a collection with the specified ID. Possible events are `create`, `add`, and `remove`. If the specified collection does not exist, a JSON object with an empty `collection_events` array is returned.
### Inputs
Specify a JSON object that has the following fields as inputs.
| Field | Description |
|:----------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `collection_id` | An ID of a collection to get a history. |
| `options` | (Optional) A JSON object for specifying options. Available options: `limit`: An integer value to specify how many latest events to get. The default is `0` (no limit). |
### Outputs
A JSON object that has the following fields is returned.
| Field | Description |
|:--------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `collection_id` | An ID of the collection. |
| `collection_events` | A JSON object that has the following fields: `operation_type`, `object_ids`, and `age`. A value for `operation_type` can be `create`, `add`, or `remove`. `object_ids` is a set of added or removed IDs in the event, and the value is an array of string values. `age` is an asset record version, and the value is an integer number. |
### Examples
```console
scalardl generic-contracts execute-contract --properties client.properties \
--contract-id collection.GetHistory \
--contract-argument '{"collectionId": "audit_set", "options": {"limit": 2}}'
Contract result:
{
"collection_id": "audit_set",
"collection_events": [
{
"operation_type": "remove",
"object_ids": ["a.txt"],
"age": 5
},
{
"operation_type": "add",
"object_ids": ["a.txt", "b.txt"],
"age": 4
}
]
}
```
## `collection.GetCheckpointInterval` contract
Get a checkpoint interval, which is used for efficient collection management. You don’t have to execute this contract directly because it is internally used from other generic contracts, but you can configure the checkpoint interval via contract properties when registering this contract.
The checkpoint interval configures how often a snapshot of a collection is created. When adding or removing IDs in the collection, a new asset record only holds the differential data instead of the whole new set of IDs for storage efficiency. Then, when getting the collection, the differential data in the past is merged and returned. To avoid merging all the past data every time, we create a snapshot for each checkpoint age (version). The checkpoint interval is an integer number that indicates how many updates to wait since the previous checkpoint creation.
### Contract properties
Specify a JSON object that has the following field as a contract property if you would like to change the checkpoint interval.
| Field | Description |
|:----------------------|:----------------------------------------------|
| `checkpoint_interval` | An integer value for the checkpoint interval. |
:::note
If the `collection.GetCheckpointInterval` contract is registered and used by multiple client identities (that is `scalar.dl.client.entity.id`), you must set the same checkpoint interval when registering the contract.
:::
### Inputs
Specify an empty JSON object as the input.
### Outputs
A JSON object that has the following field is returned.
| Field | Description |
|:----------------------|:---------------------------------------------------------------------------------------------------------------------------------------|
| `checkpoint_interval` | An integer value for the checkpoint interval configured by the contract properties. If you do not configure a value, the default value will be `10`. |
### Examples
```console
scalardl generic-contracts execute-contract --properties client.properties \
--contract-id collection.GetCheckpointInterval \
--contract-argument '{}'
Contract result:
{"checkpoint_interval": 10}
```
================================================
FILE: docs/getting-started-hashstore.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import JavadocLink from "/src/theme/JavadocLink.js";
import StartupLedger from '/src/components/en-us/_getting-started-startup-ledger.mdx';
# Get Started with ScalarDL HashStore
ScalarDL HashStore is a high-level abstraction on top of a low-level ledger abstraction. It is specially designed for digital evidence preservation and offers two functionalities: object authenticity management and collection authenticity management. By using HashStore, you can manage hash values of objects and a collection of objects in an immutable manner without writing a [contract](design.mdx#contract), enabling you to develop authenticity management applications quickly and easily.
This getting started tutorial explains how to configure ScalarDL HashStore on your preferred database and manage objects and collections in a tamper-evident manner.
## What is ScalarDL HashStore?
HashStore provides two functionalities: object authenticity management and collection authenticity management. The object authenticity management enables you to manage the authenticity of any kind of your objects, like files, audit logs, and even directories in your file or object storage. The collection authenticity management enables you to manage which objects exist in a collection. For example, you can create a collection of objects that need to be validated in an auditing process.
For how HashStore achieves these functionalities, see the examples in [Manage object authenticity](#manage-object-authenticity) and [Manage collection authenticity](#manage-collection-authenticity) below.
## Download the Client SDK
Next, you'll use the ScalarDL HashStore client tools. Specify a version that is the same as the deployed ScalarDL version and is used for downloading the tools by running the following command:
```console
VERSION=$(grep SCALARDL_VERSION .env | awk -F= '{print $2}')
```
Then, download the tools by running the following command:
```console
curl -OL https://github.com/scalar-labs/scalardl/releases/download/v$VERSION/scalardl-hashstore-java-client-sdk-$VERSION.zip
unzip scalardl-hashstore-java-client-sdk-$VERSION.zip
mv scalardl-hashstore-java-client-sdk-$VERSION hashstore
```
## Configure the client properties
Before interacting with ScalarDL HashStore, you need to configure the client. To create a configuration file with the minimum required properties for the client, run the following command:
```console
cat << 'EOF' > client.properties
# A host name for ScalarDL Ledger.
scalar.dl.client.server.host=localhost
# An ID for the certificate holder. This must be configured for each private key and must be unique in the system.
scalar.dl.client.cert_holder_id=foo
# A path to the certificate file.
scalar.dl.client.cert_path=./fixture/client.pem
# A path to the private key file.
scalar.dl.client.private_key_path=./fixture/client-key.pem
EOF
```
You can use `localhost` for the ScalarDL Ledger host name in this tutorial. For the private key and certificate, you can use the ones provided in the [`fixture` directory of the `scalardl-samples` repository](https://github.com/scalar-labs/scalardl-samples/tree/master/fixture) (`client-key.pem` and `client.pem`, respectively). For the certificate holder, any unique ID can be specified.
:::warning
Do not use the sample private key and certificate in production environments. For details about getting your own certificate, see [How to Get a Certificate](ca/caclient-getting-started.mdx).
:::
## Bootstrap
Next, you can bootstrap HashStore by running the following command:
```console
hashstore/bin/scalardl-hashstore bootstrap --properties client.properties
```
The bootstrap command internally registers identity information (a certificate or secret) and predefined contracts necessary to use HashStore.
## Manage object authenticity
With the object authenticity management in HashStore, you can put the hash value of an object by using the `put-object` command. Specify the target object ID and the hash value of the object, like in the following example. The object ID must be a unique ID that identifies your objects or files, for example, a key of an object or a file path. You can also put any metadata associated with the object by using the `metadata` option.
First, get the hash value of a file and put it into the tamper-evident ledger.
:::note
The `sha256sum` command is for Linux environments only. `shasum` and `certutil` are available for macOS and Windows environments, respectively. For details on getting the same SHA256 hash values, see the usage of those commands.
:::
```console
echo "Alice created this file." > a.txt
sha256sum a.txt
```
You should get the following hash value:
```console
5c7440fb2273a247f78aadefbc511c680a84e7d44004abfaedef2b145151dab0 a.txt
```
You can put the hash value by running the following command:
```console
hashstore/bin/scalardl-hashstore put-object --properties client.properties \
--object-id a.txt \
--hash 5c7440fb2273a247f78aadefbc511c680a84e7d44004abfaedef2b145151dab0 \
--metadata '{"note": "created"}'
```
If the object is updated, you can put the new hash value in the same way. For example, the following assumes that the command below was executed:
```console
echo "Alice updated this file." >> a.txt
sha256sum a.txt
```
You should get the following result as the hash value:
```console
b97a42c87a46ffebe1439f8c1cd2f86e2f9b84dad89c8e9ebb257a19b6fdfe1c a.txt
```
You can then update the hash value as follows:
```console
hashstore/bin/scalardl-hashstore put-object --properties client.properties \
--object-id a.txt \
--hash b97a42c87a46ffebe1439f8c1cd2f86e2f9b84dad89c8e9ebb257a19b6fdfe1c \
--metadata '{"note": "updated"}'
```
You can also get the latest status of the object by running the following command:
```console
hashstore/bin/scalardl-hashstore get-object --properties client.properties \
--object-id a.txt
```
You should get a result like the following:
```console
Result:
{
"object_id" : "a.txt",
"hash_value" : "b97a42c87a46ffebe1439f8c1cd2f86e2f9b84dad89c8e9ebb257a19b6fdfe1c",
"metadata" : {
"note" : "updated"
}
}
```
If you want to validate the object's authenticity, first recalculate the hash value, for example, by using the `sha256sum` command, for each version of the object that you want to validate.
Then, execute the `compare-object-versions` command with the recalculated hash values with the version IDs in descending order. You can specify any number of versions. The version IDs are only used for showing which hash values are different from the original values in the output, so any string values can be used as long as the values are uniquely identifiable.
:::note
If you cannot get the hash value of the older version of the `a.txt` file in your environment, specify only the current version instead.
:::
```console
hashstore/bin/scalardl-hashstore compare-object-versions --properties client.properties \
--object-id a.txt \
--versions '[{"version_id": "v2", "hash_value": "b97a42c87a46ffebe1439f8c1cd2f86e2f9b84dad89c8e9ebb257a19b6fdfe1c"}, {"version_id": "v1", "hash_value": "5c7440fb2273a247f78aadefbc511c680a84e7d44004abfaedef2b145151dab0"}]}'
```
You should see the following result if the recalculated hash values of the object are the same as the ones in the tamper-evident ledger.
```console
Result:
{
"status" : "correct",
"details" : "The status is correct.",
"faulty_versions" : [ ]
}
```
Suppose that someone tampered with the file `a.txt` as follows:
```txt
Bob created this file.
Alice updated this file
```
Now the hash value of the latest version is `1f75d715648a3b4b3a33ecd7428a3e7139d9357da7d38735c23bf38618ecf9c7`. You can execute validation by running the following command:
```console
hashstore/bin/scalardl-hashstore compare-object-versions --properties client.properties \
--object-id a.txt \
--versions '[{"version_id": "v2", "hash_value": "1f75d715648a3b4b3a33ecd7428a3e7139d9357da7d38735c23bf38618ecf9c7"}, {"version_id": "v1", "hash_value": "5c7440fb2273a247f78aadefbc511c680a84e7d44004abfaedef2b145151dab0"}]}'
```
You should get a result like the following:
```console
Result:
{
"status" : "faulty",
"details" : "A faulty version is found.",
"faulty_versions" : [ "v2" ]
}
```
This validation process confirms if the data outside ScalarDL has not been changed by comparing the hash value of the data with the corresponding hash value stored in ScalarDL. To validate whether the data in ScalarDL (the hash values in this case) has not been tampered with, you can use the `validate-ledger` command. For details, see [Validate data managed by HashStore](#validate-data-managed-by-hashstore).
### Synchronize the object state between ScalarDL Ledger and a ScalarDB table
Since ScalarDL manages data (called "assets") in a tamper-evident and append-only manner, you are not able to update data in place, and you need to model your data in a somewhat inflexible manner. To mitigate these limitations, you can use ScalarDB in conjunction with ScalarDL. Specifically, you can issue operations to ScalarDL in parallel with issuing ScalarDB's mutation operations to ScalarDB-managed databases.
For example, in object authenticity management, the `put-object` command (and the corresponding API) provides the `--put-to-mutable` option, for putting an arbitrary record into a ScalarDB table when putting an object hash value. One primary use case for the option is managing object status (whether the hash value of the object is stored correctly in ScalarDL) on the ScalarDB side, allowing for identifying target objects flexibly and efficiently by using ScalarDB APIs. In such a case, you would:
1. Create a table (for example, `objects`) in ScalarDB to manage whether the hash value of an object version has already been registered.
1. List and put target objects in the `objects` table with a hash-value-not-registered status.
1. Update the state in the `objects` table after the hash value is successfully registered to ScalarDL.
The third step above must be done in an ACID manner by executing the following command with the `--put-to-mutable` option:
```console
hashstore/bin/scalardl-hashstore put-object --properties client.properties \
--object-id a.txt \
--hash 5c7440fb2273a247f78aadefbc511c680a84e7d44004abfaedef2b145151dab0 \
--put-to-mutable '{...}'
```
For the argument of the `--put-to-mutable` option, you need to specify a namespace name, a table name, a partition key, a clustering key (if any), and columns, depending on your ScalarDB table schema. An example is as follows.
```json
{
"namespace": "myns",
"table": "objects",
"partition_key": [
{ "column_name": "object_id", "value": "a.txt", "data_type": "TEXT" }
],
"clustering_key": [
{ "column_name": "version", "value": "1234aef", "data_type": "TEXT" }
],
"columns": [
{ "column_name": "status", "value": 3, "data_type": "INT" },
{ "column_name": "size", "value": 10.000, "data_type": "DOUBLE" },
{ "column_name": "timestamp", "value": 123456789, "data_type": "BIGINT" },
{ "column_name": "comment", "value": "hash-registered", "data_type": "TEXT" }
]
}
```
## Manage collection authenticity
Collection authenticity management allows you to manage the authenticity of a set. For example, when you use a file storage and manage the authenticity of the files by using the `compare-object-versions` command, you may also want to do the same for folders or sets of objects that must be validated in an auditing process. Collection management covers these use cases and protects the audit sets.
If a system cannot guarantee that an audit set has not been changed unexpectedly, a malicious user may be able to change an object fraudulently and remove it from the audit set to avoid being revealed as a fraud. Therefore, managing the audit set is an important and major use case of collection authenticity management.
You can create a collection for an audit set by running the following command:
```console
hashstore/bin/scalardl-hashstore create-collection --properties client.properties \
--collection-id audit_set --object-ids a.txt --object-ids b.txt
```
The collection ID must be a unique ID that identifies the collection. You can specify a set of object IDs by using the `--object-ids` option. The object IDs are just string values, so you can specify any IDs for them. For example, you can put the collection IDs to represent the audit set in a hierarchical manner.
You can also add objects to the collection by running the following command:
```console
hashstore/bin/scalardl-hashstore add-to-collection --properties client.properties \
--collection-id audit_set --object-ids c.txt --object-ids d.txt
```
And you can remove objects from the collection by running the following command:
```console
hashstore/bin/scalardl-hashstore remove-from-collection --properties client.properties \
--collection-id audit_set --object-ids a.txt
```
You can get the latest status of the collection by running the following command:
```console
hashstore/bin/scalardl-hashstore get-collection --properties client.properties \
--collection-id audit_set
```
You should get a result like the following:
```console
Result:
{"object_ids": ["d.txt", "c.txt", "b.txt"]}
```
To confirm that the audit set has not been changed unexpectedly, you can check the update history of the audit set by running the following command:
```console
hashstore/bin/scalardl-hashstore get-collection-history --properties client.properties \
--collection-id audit_set
```
You should get a result like the following:
```console
Result:
{
"collection_id" : "audit_set",
"collection_events" : [ {
"operation_type" : "remove",
"age" : 2,
"object_ids" : [ "a.txt" ]
}, {
"operation_type" : "add",
"age" : 1,
"object_ids" : [ "c.txt", "d.txt" ]
}, {
"operation_type" : "create",
"age" : 0,
"object_ids" : [ "a.txt", "b.txt" ]
} ]
}
```
## Validate data managed by HashStore
In ScalarDL, you occasionally need to validate your data to make sure all the data is in a valid state. You can use the `validate-ledger` command to validate data managed by HashStore.
You can validate an object by running the following command:
```console
hashstore/bin/scalardl-hashstore validate-ledger --properties client.properties \
--object-id a.txt
```
You should get a result like the following:
```console
{
"status_code" : "OK",
"Ledger" : {
"id" : "o_a.txt",
"age" : 2,
"nonce" : "8182ce3f-620d-4b8d-8718-19fc2666e060",
"hash" : "8wLsztcUHRBSfdu4vCLfmWeAuS4T8UUoz+9QkqDl7Xc=",
"signature" : "MEYCIQC83aBqEiBtyGW0UHa7AlJeLWho/wOnL1U5AzTbDMb7ngIhAOkgyVQtEYjtCD4FBZuuqAWuIOIW9Gnbd/djkxnet53a"
},
"Auditor" : null
}
```
You can validate a collection by running the following command:
```console
hashstore/bin/scalardl-hashstore validate-ledger --properties client.properties \
--collection-id audit_set
```
You should get a result like the following:
```console
{
"status_code" : "OK",
"Ledger" : {
"id" : "c_audit_set",
"age" : 2,
"nonce" : "cd99fb75-1bde-4be3-af03-b43bd05f85eb",
"hash" : "9Mw+Z4BQkDeLyd+su3WAi2Pes89AKU9kdZmy5Bgtj6c=",
"signature" : "MEUCIAcG5di+Tn+VK35J2ZlzembZXxO4DV9cv/9zS1kMdimHAiEAnR3nqQ5I8UzQ+n99Uew6rZQ1DGZWIJzhcmJ9U3axXBs="
},
"Auditor" : null
}
```
:::note
ScalarDL HashStore internally assigns a dedicated asset ID to an [asset record](data-modeling.mdx#asset-record), which is an object in the primitive data model of ScalarDL. The asset ID consists of a prefix for the asset type and keys for identification; for example, a prefix `c_` and collection ID are used for the asset ID of a collection. You will see such raw asset IDs in the result of `validate-ledger`.
:::
## See also
To interact with ScalarDL HashStore in your Java applications, see the following:
* [Javadocs for the ScalarDL HashStore Java Client SDK](https://javadoc.io/doc/com.scalar-labs/scalardl-hashstore-java-client-sdk/latest/index.html)
================================================
FILE: docs/getting-started-tablestore.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import JavadocLink from "/src/theme/JavadocLink.js";
import StartupLedger from '/src/components/en-us/_getting-started-startup-ledger.mdx';
# Get Started with ScalarDL TableStore
ScalarDL TableStore is a high-level abstraction on top of the low-level ledger abstraction. It offers an [SQL interface](sql-grammar.mdx) instead of primitive CRUD interfaces like get and put, enabling you to build versatile, tamper-evident applications with the familiar data model and commands quickly and easily.
This getting started tutorial explains how to configure TableStore on your preferred database and manage tables and records in a tamper-evident manner.
## What is ScalarDL TableStore?
TableStore provides table-based data management through an [SQL interface](sql-grammar.mdx). You can create tables in a flexible schemaless manner, perform SQL operations like SELECT, INSERT, and UPDATE, and maintain complete audit trails of all data modifications. It also provides an indexing capability, allowing you to select records not only by a primary key but also by an index key.
## Download the Client SDK
Next, you'll use the TableStore client tools. Specify a version that is the same as the deployed ScalarDL version and is used for downloading the tools by running the following command:
```console
VERSION=$(grep SCALARDL_VERSION .env | awk -F= '{print $2}')
```
Then, download the tools by running the following command:
```console
curl -OL https://github.com/scalar-labs/scalardl/releases/download/v$VERSION/scalardl-tablestore-java-client-sdk-$VERSION.zip
unzip scalardl-tablestore-java-client-sdk-$VERSION.zip
mv scalardl-tablestore-java-client-sdk-$VERSION tablestore
```
## Configure the client properties
Before interacting with TableStore, you need to configure the client. To create a configuration file with the minimum required properties for the client, run the following command:
```console
cat << 'EOF' > client.properties
# A host name for ScalarDL Ledger.
scalar.dl.client.server.host=localhost
# An ID for the certificate holder. This must be configured for each private key and must be unique in the system.
scalar.dl.client.cert_holder_id=foo
# A path to the certificate file.
scalar.dl.client.cert_path=./fixture/client.pem
# A path to the private key file.
scalar.dl.client.private_key_path=./fixture/client-key.pem
EOF
```
You can use `localhost` for the ScalarDL Ledger host name in this tutorial. For the private key and certificate, you can use the ones provided in the [`fixture` directory of the `scalardl-samples` repository](https://github.com/scalar-labs/scalardl-samples/tree/master/fixture) (`client-key.pem` and `client.pem`, respectively). For the certificate holder, any unique ID can be specified.
:::warning
Do not use the sample private key and certificate in production environments. For details about getting your own certificate, see [How to Get a Certificate](ca/caclient-getting-started.mdx).
:::
## Bootstrap
Next, you can bootstrap TableStore by running the following command:
```console
tablestore/bin/scalardl-tablestore bootstrap --properties client.properties
```
The bootstrap command internally registers identity information (a certificate or secret) and predefined contracts necessary to use TableStore.
## Interact with TableStore
Now you can execute SQL statements with TableStore. In this section, you'll try the following functionalities through two sample tables (`employee` and `department`) that can be joined through the department IDs of employees:
- [Create and show tables](#create-and-show-tables)
- [Insert records](#insert-records)
- [Select records](#select-records)
- [Update records](#update-records)
- [Get record histories](#get-record-histories)
### Create and show tables
You can create the sample table by running the following commands:
```console
tablestore/bin/scalardl-tablestore execute-statement --properties client.properties \
--statement "CREATE TABLE employee (id STRING PRIMARY KEY, department STRING)"
```
```console
tablestore/bin/scalardl-tablestore execute-statement --properties client.properties \
--statement "CREATE TABLE department (id STRING PRIMARY KEY)"
```
When creating a table, you need to specify the name and the primary key. You can create secondary indexes by specifying additional columns. Because ScalarDL TableStore treats a JSON object as a record in tables, you don't have to specify a strict schema when creating a table.
You can show the created tables by running the following command:
```console
tablestore/bin/scalardl-tablestore execute-statement --properties client.properties \
--statement "SELECT * FROM information_schema.tables"
```
You should get a result like the following:
```console
Result:
[ {
"name" : "employee",
"key" : "id",
"type" : "string",
"indexes" : [ {
"key" : "department",
"type" : "string"
} ]
}, {
"name" : "department",
"key" : "id",
"type" : "string",
"indexes" : [ ]
} ]
```
### Insert records
Next, insert several `employee` records by running the following commands:
```console
tablestore/bin/scalardl-tablestore execute-statement --properties client.properties \
--statement "INSERT INTO employee VALUES {'id': '1001', 'name': 'Alice', 'department': 'sales', 'salary': 654.3}"
```
```console
tablestore/bin/scalardl-tablestore execute-statement --properties client.properties \
--statement "INSERT INTO employee VALUES {'id': '1002', 'name': 'Bob', 'department': 'sales', 'salary': 543.2}"
```
```console
tablestore/bin/scalardl-tablestore execute-statement --properties client.properties \
--statement "INSERT INTO employee VALUES {'id': '1003', 'name': 'Carol', 'department': 'engineering', 'salary': 654.3}"
```
Insert the corresponding `department` records as well by running the following commands:
```console
tablestore/bin/scalardl-tablestore execute-statement --properties client.properties \
--statement "INSERT INTO department VALUES {'id': 'sales', 'location': 'Shinjuku', 'phone': '000-1234'}"
```
```console
tablestore/bin/scalardl-tablestore execute-statement --properties client.properties \
--statement "INSERT INTO department VALUES {'id': 'engineering', 'location': 'Shibuya', 'phone': '000-4321'}"
```
### Select records
Then, check the inserted records. You need to specify at least a primary key or index key to select records. For example, you can get an `employee` record by specifying the primary key by running the following command:
```console
tablestore/bin/scalardl-tablestore execute-statement --properties client.properties \
--statement "SELECT id, name, department FROM employee WHERE id = '1001'"
```
You can optionally project the columns by specifying top-level fields in the JSON record object. You should get a result like the following:
```console
Result:
[ {
"id" : "1001",
"name" : "Alice",
"department" : "sales"
} ]
```
You can also specify an index key to select records by running the following command:
```console
tablestore/bin/scalardl-tablestore execute-statement --properties client.properties \
--statement "SELECT id, name, department FROM employee WHERE department = 'sales'"
```
You should get a result like the following:
```console
Result:
[ {
"id" : "1001",
"name" : "Alice",
"department" : "sales"
}, {
"id" : "1002",
"name" : "Bob",
"department" : "sales"
} ]
```
If you want to filter records, specify additional conditions by running the following command:
```console
tablestore/bin/scalardl-tablestore execute-statement --properties client.properties \
--statement "SELECT id, name, department FROM employee WHERE department = 'sales' AND salary < 600"
```
You should get a result like the following:
```console
Result:
[ {
"id" : "1002",
"name" : "Bob",
"department" : "sales",
"salary" : 543.2
} ]
```
You can also join the two tables by running the following command:
```console
tablestore/bin/scalardl-tablestore execute-statement --properties client.properties \
--statement "SELECT * FROM employee JOIN department ON employee.department = department.id WHERE employee.department = 'engineering'"
```
You should get a result like the following:
```console
Result:
[ {
"employee.id" : "1003",
"employee.name" : "Carol",
"employee.department" : "engineering",
"employee.salary" : 654.3,
"department.id" : "engineering",
"department.location" : "Shibuya",
"department.phone" : "000-4321"
} ]
```
### Update records
You can update the `employee` records by running the following command:
```console
tablestore/bin/scalardl-tablestore execute-statement --properties client.properties \
--statement "UPDATE employee SET salary = 754.3 WHERE department = 'engineering'"
```
Make sure to specify at least a primary key or an index key to update the records, in the same way as using the `SELECT` statement.
### Get record histories
You can get the update history of a record by running the following command:
```console
tablestore/bin/scalardl-tablestore execute-statement --properties client.properties \
--statement "SELECT history() FROM employee WHERE id = '1003'"
```
You should get a result like the following:
```console
Result:
[ {
"age" : 1,
"values" : {
"id" : "1003",
"name" : "Carol",
"department" : "engineering",
"salary" : 754.3
}
}, {
"age" : 0,
"values" : {
"id" : "1003",
"name" : "Carol",
"department" : "engineering",
"salary" : 654.3
}
} ]
```
If you want to limit the number of versions (ages), specify the `LIMIT` clause by running the following command:
```console
tablestore/bin/scalardl-tablestore execute-statement --properties client.properties \
--statement "SELECT history() FROM employee WHERE id = '1003' LIMIT 1"
```
You should get the specified number of the **latest** records like the following:
```console
Result:
[ {
"age" : 1,
"values" : {
"id" : "1003",
"name" : "Carol",
"department" : "engineering",
"salary" : 754.3
}
} ]
```
## Validate data managed by TableStore
In ScalarDL, you occasionally need to validate your data to make sure all the data is in a valid state. You can use the `validate-ledger` command to validate data managed by TableStore.
You can validate the table schema by running the following command:
```console
tablestore/bin/scalardl-tablestore validate-ledger --properties client.properties \
--table-name employee
```
You should get a result like the following:
```console
{
"status_code" : "OK",
"Ledger" : {
"id" : "tbl_employee",
"age" : 0,
"nonce" : "26af1229-1c1f-4b89-86e2-ec011da3b313",
"hash" : "ZA9yFzjIg1qeHAd7Sub8uFvt2JrTb6XSzGUktPEITr0=",
"signature" : "MEUCIAh4Xj93J/jldqbQor7AVM4ii9+suxQrZlCFnKWWDIo0AiEAiM6Yi6GO4bQ2VZg2GnqKmOFPEANrTU4g7pjBMcaX6TQ="
},
"Auditor" : null
}
```
You can validate the record by running the following command:
```console
tablestore/bin/scalardl-tablestore validate-ledger --properties client.properties \
--table-name employee --primary-key-column-name id --column-value '"1001"'
```
:::note
The `--column-value` option expects a JSON value; thus, you need to put double quotes for a string value.
:::
You should get a result like the following:
```console
{
"status_code" : "OK",
"Ledger" : {
"id" : "rec_employee_id_1001",
"age" : 0,
"nonce" : "41a18e7f-314f-4aec-8984-62bf6cd355d0",
"hash" : "n7KJLuC/KOzFZLnGKEs6pOQvCbl4WSF+xplOUd9MrSo=",
"signature" : "MEUCIEHafCsSXWWtZnDbSpAwFQk4qjW1B7cXjEgdwVF8uKQeAiEAsvzEMKyuNFozAbLC/E8FEviCMLCqo9DPRQe4tVBFwIk="
},
"Auditor" : null
}
```
You can validate the index record by running the following command:
```console
tablestore/bin/scalardl-tablestore validate-ledger --properties client.properties \
--table-name employee --index-key-column-name department --column-value '"sales"'
```
You should get a result like the following:
```console
{
"status_code" : "OK",
"Ledger" : {
"id" : "idx_employee_department_sales",
"age" : 0,
"nonce" : "41a18e7f-314f-4aec-8984-62bf6cd355d0",
"hash" : "n7KJLuC/KOzFZLnGKEs6pOQvCbl4WSF+xplOUd9MrSo=",
"signature" : "MEUCIEHafCsSXWWtZnDbSpAwFQk4qjW1B7cXjEgdwVF8uKQeAiEAsvzEMKyuNFozAbLC/E8FEviCMLCqo9DPRQe4tVBFwIk="
},
"Auditor" : null
}
```
:::note
ScalarDL TableStore internally assigns a dedicated asset ID to an [asset record](data-modeling.mdx#asset-record), which is an object in the primitive data model of ScalarDL. The asset ID consists of a prefix for the asset type and keys for identification; for example, a prefix `rec_`, table name, primary key column name, and column value are used for the asset ID of a record. You will see such raw asset IDs in the result of `validate-ledger`.
:::
## See also
To interact with ScalarDL TableStore in your Java applications, see the following:
* [Javadocs for the ScalarDL TableStore Java Client SDK](https://javadoc.io/doc/com.scalar-labs/scalardl-tablestore-java-client-sdk/latest/index.html)
## References
* [ScalarDL TableStore SQL Grammar](sql-grammar.mdx)
================================================
FILE: docs/getting-started.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import JavadocLink from "/src/theme/JavadocLink.js";
import StartupLedger from '/src/components/en-us/_getting-started-startup-ledger.mdx';
# Get Started with ScalarDL Ledger
This getting started tutorial explains how to configure ScalarDL on your preferred database and illustrates the process of creating a simple application where the historical states of data are traced.
## Download the Client SDK
Next, you'll use the ScalarDL client tools and samples to interact with ScalarDL.
Specify a version that is the same as the deployed ScalarDL version and is used for downloading the tools by running the following command:
```console
VERSION=$(grep SCALARDL_VERSION .env | awk -F= '{print $2}')
```
Then, download the tools by running the following command:
```console
curl -OL https://github.com/scalar-labs/scalardl/releases/download/v$VERSION/scalardl-java-client-sdk-$VERSION.zip
unzip scalardl-java-client-sdk-$VERSION.zip
mv scalardl-java-client-sdk-$VERSION client
```
## Configure the client properties
Before you can run ScalarDL Ledger, you need to configure the ScalarDL client. To create a configuration file with the minimum required properties for the client to interact with ScalarDL Ledger, run the following command:
```console
cat << 'EOF' > client.properties
# A host name for ScalarDL Ledger.
scalar.dl.client.server.host=localhost
# An ID for the certificate holder. This must be configured for each private key and must be unique in the system.
scalar.dl.client.cert_holder_id=foo
# A path to the certificate file.
scalar.dl.client.cert_path=./fixture/client.pem
# A path to the private key file.
scalar.dl.client.private_key_path=./fixture/client-key.pem
EOF
```
You can use `localhost` for the ScalarDL Ledger host name in this tutorial. For the private key and certificate, you can use the ones provided in the `fixture` directory of `scalardl-samples` (`client-key.pem` and `client.pem`, respectively). For the certificate holder, any unique ID can be specified.
:::warning
Do not use the sample private key and certificate in production environments. For details about getting your own certificate, see [How to Get a Certificate](ca/caclient-getting-started.mdx).
:::
## Register the certificate
Next, you can register your certificate to ScalarDL Ledger by running the following command:
```console
client/bin/scalardl register-cert --properties client.properties
```
The registered certificate will allow you to register and execute contracts and will also be used for detecting Byzantine faults in databases.
Note that you can only add new certs and cannot update existing certs in place for security reasons. When you want to add a new cert, increment `scalar.dl.client.cert_version` before executing the registration tool.
## Create a contract
You can interact with ScalarDL through a contract, which is a Java program that implements single business logic. In this tutorial, you can see how a contract is written, built, and works by using a basic contract example, which creates an asset and associates some states with it.
Below, you can see a sample contract, [StateUpdater.java](https://github.com/scalar-labs/scalardl-samples/blob/master/src/main/java/com/org1/contract/StateUpdater.java). A contract is simply a Java class that extends the predefined base contract classes (such as class) and overrides the `invoke` method. The business logic is implemented in the `invoke` method.
Specifically, the `invoke` method will extract a client-defined asset ID (`asset_id`) and state (`state`) from the argument, and then associate the asset ID with the state in the ledger if the given state is different from the asset's current state.
```java
package com.org1.contract;
import com.fasterxml.jackson.databind.JsonNode;
import com.scalar.dl.ledger.contract.JacksonBasedContract;
import com.scalar.dl.ledger.exception.ContractContextException;
import com.scalar.dl.ledger.statemachine.Asset;
import com.scalar.dl.ledger.statemachine.Ledger;
import java.util.Optional;
import javax.annotation.Nullable;
public class StateUpdater extends JacksonBasedContract {
@Nullable
@Override
public JsonNode invoke(Ledger ledger, JsonNode argument, @Nullable JsonNode properties) {
if (!argument.has("asset_id") || !argument.has("state")) {
// ContractContextException is the only throwable exception in a contract and
// it should be thrown when a contract faces some non-recoverable error
throw new ContractContextException("please set asset_id and state in the argument");
}
String assetId = argument.get("asset_id").asText();
int state = argument.get("state").asInt();
Optional> asset = ledger.get(assetId);
if (!asset.isPresent() || asset.get().data().get("state").asInt() != state) {
ledger.put(assetId, getObjectMapper().createObjectNode().put("state", state));
}
return null;
}
}
```
You can compile the contract by running the following command:
```console
./gradlew assemble
```
This will generate `build/classes/java/main/com/org1/contract/StateUpdater.class`.
## Register the contract
Next, register your contract by running the following command:
```console
client/bin/scalardl register-contract --properties client.properties --contract-id StateUpdater --contract-binary-name com.org1.contract.StateUpdater --contract-class-file build/classes/java/main/com/org1/contract/StateUpdater.class
```
Please set a globally unique ID for the contract ID (e.g. `StateUpdater` in the above command).
:::tip
You can set different contract IDs on the same contract by using different certificates to clarify "who did what" in a tamper-evident way.
For example, think about a voting application. In the application, anyone can vote with the same voting logic and therefore can use the same contract, but A's vote and B's vote need to be properly and securely distinguished—A cannot vote for B, and vice versa. By using different contract IDs on the same contract, you can ensure that A's vote and B's vote are identified differently from one another.
:::
## Execute the contract
Now you are ready to execute the contract with the following command.
```console
client/bin/scalardl execute-contract --properties client.properties --contract-id StateUpdater --contract-argument '{"asset_id":"some_asset", "state":3}'
```
In the contract argument, the value specified with the key `asset_id` must be unique globally for each asset.
## Validate the states of Ledger
You can validate the states of Ledger by executing the following command.
```console
client/bin/scalardl validate-ledger --properties client.properties --asset-id="some_asset"
```
What the validation does is depending on how you set up and configure ScalarDL.
Briefly speaking, if only ScalarDL Ledger is used, the validation traverses assets to see if the assets can be recomputed and have a valid hash-chain structure.
With ScalarDL Ledger and Auditor, the validation checks discrepancies (i.e., Byzantine faults) between the states of Ledger and Auditor without centralized coordination.
For more details about the validation with Auditor, see [Validate your data](how-to-write-applications.mdx#validate-your-data) and [Run a ScalarDL Application Through ScalarDL Ledger and Auditor](how-to-run-applications-with-auditor.mdx).
## Create your own contracts or use predefined contracts
There are two options for preparing contracts: creating your own or using predefined ones.
As explained above, what you need to do to create your contracts is to extend the predefined base contract classes and override the `invoke` method as you like. For details, see [A Guide on How to Write a Good Contract](how-to-write-contract.mdx).
Predefined contracts for common use cases are available through two abstracted data stores: HashStore and TableStore.
* HashStore provides interfaces for ensuring the authenticity of objects and collections, making it ideal for chain-of-custody and similar applications.
* TableStore offers an SQL-compatible interface for verifying table authenticity, enabling developers to build versatile, tamper-evident applications with familiar data models and interfaces.
For details, see [Get Started with ScalarDL HashStore](getting-started-hashstore.mdx) and [Get Started with ScalarDL TableStore](getting-started-tablestore.mdx).
## See also
To write your own contracts, see the following:
* [A Guide on How to Write a Good Contract](how-to-write-contract.mdx)
To interact with ScalarDL components in your Java applications, see the following:
* [Write a ScalarDL Application in Java](how-to-write-applications.mdx)
To use abstracted data stores for easy Ledger interaction without writing your own contracts, see the following:
* [Get Started with ScalarDL HashStore](getting-started-hashstore.mdx)
* [Get Started with ScalarDL TableStore](getting-started-tablestore.mdx)
To better understand the foundation of ScalarDL, see the following:
* [ScalarDL Design Document](design.mdx)
* [ScalarDL Implementation](implementation.mdx)
================================================
FILE: docs/glossary.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Glossary
This glossary includes terms that are often used when using ScalarDL.
## Security terms
The following are security terms.
### administrative domain
An administrative domain is a boundary within which entities or systems are governed by the same administrative authorities, allowing for controlled data and resource management.
### authenticity
Authenticity is the assurance that data, messages, or transactions originate from verified sources, preventing impersonation or forgery.
### blockchain
A blockchain is a distributed-ledger technology where data is recorded in blocks and linked together in a chain, ensuring transparency, immutability, and security.
### Byzantine fault
A Byzantine fault refers to an arbitrary fault regardless of maliciousness, such as software bugs and data tampering, posing a challenge to maintaining consistency in distributed systems.
### Byzantine-fault detection
Byzantine-fault detection is the process of identifying nodes that exhibit Byzantine faults in a distributed system, supporting system reliability by flagging potential threats.
### Byzantine-fault tolerance
Byzantine-fault tolerance is a system's ability to continue functioning correctly even when some nodes act maliciously or inconsistently, often through consensus mechanisms.
### CA
A certificate authority (CA) is a trusted entity that issues digital certificates to verify the identity of organizations and individuals, ensuring secure communication through public key infrastructure (PKI).
### certificate
A certificate is a digital document that verifies the identity of an entity by using cryptographic signatures, ensuring secure communication and trust.
### digital signature
A digital signature is a cryptographic technique that verifies the authenticity and integrity of a message or document, confirming it was created by a known sender and having the non-repudiation property.
### ECDSA
Elliptic Curve Digital Signature Algorithm (ECDSA) is a cryptographic algorithm that uses elliptic curve mathematics to create digital signatures, providing strong security with shorter key lengths compared to RSA.
### HMAC
HMAC (hash-based message authentication code) is a cryptographic function that ensures data integrity and authenticity by hashing the data along with a secret key. Unlike a digital signature, HMAC does not have the non-repudiation property.
### ledger database
A ledger database is a tamper-evident, verifiable database that records data in a sequential manner, supporting traceability and verification, often with cryptographic proof for integrity.
### private key
A private key is a secret cryptographic key used to sign or decrypt data, ensuring secure and authorized access.
### public key
A public key is a cryptographic key shared publicly that enables users to encrypt messages or verify digital signatures, often paired with a private key for secure communication.
### RSA
RSA (Rivest-Shamir-Adleman) is an asymmetric cryptographic algorithm that uses the difficulty of factoring large prime numbers to enable secure data transmission, digital signatures, and key exchange.
### smart contract
A smart contract is a computer program that automatically enforces and verifies rules, terms, or conditions, typically used in ledger and blockchain systems.
### tamper evidence
Tamper evidence ensures the detection of unauthorized modifications of digital data, typically through secure data management systems like ledger databases and blockchains.
### TLS
Transport Layer Security (TLS) is a cryptographic protocol that ensures privacy and data integrity between client-server applications over the internet, replacing its predecessor, Secure Sockets Layer (SSL).
## Database and distributed-system terms
The following are database and distributed-system terms.
### ACID
Atomicity, consistency, isolation, and durability (ACID) is a set of properties that ensure database transactions are processed reliably, maintaining integrity even in cases of errors or system failures.
### concurrency control
Concurrency control in databases ensures that multiple transactions can occur simultaneously without causing data inconsistency, usually through mechanisms like locking or timestamp ordering.
### consensus
Consensus in distributed systems refers to the process of achieving agreement among multiple computers or nodes on a single data value or system state.
### linearizability
Linearizability is a strong consistency model in distributed systems where operations appear to occur atomically in some order consistent with real-time ordering, and each operation takes effect between its start and end.
### Paxos
Paxos is a family of protocols used in distributed systems to achieve consensus, even in the presence of node failures.
### PITR
Point-in-time recovery (PITR) allows a database to be restored to a previous state at any specific time, usually after an unintended event like data corruption.
### read-committed isolation
Read-committed isolation is an isolation level where each transaction sees only committed data, preventing dirty reads but allowing non-repeatable reads.
### serializable isolation
Serializable isolation (serializability) is the highest isolation level in transactional systems, ensuring that the outcome of concurrently executed transactions is the same as if they were executed sequentially.
### snapshot isolation
Snapshot isolation is an isolation level that allows transactions to read a consistent snapshot of the database, protecting them from seeing changes made by other transactions until they complete.
### transaction
A transaction in databases is a sequence of operations treated as a single logical unit of work, ensuring consistency and integrity, typically conforming to ACID properties.
### two-phase locking
Two-phase locking is a concurrency control protocol that enforces serializability by acquiring all required locks before releasing any, in two distinct phases.
================================================
FILE: docs/how-to-run-applications-with-auditor.mdx
================================================
---
tags:
- Enterprise
displayed_sidebar: docsEnglish
---
# Run a ScalarDL Application Through ScalarDL Ledger and Auditor
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import JavadocLink from "/src/theme/JavadocLink.js";
import DbSpecificSteps from '/src/components/en-us/_getting-started-auditor-db-specific-steps.mdx';
This guide explains how to run a ScalarDL application through ScalarDL Ledger and Auditor. This document assumes that you have already tried one of the [Quickstart](quickstart-overview.mdx) tutorials and created your application that integrates ScalarDL by using client SDKs by referring to the [Write an Application](develop-write-an-application-overview.mdx) guides.
## What is ScalarDL Auditor?
ScalarDL Auditor is a component that manages the identical states of Ledger to help clients detect Byzantine faults. Using Auditor is beneficial from a security perspective, but it requires extra processing costs. Therefore, please carefully consider if it is necessary for your use case.
:::note
To make Byzantine fault detection work properly, Ledger and Auditor should be deployed and managed in different administrative domains. However, for the sake of simplicity in this guide, you'll use a simple configuration in the `scalardl-samples` environment, where both Ledger and Auditor are placed on the same network and managed within the same administrative domain.
:::
## Decide on configurations
Before running ScalarDL applications through Ledger and Auditor, you first need to configure Ledger, Auditor, and the client that interacts with ScalarDL.
There are several important options that you must set and decisions to make as described below.
### Enable Auditor
You must enable Auditor since you'll be running applications through Ledger and Auditor. Enabling Auditor has to be done in the configurations for the clients and Ledger as follows.
- In the client configuration, set `scalar.dl.client.auditor.enabled` to `true`.
- In the Ledger configuration, set `scalar.dl.ledger.auditor.enabled` to `true`.
Then, you must enable [Asset Proof](how-to-write-applications.mdx#what-is-asset-proof) in the Ledger configuration by setting `scalar.dl.ledger.proof.enabled` to `true` since ScalarDL uses Asset Proofs to check for consistency between Ledger and Auditor. You also need to configure a proper private key or secret key in the Ledger and Auditor configurations to sign the Asset Proofs, depending on the authentication method chosen in the [Decide on an authentication method](#decide-on-an-authentication-method) section.
:::note
If you are using the `scalardl-samples` environment, see the `ledger.properties` and `auditor.properties` files for the corresponding storage.
:::
For details about the configurations, see the following:
- [Client configurations](configurations.mdx#client-configurations)
- [Ledger configurations](configurations.mdx#ledger-configurations)
- [Auditor configurations](configurations.mdx#auditor-configurations)
### Decide on an authentication method
You must decide which authentication method to use for clients: digital signature or HMAC. As a simple comparison, the digital-signature method provides non-repudiation in addition to authentication but is slow, whereas the HMAC method provides only authentication but is fast.
You can configure an authentication method as follows. The same method (`digital-signature` or `hmac`) must be configured across the client, Ledger, and Auditor.
- In the client configuration, set `scalar.dl.client.authentication.method` to `digital-signature` or `hmac` (depending on which method you choose).
- In the Ledger configuration, set `scalar.dl.ledger.authentication.method` to `digital-signature` or `hmac` (depending on which method you choose).
- In the Auditor configuration, set `scalar.dl.auditor.authentication.method` to `digital-signature` or `hmac` (depending on which method you choose).
You also need to prepare some secret information. If you're using the digital-signature method, you need to prepare a certificate and a private key. If you're using the HMAC method, you need to prepare a secret key. For more details about authentication in ScalarDL, see the [ScalarDL Authentication Guide](./authentication.mdx).
For details about the configurations, see the following:
- [Client configurations](configurations.mdx#client-configurations)
- [Ledger configurations](configurations.mdx#ledger-configurations)
- [Auditor configurations](configurations.mdx#auditor-configurations)
### Configure your database
Both Ledger and Auditor use ScalarDB to interact with databases, which enables you to run ScalarDL on top of various databases. So, you need to decide on a database that ScalarDB supports based on your applications' requirements and configure several ScalarDB parameters.
For details about the ScalarDB parameters, see [ScalarDB Configurations](https://scalardb.scalar-labs.com/docs/latest/configurations/).
#### Underlying database
You can configure which database to use in the Ledger and Auditor configurations by setting `scalar.db.storage`, `scalar.db.contact_points`, `scalar.db.username`, and `scalar.db.password` to the appropriate values based on the database that you'll be using.
For databases and their versions supported by ScalarDL via ScalarDB, see [Requirements](requirements.mdx#databases).
:::warning
If your applications read and write a table through the Function feature, and the table is also directly accessed from ScalarDB applications, you need to properly configure the database chosen here. Specifically, both ScalarDL and ScalarDB applications must refer to the same Coordinator table to guarantee consistency.
:::
#### Isolation level
Ledger relies on the [Consensus Commit](https://scalardb.scalar-labs.com/docs/latest/consensus-commit/) transaction manager of ScalarDB to manage transactions. The transaction manager is responsible for guaranteeing the isolation property of transactions, which is crucial for ensuring the consistency and correctness of transactions.
You can configure the isolation level for Ledger in the Ledger configuration by setting `scalar.db.consensus_commit.isolation_level` to an isolation level of your choice. The default value is `SNAPSHOT`, but if you are unsure about which isolation level to use, use `SERIALIZABLE`.
:::note
Because Auditor does not rely on the Consensus Commit transaction manager, you do not have to configure the transaction manager or the isolation level for Auditor.
:::
#### Limitations
While ScalarDL leverages ScalarDB, the following ScalarDB features are not compatible with the consistency guarantee mechanism of ScalarDL:
- [Group commit for the Coordinator table](https://scalardb.scalar-labs.com/docs/latest/api-guide/#group-commit-for-the-coordinator-table) (`scalar.db.consensus_commit.coordinator.group_commit.enabled` must be `false`.)
- Coordinator write omission optimization in [Performance-related configurations](https://scalardb.scalar-labs.com/docs/latest/configurations#performance-related-configurations) (`scalar.db.consensus_commit.coordinator.write_omission_on_read_only.enabled` must be `false`.)
### Decide which other configurations to use
You can also apply other configurations, such as TLS and gRPC configurations, for the client, Ledger, and Auditor. For details about the configurations, see the following:
- [Client configurations](configurations.mdx#client-configurations)
- [Ledger configurations](configurations.mdx#ledger-configurations)
- [Auditor configurations](configurations.mdx#auditor-configurations)
## Start Ledger and Auditor
After configuring Ledger, Auditor, and the client, you need to start up Ledger and Auditor.
This guide uses a container-based environment in `scalardl-samples` to locally start up Ledger and Auditor. If you have not finished cloning the repository, see [Prerequisites](getting-started.mdx#prerequisites) and [Clone the ScalarDL samples repository](getting-started.mdx#clone-the-scalardl-samples-repository).
For details on how to locally start up Ledger and Auditor in local or cloud-based Kubernetes environments, see [Deploy ScalarDL in your local Kubernetes environment](deploy-local-environment-overview.mdx) or [Deploy ScalarDL in a cloud-based Kubernetes environment](deploy-managed-kubernetes-environment-overview.mdx), respectively.
### Select database
Select your database, and follow the instructions to deploy ScalarDL Ledger and Auditor.
Set up your license
You need a commercial license to use ScalarDL Auditor. Set up your license as follows.
1. Enable the container image for the Enterprise edition in the `cosmosdb/docker-compose-ledger.yml` file as follows:
- Before changing the image (default configuration):
```yaml
# docker-compose-ledger.yml
services:
scalardl-ledger:
image: ghcr.io/scalar-labs/scalardl-ledger:${SCALARDL_VERSION}
# image: ghcr.io/scalar-labs/scalardl-ledger-byol:${SCALARDL_VERSION}
```
- After changing the image:
```yaml
# docker-compose-ledger.yml
services:
scalardl-ledger:
# image: ghcr.io/scalar-labs/scalardl-ledger:${SCALARDL_VERSION}
image: ghcr.io/scalar-labs/scalardl-ledger-byol:${SCALARDL_VERSION}
```
2. Set your license key for ScalarDL Ledger and Auditor. In the `cosmosdb/ledger.properties` and `cosmosdb/auditor.properties` files, replace `` with your license key. For example:
```properties
##### PLEASE REPLACE THIS VALUE WITH YOUR LICENSE KEY (ENTERPRISE EDITION ONLY) #####
scalar.dl.licensing.license_key={"organization_name":"XXXXXXXX","expiration_date_time":"YYYY-MM-DDTHH:mm:SS+TIMEZONE","product_name":"ScalarDL Ledger","product_version":N,"license_type":"trial","signature":"XXXXXXXX"}
##### PLEASE REPLACE THIS VALUE WITH YOUR LICENSE KEY (ENTERPRISE EDITION ONLY) #####
```
3. To validate the license by using a certificate, update the `cosmosdb/docker-compose-ledger.yml` and `cosmosdb/docker-compose-auditor.yml` files as follows. If you're using a trial license, skip this step.
- Before changing the certificate file path (default configuration):
```yaml
# docker-compose-ledger.yml
services:
scalardl-ledger:
volumes:
- ./ledger.properties:/scalar/ledger/ledger.properties.tmpl
- ../fixture/ledger-key.pem:/scalar/ledger-key.pem
- ../fixture/trial-license-cert.pem:/scalar/license-cert.pem
# If you have a commercial license key, you must use `commercial-license-cert.pem` instead of `trial-license-cert.pem`.
# - ../fixture/commercial-license-cert.pem:/scalar/license-cert.pem
```
```yaml
# docker-compose-auditor.yml
services:
scalardl-auditor:
volumes:
- ./auditor.properties:/scalar/auditor/auditor.properties.tmpl
- ../fixture/auditor-key.pem:/scalar/auditor-key.pem
- ../fixture/trial-license-cert.pem:/scalar/license-cert.pem
# If you have a commercial license key, you must use `commercial-license-cert.pem` instead of `trial-license-cert.pem`.
# - ../fixture/commercial-license-cert.pem:/scalar/license-cert.pem
```
- After changing the certificate file path:
```yaml
# docker-compose-ledger.yml
services:
scalardl-ledger:
volumes:
- ./ledger.properties:/scalar/ledger/ledger.properties.tmpl
- ../fixture/ledger-key.pem:/scalar/ledger-key.pem
# - ../fixture/trial-license-cert.pem:/scalar/license-cert.pem
# If you have a commercial license key, you must use `commercial-license-cert.pem` instead of `trial-license-cert.pem`.
- ../fixture/commercial-license-cert.pem:/scalar/license-cert.pem
```
```yaml
# docker-compose-auditor.yml
services:
scalardl-auditor:
volumes:
- ./auditor.properties:/scalar/auditor/auditor.properties.tmpl
- ../fixture/auditor-key.pem:/scalar/auditor-key.pem
# - ../fixture/trial-license-cert.pem:/scalar/license-cert.pem
# If you have a commercial license key, you must use `commercial-license-cert.pem` instead of `trial-license-cert.pem`.
- ../fixture/commercial-license-cert.pem:/scalar/license-cert.pem
```
Start up ScalarDL
You can start using ScalarDL Ledger and Auditor by following the steps below:
1. Configure Cosmos DB for NoSQL.
To use Azure Cosmos DB for NoSQL, you must have an Azure account. If you don't have an Azure account, visit [Create an Azure Cosmos DB account](https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/quickstart-portal#create-account).
After setting up Cosmos DB for NoSQL, modify the following items in `cosmodb/ledger.properties` and `cosmodb/auditor.properties` based on your configuration of Cosmos DB for NoSQL.
```properties
scalar.db.contact_points=
scalar.db.password=
```
2. Load the database schema for ScalarDL Ledger and Auditor by running the following command:
```console
docker compose -f cosmosdb/docker-compose-auditor.yml up -d scalardl-ledger-schema-loader
docker compose -f cosmosdb/docker-compose-auditor.yml up -d scalardl-auditor-schema-loader
```
3. Run ScalarDL Ledger, Auditor, and its dependent components by running the following command:
```console
docker compose -f cosmosdb/docker-compose-auditor.yml up -d
```
## Set up authentication between Ledger and Auditor (digital signature authentication only)
When using digital signature authentication, you need to register the Ledger certificate and the Auditor certificate with each other. If you are using HMAC authentication, skip this step.
To register the Ledger and Auditor certificates, you need to run the client commands, which are included in the Client SDK. To get the Client SDK, see [Download the Client SDK](getting-started.mdx#download-the-client-sdk). After downloading it, run the following commands:
```console
scalardl register-cert --properties
scalardl register-cert --properties
```
Specifically, in the `scalardl-samples` environment, you can register the certificates by running the following commands with the sample property files found in `./fixture/`:
```console
client/bin/scalardl register-cert --properties ./fixture/ledger.as.client.properties
client/bin/scalardl register-cert --properties ./fixture/auditor.as.client.properties
```
:::warning
Do not use the sample private key and certificate in production environments. For details about getting your own certificate, see [How to Get a Certificate](ca/caclient-getting-started.mdx).
:::
## Set up clients for the HashStore, TableStore, or Ledger abstractions
Depending on the abstraction that your application is based on (specifically, HashStore, TableStore, or Ledger), the setup instructions are different. Select an abstraction and follow the instructions.
Bootstrap HashStore clients
When creating `HashStoreClientService` in your application, the client certificate or secret key and the necessary contracts for using HashStore are automatically registered based on the configuration in `ClientConfig`. Thus, you don't have to manually bootstrap HashStore. If you would like to do it manually, for example, for testing purposes, download the HashStore Client SDK by following [Download the Client SDK](getting-started-hashstore.mdx#download-the-client-sdk) and run the following command.
```console
scalardl-hashstore bootstrap --properties
```
Bootstrap TableStore clients
When creating `TableStoreClientService` in your application, the client certificate or secret key and the necessary contracts for using TableStore are automatically registered based on the configuration in `ClientConfig`. Thus, you don't have to manually bootstrap TableStore. If you would like to do it manually, for example, for testing purposes, download the TableStore Client SDK by following [Download the Client SDK](getting-started-tablestore.mdx#download-the-client-sdk) and run the following command.
```console
scalardl-tablestore bootstrap --properties
```
Bootstrap Ledger clients
Register the client identity and system contracts by running the following `bootstrap` command:
```console
scalardl bootstrap --properties
```
Specifically, in the `scalardl-samples` environment, you can use the command located at `client/bin/scalardl` with the sample property files found in `./fixture/` as follows.
```console
client/bin/scalardl bootstrap --properties ./fixture/client.properties
```
The bootstrap command registers the client certificate or secret key based on the authentication configuration done in [Decide on an authentication method](#decide-on-an-authentication-method).
You can also bootstrap by using in the [ScalarDL Java Client SDK](how-to-write-applications.mdx#use-the-scalardl-client-sdk).
Register contracts and functions
You can register contracts by using the `register-contract` command.
```console
scalardl register-contract --properties --contract-id --contract-binary-name --contract-class-file
```
You can register functions by using the `register-function` command.
```console
scalardl register-function --properties --function-id --function-binary-name --function-class-file
```
You can also register contracts and functions by using in the [ScalarDL Java Client SDK](how-to-write-applications.mdx#use-the-scalardl-client-sdk).
## Run your application
Now that you have registered the necessary identities and contracts, you can run your application that integrates ScalarDL.
## See also
For details about each command, see the following command references:
- [ScalarDL Client Command Reference](scalardl-command-reference.mdx)
- [ScalarDL HashStore Command Reference](scalardl-hashstore-command-reference.mdx)
- [ScalarDL TableStore Command Reference](scalardl-tablestore-command-reference.mdx)
================================================
FILE: docs/how-to-run-applications.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Run a ScalarDL Application Through ScalarDL Ledger
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import JavadocLink from "/src/theme/JavadocLink.js";
This guide explains how to run a ScalarDL application through ScalarDL Ledger. This document assumes that you have already tried one of the [Quickstart](quickstart-overview.mdx) tutorials and created your application that integrates ScalarDL by using client SDKs by referring to the [Write an Application](develop-write-an-application-overview.mdx) guides.
## Decide on configurations
Before running ScalarDL applications through Ledger, you first need to configure Ledger and the client that interacts with Ledger.
There are several important options that you must set and decisions to make as described below.
### Disable Auditor
You must disable Auditor since you'll be running your applications through only Ledger. Disabling Auditor has to be done in the client and Ledger configurations as follows.
- In the client configuration, set `scalar.dl.client.auditor.enabled` to `false`. (Since `false` is the default value, you can choose to omit this property.)
- In the Ledger configuration, set `scalar.dl.ledger.auditor.enabled` to `false`. (Since `false` is the default value, you can choose to omit this property.)
:::note
If you are using the `scalardl-samples` environment, see the `ledger.properties` file for the corresponding storage.
:::
For details about the configurations, see the following:
- [Client configurations](configurations.mdx#client-configurations)
- [Ledger configurations](configurations.mdx#ledger-configurations)
### Decide on an authentication method
You must decide which authentication method to use for clients: digital signature or HMAC. As a simple comparison, the digital-signature method provides non-repudiation in addition to authentication but is slow, whereas the HMAC method provides only authentication but is fast.
You can configure an authentication method as follows. The same method (`digital-signature` or `hmac`) must be configured in both the client and Ledger.
- In the client configuration, set `scalar.dl.client.authentication.method` to `digital-signature` or `hmac` (depending on which method you choose).
- In the Ledger configuration, set `scalar.dl.ledger.authentication.method` to `digital-signature` or `hmac` (depending on which method you choose).
You also need to prepare some secret information. If you're using the digital-signature method you need to prepare a certificate and a private key. If you're using the HMAC method, you need to prepare a secret key. For more details about the authentication in ScalarDL, check out the [ScalarDL Authentication Guide](./authentication.mdx).
For details about the configurations, see the following:
- [Client configurations](configurations.mdx#client-configurations)
- [Ledger configurations](configurations.mdx#ledger-configurations)
### Configure your database
Ledger uses ScalarDB to interact with databases, which enables you to run ScalarDL on top of various databases. So, you need to decide on a database that ScalarDB supports based on your applications' requirements and configure several ScalarDB parameters.
For details about the ScalarDB parameters, see also [ScalarDB Configurations](https://scalardb.scalar-labs.com/docs/latest/configurations/).
#### Underlying database
You can configure which database to use as follows:
- In the Ledger configuration, set `scalar.db.storage`, `scalar.db.contact_points`, `scalar.db.username`, and `scalar.db.password` to the appropriate values based on the database that you'll be using.
For databases and their versions supported by ScalarDL via ScalarDB, see [Requirements](requirements.mdx#databases).
:::warning
If your applications read and write a table through the Function feature, and the table is also directly accessed from ScalarDB applications, you need to properly configure the database chosen here. Specifically, both ScalarDL and ScalarDB applications must refer to the same Coordinator table to guarantee consistency.
:::
#### Isolation level
Ledger relies on the [Consensus Commit](https://scalardb.scalar-labs.com/docs/latest/consensus-commit/) transaction manager of ScalarDB to manage transactions. The transaction manager is responsible for guaranteeing the isolation property of transactions, which is crucial for ensuring the consistency and correctness of transactions.
You can configure the isolation level of Ledger as follows. If you are unsure about which isolation level to use, use `SERIALIZABLE`.
- In the Ledger configuration, set `scalar.db.consensus_commit.isolation_level` to an isolation level of your choice. The default value is `SNAPSHOT`.
#### Limitations
While ScalarDL leverages ScalarDB, the following ScalarDB features are not compatible with the consistency guarantee mechanism of ScalarDL:
- [Group commit for the Coordinator table](https://scalardb.scalar-labs.com/docs/latest/api-guide/#group-commit-for-the-coordinator-table) (`scalar.db.consensus_commit.coordinator.group_commit.enabled` must be `false`.)
- Coordinator write omission optimization in [Performance-related configurations](https://scalardb.scalar-labs.com/docs/latest/configurations#performance-related-configurations) (`scalar.db.consensus_commit.coordinator.write_omission_on_read_only.enabled` must be `false`.)
### Decide which other configurations to use
You can also apply other configurations, such as TLS and gRPC configurations, for the client and Ledger. For details about the configurations, see the following:
- [Client configurations](configurations.mdx#client-configurations)
- [Ledger configurations](configurations.mdx#ledger-configurations)
## Start Ledger
After configuring Ledger and the client, you need to start up Ledger.
For details on how to locally start up Ledger by using Docker Compose, see [Start up ScalarDL with your preferred database](getting-started.mdx#start-up-scalardl-with-your-preferred-database). For how to start up Ledger in local or cloud-based Kubernetes environments, see [Deploy ScalarDL in your local Kubernetes environment](deploy-local-environment-overview.mdx) or [Deploy ScalarDL in a cloud-based Kubernetes environment](deploy-managed-kubernetes-environment-overview.mdx), respectively.
## Set up clients for the HashStore, TableStore, or Ledger abstractions
Depending on the abstraction that your application is based on (specifically, HashStore, TableStore, or Ledger), the setup instructions are different. Select an abstraction and follow the instructions.
Bootstrap HashStore clients
When creating `HashStoreClientService` in your application, the client certificate or secret key and the necessary contracts for using HashStore are automatically registered based on the configuration in `ClientConfig`. Thus, you don't have to manually bootstrap HashStore clients. If you would like to do it manually, for example, for testing purposes, download the HashStore Client SDK by following [Download the Client SDK](getting-started-hashstore.mdx#download-the-client-sdk) and run the following command.
```console
scalardl-hashstore bootstrap --properties
```
Bootstrap TableStore clients
When creating `TableStoreClientService` in your application, the client certificate or secret key and the necessary contracts for using TableStore are automatically registered based on the configuration in `ClientConfig`. Thus, you don't have to manually bootstrap TableStore clients. If you would like to do it manually, for example, for testing purposes, download the TableStore Client SDK by following [Download the Client SDK](getting-started-tablestore.mdx#download-the-client-sdk) and run the following command.
```console
scalardl-tablestore bootstrap --properties
```
Download the client commands
When you set up Ledger clients, you need to run the client commands, which are included in the Client SDK. To get the Client SDK, see [Download the Client SDK](getting-started.mdx#download-the-client-sdk).
Bootstrap Ledger clients
Register the client identity and system contracts by running the following `bootstrap` command:
```console
scalardl bootstrap --properties
```
The bootstrap command registers the client certificate or secret key based on the authentication configuration done in [Decide on an authentication method](#decide-on-an-authentication-method).
You can also bootstrap by using in the [ScalarDL Java Client SDK](how-to-write-applications.mdx#use-the-scalardl-client-sdk).
Register contracts and functions
You can register contracts by using the `register-contract` command.
```console
scalardl register-contract --properties --contract-id --contract-binary-name --contract-class-file
```
You can register functions by using the `register-function` command.
```console
scalardl register-function --properties --function-id --function-binary-name --function-class-file
```
You can also register contracts and functions by using in the [ScalarDL Java Client SDK](how-to-write-applications.mdx#use-the-scalardl-client-sdk).
## Run your application
Now that you have registered the necessary identities and contracts, you can run your application that integrates ScalarDL.
## See also
For details about each command, see the following command references:
- [ScalarDL Client Command Reference](scalardl-command-reference.mdx)
- [ScalarDL HashStore Command Reference](scalardl-hashstore-command-reference.mdx)
- [ScalarDL TableStore Command Reference](scalardl-tablestore-command-reference.mdx)
================================================
FILE: docs/how-to-write-applications-with-generic-contracts.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Write a ScalarDL Application with Generic Contracts
import JavadocLink from "/src/theme/JavadocLink.js";
:::tip
Although generic contracts were introduced in ScalarDL 3.10, HashStore, released in ScalarDL 3.12, provides a higher-level abstraction that wraps generic contracts. For most use cases, using HashStore is simpler and more efficient than using generic contracts directly. For details, see [Write a ScalarDL Application with the HashStore Abstraction](./how-to-write-applications-with-hashstore.mdx) in the latest version of ScalarDL.
:::
This document explains how to write ScalarDL applications with generic contracts. You will learn how to interact with ScalarDL in your applications, handle errors, and validate your data when using generic contracts in ScalarDL.
## Use the ScalarDL Client SDK for generic contracts
You have two options to interact with ScalarDL when using generic contracts:
- Using [commands](scalardl-command-reference.mdx), as shown in [Use Generic Contracts and Functions](use-generic-contracts.mdx)
- Using the [Java Client SDK](https://javadoc.io/doc/com.scalar-labs/scalardl-java-client-sdk/latest/index.html)
Using commands is convenient because you don't need to write applications. However, they invoke a process for each execution, which is slow, so they are mainly for quickly testing generic contracts. Instead, using the Client SDK is usually recommended when you write ScalarDL-based applications because it is more efficient.
The Client SDK is available on [Maven Central](https://search.maven.org/search?q=a:scalardl-java-client-sdk). You can install it in your application by using a build tool such as Gradle. For example, in Gradle, you can add the following dependency to `build.gradle`, replacing `VERSION` with the version of ScalarDL that you want to use.
```gradle
dependencies {
implementation group: 'com.scalar-labs', name: 'scalardl-java-client-sdk', version: ''
}
```
The Client SDK APIs for generic contracts are provided by a service class called . The following is a code snippet that shows how to use `GenericContractClientService` to execute a contract.
```java
// ClientServiceFactory should always be reused.
ClientServiceFactory factory = new ClientServiceFactory();
// ClientServiceFactory creates a new GenericContractClientService object in every create method call
// but reuses the internal objects and connections as much as possible for better performance and resource usage.
GenericContractClientService service = factory.createForGenericContracts(new ClientConfig(new File(properties));
try {
// create an application-specific argument that matches the generic contract specification
JsonNode jsonArgument = ...;
ContractExecutionResult result = service.executeContract(contractId, jsonArgument);
result.getContractResult().ifPresent(System.out::println);
} catch (ClientException e) {
System.err.println(e.getStatusCode());
System.err.println(e.getMessage());
}
factory.close();
```
You should always use `ClientServiceFactory` to create `GenericContractClientService` objects. `ClientServiceFactory` caches objects that are required to create `GenericContractClientService` and reuses them on the basis of the given configurations, so `ClientServiceFactory` object should always be reused.
`GenericContractClientService` is a thread-safe client that interacts with ScalarDL components, like Ledger and Auditor, to register certificates, register contracts, execute contracts, and validate data. When you execute a generic contract, you need to specify a `JsonNode` argument. For details about the specification of the input argument, see [Generic Contracts and Functions Reference Guide](generic-contracts-reference.mdx).
:::warning
Do not register and execute your custom contracts through `GenericContractClientService`. Using the generic contracts and your custom contracts together is not supported because the proper asset management cannot be guaranteed.
:::
For more information about `ClientServiceFactory` and `GenericContractClientService`, see the [`scalardl-java-client-sdk` Javadoc](https://javadoc.io/doc/com.scalar-labs/scalardl-java-client-sdk/latest/index.html).
## Handle errors
If an error occurs in your application, the Client SDK will return an exception with a status code and an error message with an error code. You should check the status code and the error code to identify the cause of the error. For details about the status code and the error codes, see [Status codes](how-to-write-applications.mdx#status-codes) and [Error codes](how-to-write-applications.mdx#error-codes).
### Implement error handling
The SDK throws when an error occurs. You can handle errors by catching the exception as follows:
```java
GenericContractClientService clientService = ...;
try {
// interact with ScalarDL through a ClientService object
} catch (ClientException) {
// e.getStatusCode() returns the status of the error
}
```
## Validate your data
In ScalarDL, you occasionally need to validate your data to make sure all the data is in a valid state. Since you can learn the basics of how ScalarDL validates your data in [Write a ScalarDL Application in Java](how-to-write-applications.mdx#validate-your-data), this section mainly describes the differences between the `validateLedger` method in the regular `ClientService` and the `validateLedger` or asset validation methods in `GenericContractClientService`.
When validating assets created by generic contracts, you need to specify the type of the asset and a list of keys to identify the asset or use wrapper methods prepared for each asset type.
:::note
Generic contracts internally assign a dedicated asset ID to an [asset record](data-modeling.mdx#asset-record) that represents an object of each authenticity management. The asset ID consists of a prefix for the asset type and keys; for example, a prefix `o_` and an object ID for `AssetType.OBJECT`. Therefore, you will see such raw asset IDs in `AssetProof` in `LedgerValidationResult`.
:::
### Object and collection authenticity management
Generic contracts for object and collection authenticity management create two types of assets: an object (`AssetType.OBJECT`) and a collection (`AssetType.COLLECTION`). For keys, you can specify the object ID or collection ID.
An example code for validating an object is as follows:
```java
GenericContractClientService service = ...
try {
LedgerValidationResult result =
service.validateLedger(AssetType.OBJECT, ImmutableList.of("an_object_ID"));
// You can also specify age range.
// LedgerValidationResult result =
// service.validateLedger(
// AssetType.OBJECT, ImmutableList.of("an_object_ID"), startAge, endAge);
} catch (ClientException e) {
}
```
You can also use the `validateObject()` and `validateCollection()` methods as follows:
```java
GenericContractClientService service = ...
try {
LedgerValidationResult objectResult = service.validateObject("an_object_ID");
LedgerValidationResult collectionResult = service.validateCollection("a_collection_ID");
} catch (ClientException e) {
}
```
### Table authenticity management
Generic contracts for table authenticity management (table-oriented generic contracts) create three types of assets: a table schema (`AssetType.TABLE`), a record (`AssetType.RECORD`), and an index record (`AssetType.INDEX`). For the table schema, you must specify a table name as a key. For the record and index record, you must specify a table name, a primary or index key column name, and the value.
In table-oriented generic contracts, JSON string, number, and boolean values can be specified as primary and index keys, and they are internally converted to a string when being used as asset IDs based on certain rules. You can use the `validateTableSchema()`, `validateRecord()`, and `validateIndexRecord()` methods to validate a table schema, record, and index record without worrying about the rules as follows:
```java
GenericContractClientService service = ...
try {
LedgerValidationResult tableResult = service.validateTableSchema("a_table_name");
LedgerValidationResult recordResult =
service.validateRecord(
"a_table_name", "a_primary_key_column_name", TextNode.valueOf("a_value"));
LedgerValidationResult indexResult =
service.validateIndexRecord("a_table_name", "an_index_key_column_name", IntNode.valueOf(1));
} catch (ClientException e) {
}
```
## Use other languages
To interact with ScalarDL in languages other than Java, you can use ScalarDL Gateway.
:::note
Documentation for ScalarDL Gateway is currently being created and will be ready in the near future.
:::
================================================
FILE: docs/how-to-write-applications-with-hashstore.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Write a ScalarDL Application with the HashStore Abstraction
import JavadocLink from "/src/theme/JavadocLink.js";
This document explains how to write ScalarDL applications with the HashStore abstraction. You will learn how to use ScalarDL HashStore in your applications, handle errors, and validate your data.
## Use the ScalarDL HashStore Client SDK
You have two options to use ScalarDL HashStore:
- Using [commands](scalardl-hashstore-command-reference.mdx), as shown in [Get Started with ScalarDL HashStore](getting-started-hashstore.mdx)
- Using the [HashStore Java Client SDK](https://javadoc.io/doc/com.scalar-labs/scalardl-hashstore-java-client-sdk/)
Using commands is a convenient way to try HashStore without writing an application. For building HashStore-based applications, however, the HashStore Client SDK is recommended, as it runs more efficiently without launching a separate process for each operation.
The HashStore Client SDK is available on [Maven Central](https://central.sonatype.com/artifact/com.scalar-labs/scalardl-hashstore-java-client-sdk). You can install it in your application by using a build tool such as Gradle. For example, in Gradle, you can add the following dependency to `build.gradle`, replacing `VERSION` with the version of ScalarDL that you want to use.
```gradle
dependencies {
implementation group: 'com.scalar-labs', name: 'scalardl-hashstore-java-client-sdk', version: ''
}
```
The Client SDK APIs for HashStore are provided by a service class called . The following is a code snippet that shows how to use `HashStoreClientService` to manage objects and collections. `HashStoreClientService` provides the same functionalities as the HashStore client commands shown in [Get Started with ScalarDL HashStore](getting-started-hashstore.mdx).
```java
// HashStoreClientServiceFactory should always be reused.
HashStoreClientServiceFactory factory = new HashStoreClientServiceFactory();
// HashStoreClientServiceFactory creates a new HashStoreClientService object in every create
// method call but reuses the internal objects and connections as much as possible for better
// performance and resource usage.
HashStoreClientService service = factory.create(new ClientConfig(new File(properties)));
try {
// put the hash value of an object with metadata.
String objectId = ...;
String hash = ...;
JsonNode metadata = ...;
ExecutionResult result = service.putObject(objectId, hash, metadata);
} catch (ClientException e) {
System.err.println(e.getStatusCode());
System.err.println(e.getMessage());
}
factory.close();
```
:::note
You should always use `HashStoreClientServiceFactory` to create `HashStoreClientService` objects. `HashStoreClientServiceFactory` caches objects that are required to create `HashStoreClientService` and reuses them on the basis of the given configurations, so the `HashStoreClientServiceFactory` object should always be reused.
:::
For more information about `HashStoreClientServiceFactory` and `HashStoreClientService`, see the [`scalardl-hashstore-java-client-sdk` Javadoc](https://javadoc.io/doc/com.scalar-labs/scalardl-hashstore-java-client-sdk/latest/index.html).
## Handle errors
If an error occurs in your application, the Client SDK will return an exception with a status code and an error message with an error code. You should check the status code and the error code to identify the cause of the error. For details about the status code and the error codes, see [Status codes](how-to-write-applications.mdx#status-codes) and [Error codes](how-to-write-applications.mdx#error-codes).
### Implement error handling
The SDK throws when an error occurs. You can handle errors by catching the exception as follows:
```java
HashStoreClientService service = ...;
try {
// interact with ScalarDL HashStore through a HashStoreClientService object
} catch (ClientException e) {
// e.getStatusCode() returns the status of the error
}
```
## Validate your data
In ScalarDL, you occasionally need to validate your data to make sure all the data is in a valid state. Since you can learn the basics of how ScalarDL validates your data in [Write a ScalarDL Application in Java](how-to-write-applications.mdx#validate-your-data), this section mainly describes how you can perform the validation in HashStore.
When validating [assets](data-modeling.mdx#asset) (objects and collections here) in HashStore, you only need to specify an object ID or a collection ID. An example code for validating an object is as follows:
```java
HashStoreClientService service = ...
try {
LedgerValidationResult result = service.validateObject("an_object_ID");
// You can also specify age range.
// LedgerValidationResult result = service.validateObject("an_object_ID", startAge, endAge);
} catch (ClientException e) {
}
```
An example code for validating a collection is as follows:
```java
HashStoreClientService service = ...
try {
LedgerValidationResult result = service.validateCollection("a_collection_ID");
// You can also specify age range.
// LedgerValidationResult result = service.validateCollection("a_collection_ID", startAge, endAge);
} catch (ClientException e) {
}
```
:::note
- The error-handling behavior of the validation methods differs when using Ledger compared to when using both Ledger and Auditor. For details, see [Validate your data](how-to-write-applications.mdx#validate-your-data).
- HashStore internally assigns a dedicated asset ID to an asset that represents an object or a collection. The asset ID consists of a prefix to show the asset type and a key; for example, a prefix `o_` and an object ID for objects, and a prefix `c_` and a collection ID for collections are used. You will see such raw asset IDs in `AssetProof` in `LedgerValidationResult`.
:::
================================================
FILE: docs/how-to-write-applications-with-tablestore.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Write a ScalarDL Application with the TableStore Abstraction
import JavadocLink from "/src/theme/JavadocLink.js";
This document explains how to write ScalarDL applications with the TableStore abstraction. You will learn how to use ScalarDL TableStore in your applications, handle errors, and validate your data.
## Use the ScalarDL TableStore Client SDK
You have two options to use ScalarDL TableStore:
- Using [commands](scalardl-tablestore-command-reference.mdx), as shown in [Get Started with ScalarDL TableStore](getting-started-tablestore.mdx)
- Using the [TableStore Java Client SDK](https://javadoc.io/doc/com.scalar-labs/scalardl-tablestore-java-client-sdk/)
Using commands is a convenient way to try TableStore without writing an application. For building TableStore-based applications, however, the TableStore Client SDK is recommended, as it runs more efficiently without launching a separate process for each operation.
The TableStore Client SDK is available on [Maven Central](https://central.sonatype.com/artifact/com.scalar-labs/scalardl-tablestore-java-client-sdk). You can install it in your application by using a build tool such as Gradle. For example, in Gradle, you can add the following dependency to `build.gradle`, replacing `VERSION` with the version of ScalarDL that you want to use.
```gradle
dependencies {
implementation group: 'com.scalar-labs', name: 'scalardl-tablestore-java-client-sdk', version: ''
}
```
The Client SDK APIs for TableStore are provided by a service class called . The following is a code snippet that shows how to use `TableStoreClientService` to manage table authenticity. `TableStoreClientService` provides the same functionalities as the TableStore client commands shown in [Get Started with ScalarDL TableStore](getting-started-tablestore.mdx).
```java
// TableStoreClientServiceFactory should always be reused.
TableStoreClientServiceFactory factory = new TableStoreClientServiceFactory();
// TableStoreClientServiceFactory creates a new TableStoreClientService object in every create
// method call but reuses the internal objects and connections as much as possible for better
// performance and resource usage.
TableStoreClientService service = factory.create(new ClientConfig(new File(properties)));
try {
// execute a SQL statement.
String sql = "SELECT * FROM employee WHERE id = '1001'";
ExecutionResult result = service.executeStatement(sql);
result.getResult().ifPresent(System.out::println);
} catch (ClientException e) {
System.err.println(e.getStatusCode());
System.err.println(e.getMessage());
}
factory.close();
```
:::note
You should always use `TableStoreClientServiceFactory` to create `TableStoreClientService` objects. `TableStoreClientServiceFactory` caches objects that are required to create `TableStoreClientService` and reuses them on the basis of the given configurations, so the `TableStoreClientServiceFactory` object should always be reused.
:::
For more information about `TableStoreClientServiceFactory` and `TableStoreClientService`, see the [`scalardl-tablestore-java-client-sdk` Javadoc](https://javadoc.io/doc/com.scalar-labs/scalardl-tablestore-java-client-sdk/latest/index.html).
## Handle errors
If an error occurs in your application, the Client SDK will return an exception with a status code and an error message with an error code. You should check the status code and the error code to identify the cause of the error. For details about the status code and the error codes, see [Status codes](how-to-write-applications.mdx#status-codes) and [Error codes](how-to-write-applications.mdx#error-codes).
### Implement error handling
The SDK throws when an error occurs. You can handle errors by catching the exception as follows:
```java
TableStoreClientService service = ...;
try {
// interact with ScalarDL TableStore through a TableStoreClientService object
} catch (ClientException e) {
// e.getStatusCode() returns the status of the error
}
```
## Validate your data
In ScalarDL, you occasionally need to validate your data to make sure all the data is in a valid state. Since you can learn the basics of how ScalarDL validates your data in [Write a ScalarDL Application in Java](how-to-write-applications.mdx#validate-your-data), this section mainly describes how you can perform the validation in TableStore.
When validating [assets](data-modeling.mdx#asset) (records, index records, and table schema here) in TableStore, you need to specify a table and a primary or index key if necessary. An example code for validating assets in TableStore is as follows:
```java
TableStoreClientService service = ...
String tableName = "employee";
String primaryKeyColumn = "id";
String indexKeyColumn = "department";
TextNode primaryKeyValue = TextNode.valueOf("1001");
TextNode indexKeyValue = TextNode.valueOf("sales");
try {
LedgerValidationResult result1 =
service.validateRecord(tableName, primaryKeyColumn, primaryKeyValue);
LedgerValidationResult result2 =
service.validateIndexRecord(tableName, indexKeyColumn, indexKeyValue);
LedgerValidationResult result3 = service.validateTableSchema(tableName);
// You can also specify age range.
// LedgerValidationResult result1 =
// service.validateRecord(tableName, primaryKeyColumn, primaryKeyValue, startAge, endAge);
// LedgerValidationResult result2 =
// service.validateIndexRecord(tableName, indexKeyColumn, indexKeyValue, startAge, endAge);
// LedgerValidationResult result3 = service.validateTableSchema(tableName, startAge, endAge);
} catch (ClientException e) {
}
```
:::note
- The error-handling behavior of the validation methods differs when using Ledger compared to when using both Ledger and Auditor. For details, see [Validate your data](how-to-write-applications.mdx#validate-your-data).
- TableStore internally assigns a dedicated asset ID to an asset that represents a record, an index record, and a table schema. The asset ID consists of a prefix to show the asset type and a key; for example, a prefix `rec_`, a primary-key column name, and a primary-key value are used for asset IDs of records. You will see such raw asset IDs in `AssetProof` in `LedgerValidationResult`.
:::
================================================
FILE: docs/how-to-write-applications.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Write a ScalarDL Application with the Ledger Abstraction
import JavadocLink from "/src/theme/JavadocLink.js";
This document explains how to write ScalarDL applications with the Ledger abstraction. You will learn how to integrate ScalarDL into your applications, handle errors, and validate your data.
## Use the ScalarDL Client SDK
You have two options to interact with ScalarDL: using [commands](scalardl-command-reference.mdx) as shown in the [getting started guide](getting-started.mdx) or using the [Java Client SDK](https://javadoc.io/doc/com.scalar-labs/scalardl-java-client-sdk/latest/index.html).
Using commands is convenient because you don't need to write applications. However, they invoke a process for each execution, which is slow, so they are mainly for quickly testing your contracts. Instead, using the Java Client SDK is usually recommended when you write ScalarDL-based applications because it is more efficient.
The Java Client SDK is available on [Maven Central](https://search.maven.org/search?q=a:scalardl-java-client-sdk). You can install it in your application by using a build tool such as Gradle. For example, in Gradle, you can add the following dependency to `build.gradle`, replacing `VERSION` with the version of ScalarDL that you want to use.
```gradle
dependencies {
implementation group: 'com.scalar-labs', name: 'scalardl-java-client-sdk', version: ''
}
```
The Java Client SDK APIs are provided by a service class called . The following is a code snippet that shows how to use `ClientService` to execute a contract.
```java
// ClientServiceFactory should always be reused.
ClientServiceFactory factory = new ClientServiceFactory();
// ClientServiceFactory creates a new ClientService object in every create method call
// but reuses the internal objects and connections as much as possible for better performance and resource usage.
ClientService service = factory.create(new ClientConfig(new File(properties));
try {
// create an application-specific argument that matches your contract
JsonNode jsonArgument = ...;
ContractExecutionResult result = service.executeContract(contractId, jsonArgument);
result.getContractResult().ifPresent(System.out::println);
} catch (ClientException e) {
System.err.println(e.getStatusCode());
System.err.println(e.getMessage());
}
factory.close();
```
You should always use `ClientServiceFactory` to create `ClientService` objects. `ClientServiceFactory` caches objects that are required to create `ClientService` and reuses them on the basis of the given configurations, so `ClientServiceFactory` object should always be reused.
`ClientService` is a thread-safe client that interacts with ScalarDL components, like Ledger and Auditor, to register certificates, register contracts, execute contracts, and validate data. When you execute a contract, you need to specify the corresponding argument type of the contract. For example, if your contract extends `JacksonBasedContract`, you need to pass the `JsonNode` argument when you execute the contract.
For more information, please take a look at [Javadoc](https://javadoc.io/doc/com.scalar-labs/scalardl-java-client-sdk/latest/index.html).
## Handle errors
If an error occurs in your application, the Client SDK will return an exception with a status code and an error message with an error code. You should check the status code and the error code to identify the cause of the error.
### Implement error handling
The SDK throws when an error occurs. You can handle errors by catching the exception as follows:
```java
ClientService clientService = ...;
try {
// interact with ScalarDL through a ClientService object
} catch (ClientException) {
// e.getStatusCode() returns the status of the error
}
```
### Status codes
Status codes explain what kind of status request you ended up with. The status codes in ScalarDL are grouped into five classes, which are similar to HTTP status codes:
- Successful statuses (200-299)
- The 2xx class of status code indicates that the request has succeeded.
- Validation errors (300-399)
- The 3xx class of status code indicates that an asset record in the database is in an invalid state and possibly tampered.
- User errors (400-499)
- The 4xx class of status code indicates that the server cannot or will not process the request due to an issue that is perceived to be a client error, like when a signature or key pair is invalid, an execution error occurs inside a contract, or a contract is not found.
- Server errors (500-599)
- The 5xx class of status code indicates that the server, either on the Ledger side or the Auditor side, encountered an unexpected condition that prevented it from fulfilling the request.
- Client errors (600-699)
- The 6xx class of status code indicates that the client encountered an unexpected condition that prevented it from fulfilling the request.
For more details, see .
### Error codes
Error codes explain more details about an error that a request encountered. For details about error codes, see the following:
- [ScalarDL Client Error Codes](scalardl-client-status-codes.mdx)
- [ScalarDL Ledger Error Codes](scalardl-ledger-status-codes.mdx)
- [ScalarDL Auditor Error Codes](scalardl-auditor-status-codes.mdx)
- [ScalarDL Common Error Codes](scalardl-common-status-codes.mdx)
## Validate your data
In ScalarDL, you occasionally need to validate your data to make sure all the data is in a valid state. A valid state varies depending on how you set up and configure ScalarDL.
When using only Ledger, the valid state means that the hash-chain structure where data is stored is valid. So, if a malicious user alters a part of the data, the alteration can be detected by the structural validation. However, if a malicious user alters the Ledger program itself, the alteration may not be able to be detected since, for example, the structural validation code can also be altered.
When using Ledger and Auditor, the valid state means that the data in Ledger and Auditor are not discrepant. So, even if a malicious user alters the Ledger program, the alteration is detected as long as Auditor is correct and the alteration affects the data or the output. Auditor checks for discrepancies for referenced and generated states of Ledger and Auditor in every execution; thus, those states are guaranteed to be correct at the time of execution.
Due to this difference, what the validation does differs when using Ledger compared to when using both Ledger and Auditor. When using only Ledger, the validation traverses assets to see if the assets can be re-computed and have a valid hash-chain structure. When using Ledger and Auditor, the validation checks for discrepancies between the states of Ledger and Auditor without centralized coordination.
Also, what and when to validate can be different. When using only Ledger, you should validate assets whenever you want them to be trustworthy since they are not validated without explicit validation. When using Ledger and Auditor, you should validate when you want to use assets that have not been read recently since assets that are read or written by contract execution are validated at execution time.
You can do validation by using the `validateLedger` method. However, the error-handling behavior differs when using Ledger compared to when using both Ledger and Auditor.
#### When using only Ledger
When using only Ledger, `validateLedger` does **not** throw an exception on validation failure. Instead, you must check the status code of the returned `LedgerValidationResult` to determine whether the data is valid.
```java
ClientService service = ...
try {
LedgerValidationResult result = service.validateLedger(assetId);
// You can also specify an age range.
// LedgerValidationResult result = service.validateLedger(assetId, startAge, endAge);
if (result.getCode() != StatusCode.OK) {
// Validation failed. The status code indicates the type of invalidity.
// For example, StatusCode.INVALID_OUTPUT means data has been tampered with.
System.err.println("Validation failed: " + result.getCode());
}
} catch (ClientException e) {
// An exception here indicates a system error (e.g., network issue),
// not a validation failure.
System.err.println(e.getStatusCode());
System.err.println(e.getMessage());
}
```
Common validation-related status codes include:
- `INVALID_HASH`: The hash value of an asset record differs from the expected value.
- `INVALID_PREV_HASH`: The previous hash value differs from the expected value.
- `INVALID_CONTRACT`: A previously executed contract produced an invalid asset record.
- `INVALID_OUTPUT`: The data value of an asset record differs from the expected value.
#### When using Ledger and Auditor
When using Ledger and Auditor, `validateLedger` throws a `ClientException` if it detects an inconsistency between Ledger and Auditor. You must catch the exception and check its status code.
```java
ClientService service = ...
try {
LedgerValidationResult result = service.validateLedger(assetId);
// You can also specify an age range.
// LedgerValidationResult result = service.validateLedger(assetId, startAge, endAge);
// If no exception is thrown, the data is consistent between Ledger and Auditor.
} catch (ClientException e) {
if (e.getStatusCode() == StatusCode.INCONSISTENT_STATES) {
// The states between Ledger and Auditor are inconsistent,
// which means data may have been tampered with.
System.err.println("Inconsistency detected: " + e.getMessage());
} else {
// Handle other errors (e.g., network issues, server errors).
System.err.println(e.getStatusCode());
System.err.println(e.getMessage());
}
}
```
The key status code for Auditor-based validation is:
- `INCONSISTENT_STATES`: The states between Ledger and Auditor are inconsistent, indicating possible tampering.
When using only Ledger, you can enhance the detection capability by using information called Asset Proof. When using Ledger and Auditor, you do not need to use Asset Proof explicitly, but Auditor internally uses it to achieve the Byzantine-fault detection feature. For more details about Auditor, see [ScalarDL Design](design.mdx).
### What is Asset Proof?
Asset Proof in ScalarDL is a set of information about an asset record and used as evidence of the existence of the asset record. It is composed of the following items:
- ID of an asset record
- Age of the asset record
- Nonce of the execution request that creates the asset record
- Input (a list of the \ pairs referenced) to create the asset record
- A cryptographic hash of the asset record
- A cryptographic hash of the previous age's asset record, if any
- The digital signature of the above entries
#### Benefits of Asset Proof
Since Asset Proof is evidence at the time of execution by Ledger, it is difficult for Ledger to tamper data after the evidence is created because the Asset Proofs and Ledger states would be diverged. Thus, making use of Asset Proof appropriately could reduce the risk of data tampering.
#### How to access Asset Proof from your applications
You can get from the result of the `executeContract` method of the Client SDK. An Asset Proof can be validated if it is not tampered and it is from Ledger by verifying the signature.
Storing Asset Proofs outside of a domain in which Ledger runs is recommended. This is so that malicious activities in one domain can be detected by the other domain. Storing Asset Proofs in cloud storages for ease of management is also worth considering.
The Asset Proofs obtained in execution can be used when you do `validateLedger`. `validateLedger` also returns the Asset Proof of a specified asset record after doing Ledger-side validation. Then, the client can check if the Asset Proof is the same as the one that was previously returned from Ledger.
## Use other languages
To interact with ScalarDL in languages other than Java, you can use ScalarDL Gateway.
:::note
Documentation for ScalarDL Gateway is currently being created and will be ready in the near future.
:::
================================================
FILE: docs/how-to-write-contract.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# A Guide on How to Write a Good Contract for ScalarDL
import JavadocLink from '/src/theme/JavadocLink.js';
This document sets out some guidelines for writing contracts for ScalarDL.
## What is a contract for ScalarDL ?
A contract (a.k.a Smart Contract) for ScalarDL is a Java program extending predefined base contracts written for implementing single business logic. A contract and its arguments are digitally-signed with the contract owner's private key and passed to the ScalarDL. This mechanism allows the contract only to be executed by the owner and makes it possible for the system to detect malicious activity such as data tampering.
Before looking at this document, please check the [Getting Started with ScalarDL](getting-started.mdx) to understand what ScalarDL is and its basic terminologies.
## Write a simple contract
Let's take a closer look at the `StateUpdater` contract example to better understand how to write a contract.
```java
public class StateUpdater extends JacksonBasedContract {
@Nullable
@Override
public JsonNode invoke(Ledger ledger, JsonNode argument, @Nullable JsonNode properties) {
if (!argument.has("asset_id") || !argument.has("state")) {
// ContractContextException is the only throwable exception in a contract and
// it should be thrown when a contract faces some non-recoverable error
throw new ContractContextException("please set asset_id and state in the argument");
}
String assetId = argument.get("asset_id").asText();
int state = argument.get("state").asInt();
Optional> asset = ledger.get(assetId);
if (!asset.isPresent() || asset.get().data().get("state").asInt() != state) {
ledger.put(assetId, getObjectMapper().createObjectNode().put("state", state));
}
return null;
}
}
```
### Base contracts
The internal representation of the Ledger data and Contract arguments is String. However, dealing with structured data with String is error-prone and not always easy. The base contracts define other easy-to-handle data types for the Ledger data and Contract arguments. They also manage serialization and deserialization between the data types and String.
For example, the above `StateUpdater` contract is based on one of the base contracts called `JacksonBasedContract`, which allows you to deal with the Ledger data and Contract arguments in [Jackson](https://github.com/FasterXML/jackson)'s [JsonNode](https://fasterxml.github.io/jackson-databind/javadoc/2.13/com/fasterxml/jackson/databind/JsonNode.html) format.
As of writing this, we provide four base contracts as shown below; however, using `JacksonBasedContract` is recommended to balance development productivity and performance well.
| Base Contract Class | Type of Contract Argument, Contract Properties, Contract Output, and Ledger Data | Library |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------- |
| (recommended) | [JsonNode](https://fasterxml.github.io/jackson-databind/javadoc/2.13/com/fasterxml/jackson/databind/JsonNode.html) | [Jackson](https://github.com/FasterXML/jackson) |
| | [JsonObject](https://javadoc.io/static/javax.json/javax.json-api/1.1.4/javax/json/JsonObject.html) | [JSONP](https://javaee.github.io/jsonp/) |
| | [String](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html) | Java Standard Libraries |
| (deprecated) | [JsonObject](https://javadoc.io/static/javax.json/javax.json-api/1.1.4/javax/json/JsonObject.html) | [JSONP](https://javaee.github.io/jsonp/) |
The old is still available, but it is now deprecated and will be removed in a later major version. So, it is highly recommended to use the above new (non-deprecated) contracts as a base contract.
### About the `invoke` arguments
As shown above, the overridden `invoke` method accepts for interacting with the underlying database, a [JsonNode](https://fasterxml.github.io/jackson-databind/javadoc/2.13/com/fasterxml/jackson/databind/JsonNode.html) for the contract argument, and an optional [JsonNode](https://fasterxml.github.io/jackson-databind/javadoc/2.13/com/fasterxml/jackson/databind/JsonNode.html) for contract properties.
The `Ledger` is a database abstraction that manages a set of assets, where each asset is composed of the history of a record identified by a key called `asset_id` and a historical version number called `age`. You can interact with the `Ledger` with `get`, `put`, and `scan` APIs. The `get` API is used to retrieve the latest asset record of a specified asset. The `put` API is used to append a new asset record to a specified asset. The `scan` API is used to traverse a specified asset. Note that you can only append an asset record to the ledger with this abstraction. Thus, it is always a good practice to design your data with the abstraction before writing a contract for ScalarDL.
The contract argument is a runtime argument for the contract specified by the requester. The contract argument is usually used to define runtime variables. For example in a banking application, you may have a Payment contract where a payer and a payee are passed to the contract as the argument every time it is executed.
The contract properties is static variables for the contract. It can be used to define contract's per-instance static variables.
For example in an agreement application, the business logic for the agreement can be defined as a general contract but the agreement conditions may vary depending on the actual application. The optional properties field allows you to define the agreement conditions such as quorum for each contract instance without hard-coding it in the contract.
### About the `StateUpdater` logic
The `StateUpdater` contract first checks if the argument has proper variables, matches with an application context, and throws `ContractContextException` if they are not adequately defined. `ContractContextException` is the only throwable exception from a contract, and it is used to let the system know not to retry the contract execution because requirements are not fully satisfied.
Then the contract retrieves an `asset_id` and `state` given from the requester and retrieves `asset` from the Ledger with the specified `asset_id`. And it updates the asset's state if the asset doesn't exist or the asset's state is different from the current state.
A contract might face some `RuntimeException` when interacting with the Ledger, but it shouldn't catch it in the contract. All the exceptions are treated properly by the ScalarDL executor.
This contract will just create or update the state of an specified asset, so it doesn't need to return anything to the requester. So in this case, it can return `null`. If you want to return something to a requester, you can return an arbitrary `JsonNode` when using `JacksonBasedContract`.
### Grouping assets
The value of `asset_id` can be arbitrarily defined but it is a good practice to have some rules when you want to group assets.
For example, if you want to group them in a certain generation, you can append some generation number to the assets like `{asset_id}-0`.
Or you can group them per organization by having some organization ID as a prefix like `{org-id}-{asset_id}`.
### Exception handling
Note that you should not do any exception handling in contracts except for throwing `ContractContextException` as mentioned above.
Thus, `Ledger` might throw some runtime (unchecked) exceptions in case it can not proceed for some reason, but the exceptions should not be caught. Exceptions are handled properly outside of contracts.
### Determinism
One very important thing to note when you write a contract for ScalarDL is that you have to make the contract deterministic. In other words, a contract must always produce the same output for a given particular input. This is because ScalarDL utilizes determinism to detect tampering.
For example, ScalarDL will lazily traverse assets and re-execute contracts to check if there is no discrepancy between the expected outcome and the actual data stored in the ledger. It also utilizes determinism to make the states of multiple independent ScalarDL components (i.e., Ledger and Auditor) the same.
One common way of creating a non-deterministic contract is to generate the time inside the contract and have the output including the ledger states somehow depend on this time. Such a contract will produce different outputs each time it is executed and makes the system unable to detect tampering. If you need to use the time in a contract, you should pass it to the contract as an argument.
### Deleting an asset
The assets registered through contracts are not able to be deleted to provide tamper-evidence. However, there are cases where you want to delete some assets to follow the rules and regulations of applications you develop. To provide such a data deletion, ScalarDL supports a feature called `Function`.
For more details about `Function`, please check [How to Write Function for ScalarDL](./how-to-write-function.mdx) guide.
### Send information to Functions
In non-deprecated Contracts like `JacksonBasedContract`, you can send some information to Functions by calling `void setContext(T context)`.
Note that the base Contract class that you use will decide the argument type `T`.
For details on how to receive information from Contracts in Functions, see [Receive information from Contracts](./how-to-write-function.mdx#receive-information-from-contracts).
```Java
JsonNode context = getObjectMapper().createObjectNode().put(...);
setContext(context);
```
## Write a complex contract
This section describes how to write a complex contract.
### Call contracts in a nested way
If your contract is more than 100 lines of code, it is a good sign that you are probably doing more than one thing with your contract.
It is a good practice to write modularized contracts, where each contract is doing only one thing, and to combine contracts to express more complex business logic.
The following is the example code of doing such nested invocation. Assume that `StateReader`, which reads the state of a specified asset, has been registered with `state-reader` as a contract ID.
```java
public class StateUpdaterReader extends JacksonBasedContract {
@Nullable
@Override
public JsonNode invoke(
Ledger ledger, JsonNode argument, @Nullable JsonNode properties) {
if (!argument.has("asset_id") || !argument.has("state")) {
// ContractContextException is the only throwable exception in a contract and
// it should be thrown when a contract faces some non-recoverable error
throw new ContractContextException("please set asset_id and state in the argument");
}
String assetId = argument.get("asset_id").asText();
int state = argument.get("state").asInt();
Optional> asset = ledger.get(assetId);
if (!asset.isPresent() || asset.get().data().get("state").asInt() != state) {
ledger.put(assetId, getObjectMapper().createObjectNode().put("state", state));
}
return invoke("state-reader", ledger, argument);
}
}
```
The `StateUpdaterReader` updates the Ledger just like `StateUpdater` and additionally calls another invoke with the `state-reader` to read what was written. Although this example might not be very convincing, but modularizing contracts (e.g., defining `StateUpdater` separately) can make the contracts reusable.
It's to be noted that all the contracts in the nested invocation are executed transactionally (in an ACID manner) in ScalarDL so that they are executed entirely successfully or they are entirely failed.
### Manage who can access assets
You can get identity information, which indicates who is executing the contract, by calling `getClientIdentityKey()` in a contract. This functionality helps to control who can access a certain asset. The following example shows `StateUpdater`, which has been modified so that it can only update a restricted asset with the name `state-xxx`, where `xxx` is an entity ID of the certificate or secret holder.
For details, see the [base contract](#base-contracts) section and the page in the Javadoc.
```java
public class StateUpdater extends JacksonBasedContract {
@Nullable
@Override
public JsonNode invoke(Ledger ledger, JsonNode argument, @Nullable JsonNode properties) {
if (!argument.has("state")) {
throw new ContractContextException("please set state in the argument");
}
ClientIdentityKey clientIdentityKey = getClientIdentityKey();
String entityId = clientIdentityKey.getEntityId();
String assetId = "state-" + entityId;
int state = argument.get("state").asInt();
Optional> asset = ledger.get(assetId);
if (!asset.isPresent() || asset.get().data().get("state").asInt() != state) {
ledger.put(assetId, getObjectMapper().createObjectNode().put("state", state));
}
return null;
}
}
```
### Manage assets with a namespace
:::warning
The namespace feature is currently in Public Preview. The feature and related documentation are subject to change.
:::
By default, contracts read and write assets in the pre-configured default namespace, but you can create other namespaces and manage assets in each namespace. For details on how to create namespaces, see [ScalarDL Client Command Reference](scalardl-command-reference.mdx).
The following shows an example of a namespace-aware `StateUpdaterReader` contract. The `get` and `put` APIs can access a specific namespace by specifying the namespace. When using the `scan` API, you can specify the namespace in the class.
```java
public class NamespaceAwareStateUpdaterReader extends JacksonBasedContract {
@Nullable
@Override
public JsonNode invoke(
Ledger ledger, JsonNode argument, @Nullable JsonNode properties) {
if (!argument.has("namespace") || !argument.has("asset_id") || !argument.has("state")) {
throw new ContractContextException("please set namespace, asset_id, and state in the argument");
}
String namespace = argument.get("namespace").asText();
String assetId = argument.get("asset_id").asText();
int state = argument.get("state").asInt();
Optional> asset = ledger.get(namespace, assetId);
if (!asset.isPresent() || asset.get().data().get("state").asInt() != state) {
ledger.put(namespace, assetId, getObjectMapper().createObjectNode().put("state", state));
}
return invoke("state-reader", ledger, argument);
}
}
```
## Summary
Here are the best practices for writing good contracts for ScalarDL.
* Design your data properly to fit with Ledger abstraction before writing contracts
* Throw `ContractContextException` if a contract faces non-recoverable errors
* Do not do any exception handling except for throwing `ContractContextException`
* Modularize contracts to make each do only one thing, and use nested invocation
* Make contracts deterministic
* Define `asset_id` with some rules when you want to group assets
## More samples
You can find more contract samples in [caliper-benchmarks](https://github.com/scalar-labs/caliper-benchmarks/tree/scalardl/src/scalardl/src/main/java/com/example/contract).
## References
* [Getting Started with ScalarDL](getting-started.mdx)
* [ScalarDL Design Document](design.mdx)
* [Javadoc](javadoc/index.mdx)
================================================
FILE: docs/how-to-write-function.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# A Guide on How to Write Function for ScalarDL
import JavadocLink from '/src/theme/JavadocLink.js';
This document sets out some guidelines for writing functions for ScalarDL.
## What is a function for ScalarDL ?
A Function (Smart Function) for ScalarDL is a Java program, which extends the predefined base functions such as class, written for implementing single business logic. A Function mainly manages the data of a ScalarDL application whereas a Contract manages the evidence of the data. Before looking at this, please check [Getting Started with ScalarDL](getting-started.mdx) and [How to Write Contract For ScalarDL](how-to-write-contract.mdx) to understand what ScalarDL is and what ScalarDL can do with contracts.
## Background
Assets managed by Contracts in ScalarDL are tamper-evident and append-only, so their data structure is limited in modeling various applications. Moreover, assets cannot be deleted to guarantee tamper evidence. Many distributed ledger platforms deal with the issue by having another database, such as an RDBMS, in front of a ledger to handle the application's data in the database and write logs to the ledger as evidence. However, this scheme is not ideal since data consistency between the database and the ledger is not always preserved. There could be a case where applications don't have corresponding logs in the ledger due to a catastrophic failure, which defeats the purpose of writing logs to the ledger as evidence. ScalarDL resolves the issue with a different approach by introducing Functions to manage applications' data and making Contracts and Functions execute atomically by utilizing underlying distributed ACID transactions with [ScalarDB](https://github.com/scalar-labs/scalardb).
## Write a Function
Let's take a closer look at `Payment` Function to better understand how to write a function.
```java
public class Payment extends JacksonBasedFunction {
private final String FROM_KEY_NAME = "from";
private final String TO_KEY_NAME = "to";
private final String AMOUNT_KEY_NAME = "amount";
private final String NAMESPACE_KEY_NAME = "namespace";
private final String TABLE_KEY_NAME = "table";
@Nullable
@Override
public JsonNode invoke(
Database database,
@Nullable JsonNode functionArgument,
JsonNode contractArgument,
@Nullable JsonNode contractProperties) {
// error handling is omitted
String fromId = contractArgument.get(FROM_KEY_NAME).asText();
String toId = contractArgument.get(TO_KEY_NAME).asText();
int amount = contractArgument.get(AMOUNT_KEY_NAME).asInt();
String namespace = contractProperties.get(NAMESPACE_KEY_NAME).asText();
String table = contractProperties.get(TABLE_KEY_NAME).asText();
Key fromKey = Key.ofText("id", fromId);
Key toKey = Key.ofText("id", toId);
// get the account balances
Optional account1 =
database.get(
Get.newBuilder().namespace(namespace).table(table).partitionKey(fromKey).build());
Optional account2 =
database.get(
Get.newBuilder().namespace(namespace).table(table).partitionKey(toKey).build());
// assumes that both accounts exist, but it should be checked in production code
long balance1 = account1.get().getInt("balance");
long balance2 = account2.get().getInt("balance");
if (balance1 - amount < 0) {
throw new ContractContextException(
"The account " + fromId + " does not have enough account balance.");
}
// transfer amount
balance1 -= amount;
balance2 += amount;
// update the account balances
database.put(
Put.newBuilder()
.namespace(namespace)
.table(table)
.partitionKey(fromKey)
.bigIntValue("balance", balance1)
.build());
database.put(
Put.newBuilder()
.namespace(namespace)
.table(table)
.partitionKey(toKey)
.bigIntValue("balance", balance2)
.build());
return null;
}
}
```
It is a money transfer application written with ScalarDB API, where getting specified account balances, transferring a specified amount of money between the two account balances, and updating the balances. Please also read the [ScalarDB docs](https://scalardb.scalar-labs.com/docs/latest/api-guide) for more details about ScalarDB API.
### Base Functions
Similar to predefined base Contracts, ScalarDL also provides predefined base Functions. For example, the above PaymentFunction is based on one of the base Functions called JacksonBasedFunction, which allows you to deal with the Function inputs and output in Jackson's JsonNode format.
As of writing this, we provide four base Functions as shown below; however, using JacksonBasedFunction is recommended to balance development productivity and performance well.
| Base Function Class | Type of Function inputs and output | Library |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------- |
| (recommended) | [JsonNode](https://fasterxml.github.io/jackson-databind/javadoc/2.13/com/fasterxml/jackson/databind/JsonNode.html) | [Jackson](https://github.com/FasterXML/jackson) |
| | [JsonObject](https://javadoc.io/static/javax.json/javax.json-api/1.1.4/javax/json/JsonObject.html) | [JSONP](https://javaee.github.io/jsonp/) |
| | [String](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html) | Java Standard Libraries |
| (deprecated) | [JsonObject](https://javadoc.io/static/javax.json/javax.json-api/1.1.4/javax/json/JsonObject.html) | [JSONP](https://javaee.github.io/jsonp/) |
The old is still available, but it is now deprecated and will be removed in a later major version. So, it is highly recommended to use the above new (non-deprecated) Functions as a base Function.
### About the `invoke` arguments
Similar to a Contract using `Ledger` object to manage assets, a Function uses `Database` object to manage records of the underlying database. Note that `Database` implements [ScalarDB](https://github.com/scalar-labs/scalardb) interface so that you can do the CRUD operations based on the [data model](https://scalardb.scalar-labs.com/docs/latest/data-modeling#scalardb-data-model) of ScalarDB.
A `functionArgument` is a runtime argument for the Function specified by the requester. The argument is not digitally signed as opposed to the contract argument so that it can be used to pass data that is stored in the database but it might be deleted at some later point for some reason.
`contractArgument` and `contractProperties` are the corresponding contract's argument and properties. See [How to Write a Contract](how-to-write-contract.mdx) to understand what they are.
### Receive information from Contracts
In non-deprecated Functions like `JacksonBasedFunction`, you can receive some information from Contracts by calling `T getContractContext()`.
Note that the return value can be null if Contracts has nothing set and the base Function class that you use will decide the return value type `T`.
For details on how to send information to Functions from Contracts, see [Send information to Functions](./how-to-write-contract.mdx#send-information-to-functions).
```Java
JsonNode context = getContractContext();
```
### How to use Functions
The Function feature is enabled by default; thus, nothing needs to be configured in Ledger except for the following things. If you want to disable the feature, please set `scalar.dl.ledger.function.enabled` to `false` in the properties of Ledger.
#### Add an application-specific schema
Since Functions can read and write arbitrary records through the ScalarDB CRUD interface, ScalarDL can't define the database schema for the Function by itself. It is the applications' owner's responsibility to define such schema and apply it to the database by themselves or asking system admins to do it depending on who owns and manages the database. For more details about defining database schema for ScalarDB, please read [ScalarDB Schema Loader](https://scalardb.scalar-labs.com/docs/latest/schema-loader).
#### Register a Function
You then need to register a Function to Ledger before used like you register a Contract.
```
client/bin/scalardl register-function --properties client.properties --function-id test-function --function-binary-name com.example.function.TestFunction --function-class-file /path/to/TestFunction.class
```
#### Execute a Function
You can specify a Function to execute along with a Contract to execute.
For example, you can execute a function as follows with the command-line tool.
```
client/bin/scalardl execute-contract --properties client.properties --contract-id test-contract --contract-argument '{...}' --function-id test-function --function-argument '{...}'
```
You can also do it with the as follows.
```java
ContractExecutionResult result = clientService.executeContract(contractId, contractArgument, functionId, functionArgument);
```
Like a Contract, a Function can invoke another Function so multiple Functions (and multiple Contracts) can be grouped together. ScalarDL executes a group of Contracts and Functions in an ACID manner so that they can be done atomically and in a consistent, isolated, and durable manner.
## How to use Contracts and Functions properly
Contracts and Functions should be properly used to make the scheme meaningful. As a basic principle, Contracts should be used to manage data that requires tamper-evidence, and Functions should be used to manage data that can be updated or deleted or that needs a more flexible data model. As a good practice, Functions are used to manage applications' data and Contracts are used to manage the logs of applications' execution as evidence. For example in a payment application, a Function manages the account balances of users and a Contract manages the evidence of payment between the users.
## References
* [Getting Started with ScalarDL](getting-started.mdx)
* [A Guide on How to Write Contract for ScalarDL](how-to-write-contract.mdx)
* [ScalarDL Design Document](design.mdx)
* [Javadoc](javadoc/index.mdx)
================================================
FILE: docs/implementation.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL Implementation
ScalarDL is scalable and practical Byzantine fault detection middleware for transactional database systems, which achieves correctness, scalability, and database agnosticism.
This document briefly introduces the implementation of ScalarDL.
For the architecture, novelty and Byzantine fault detection protocol of ScalarDL, please see the [design document](design.mdx).
## ScalarDL components
ScalarDL is middleware that runs on top of databases and is mainly written in Java. ScalarDL is composed of Ledger, Auditor, and Client SDK. Let's look at each component.

### Ledger
Ledger implements the commit phase of the byzantine fault detection protocol. Ledger also manages programmable deterministic functions called Contracts for users to create one-shot transactions. In a Contract, users can write arbitrary business logic and call database operations through the interface defined by the Contract. Nested invocation, i.e., a Contract calling another Contract, is supported so that users can implement an application's business logic with multiple Contracts modularly. Ledger executes multiple Contracts in an ACID manner by exploiting the underlying database transaction. Each Contract is stored in the database in a Java bytecode format with a digital signature attached for later verification.
Ledger abstracts the underlying database as a multi-dimensional map based on the key-value data model, which is similar to the data model of Bigtable. We chose the abstraction to achieve broad applicability for various databases and data models. A record is composed of a record key (application-level primary key), a version, and a set of values, including a Contract argument used to derive the record, and a cryptographic hash of all the record values. A record key and a version form a primary key, and the primary key uniquely maps a set of values. Ledger manages the versions of records for achieving traceability. Ledger also constructs a hash-chain for the records that have the same record key to make the records difficult to be maliciously altered partially, but ScalarDL does not need the hash-chain structure to provide Byzantine fault detection capability.
Ledger implements the detection protocol using the database abstraction to achieve database-agnostic property. We use ScalarDB, a universal transaction manager, to implement the database abstraction efficiently. The database abstraction currently supports PostgreSQL, MySQL, Oracle Database, Microsoft SQL Server, Apache Cassandra, Amazon DynamoDB, Amazon Aurora, Azure Cosmos DB, and their compatible databases. For those non-ACID databases such as Cassandra, HBase, DynamoDB, and Cosmos DB, ScalarDB takes care of transactions with its database-agnostic ACID transaction capability that supports snapshot isolation and strict serializability. For those ACID databases, ScalarDB provides two options: delegating transaction management to the underlying databases or doing transaction management by itself.
Ledger by only itself can provide the service to users. In such a case, ScalarDL works similarly to Oracle Blockchain Table or Amazon QLDB except for the database-agnostic transaction capability, i.e., it manages a database in a single administrative domain (AD), so it only detects some limited class of Byzantine faults.
### Auditor
Auditor implements the ordering and validation phases of the Byzantine fault detection protocol. Auditor also manages the same Contracts as Ledger and uses the same database abstraction as Ledger so that Auditor can use various databases as the underlying database.
Auditor has to be placed in a different administrative domain from the one where Ledger is placed to guarantee correctness.
### Client SDK
Client SDK interacts with Ledger and Auditor on the basis of the protocol. An application program integrated with Client SDK manages a key pair (i.e., a private key and a certificate) for digital signature and creates a digitally-signed execution request to be authenticated to execute Contracts. The digitally-signed request is also stored in the databases so that the request can identify who has executed the request, which adds extra security and traceability to the system. Client SDK can also use HMAC authentication by sharing a secret between the client and servers; however, an HMAC-signature added request cannot provide such non-repudiation.
Client SDKs are written in several languages: Java, Node.js, in-browser JavaScript, and Go.
## Further reading
* [ScalarDL Design Document](design.mdx)
================================================
FILE: docs/index.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
image: img/scalardl-social-card-preview.png
hide_table_of_contents: true
title: ""
---
import CategoryGrid from '/src/components/Cards/3.13';
================================================
FILE: docs/installation-with-docker.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# How to Install ScalarDL in Your Local Environment with Docker
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import WarningLicenseKeyContact from '/src/components/en-us/_warning-license-key-contact.mdx';
This document shows how to set up a local environment that runs ScalarDL along with the back-end Cassandra server using [Docker Compose](https://docs.docker.com/compose/).
## Prerequisites
- [Docker](https://www.docker.com/get-started/) 20.10 or later with [Docker Compose](https://docs.docker.com/compose/install/) V2 or later
Follow the instructions on the Docker website according to your platform.
## Clone the scalardl-samples repository
The [scalar-labs/scalardl-samples](https://github.com/scalar-labs/scalardl-samples) repository includes sample applications for you to start using ScalarDL instantly.
1. In Terminal, determine the location on your local machine where you want to run the `scalardl-samples` app. Then, clone the `scalardl-samples` repository.
```console
git clone https://github.com/scalar-labs/scalardl-samples.git
```
1. Go to the `scalardl-samples` directory.
```console
cd scalardl-samples
```
## Set your license key
Set your license key for ScalarDL Ledger
You must set your license key for ScalarDL Ledger. In the `docker-compose.yml` file, please replace `` with your license key. For example:
```yaml
services:
scalardl-ledger:
environment:
- SCALAR_DL_LICENSING_LICENSE_KEY={"organization_name":"XXXXXXXX","expiration_date_time":"YYYY-MM-DDTHH:mm:SS+TIMEZONE","product_name":"ScalarDL Ledger","product_version":N,"license_type":"trial","signature":"XXXXXXXX"}
```
Set your license key for ScalarDL Ledger
You must set your license key for ScalarDL Ledger. In the `docker-compose.yml` file, please replace `` with your license key. For example:
```yaml
services:
scalardl-ledger:
environment:
- SCALAR_DL_LICENSING_LICENSE_KEY={"organization_name":"XXXXXXXX","expiration_date_time":"YYYY-MM-DDTHH:mm:SS+TIMEZONE","product_name":"ScalarDL Ledger","product_version":N,"license_type":"trial","signature":"XXXXXXXX"}
```
Set your license key for ScalarDL Auditor
You must set your license key for ScalarDL Auditor. In the `docker-compose-auditor.yml` file, please replace `` with your license key. For example:
```yaml
services:
scalardl-auditor:
environment:
- SCALAR_DL_LICENSING_LICENSE_KEY={"organization_name":"XXXXXXXX","expiration_date_time":"YYYY-MM-DDTHH:mm:SS+TIMEZONE","product_name":"ScalarDL Auditor","product_version":N,"license_type":"trial","signature":"XXXXXXXX"}
```
## Set the certificate file for checking the license key
:::note
If you have a trial license, you can skip this step and [start up ScalarDL](#start-up-scalardl).
:::
In this step, you must set the certificate file for ScalarDL Ledger.
Set the certificate file for ScalarDL Ledger
If you have a commercial license, you must update the `docker-compose.yml` file as follows:
- Before changing the certificate file path (default configuration):
```yaml
services:
scalardl-ledger:
volumes:
- ./fixture/ledger-key.pem:/scalar/ledger-key.pem
- ./fixture/ledger.properties.tmpl:/scalar/ledger/ledger.properties.tmpl
- ./fixture/trial-license-cert.pem:/scalar/license-cert.pem
# If you have a commercial license key, you must use `commercial-license-cert.pem` instead of `trial-license-cert.pem`.
# - ./fixture/commercial-license-cert.pem:/scalar/license-cert.pem
```
- After changing the certificate file path:
```yaml
services:
scalardl-ledger:
volumes:
- ./fixture/ledger-key.pem:/scalar/ledger-key.pem
- ./fixture/ledger.properties.tmpl:/scalar/ledger/ledger.properties.tmpl
# - ./fixture/trial-license-cert.pem:/scalar/license-cert.pem
# If you have a commercial license key, you must use `commercial-license-cert.pem` instead of `trial-license-cert.pem`.
- ./fixture/commercial-license-cert.pem:/scalar/license-cert.pem
```
In this step, you must set the certificate file for ScalarDL Ledger and ScalarDL Auditor.
Set the certificate file for ScalarDL Ledger
If you have a commercial license, you must update the `docker-compose.yml` file as follows:
- Before changing the certificate file path (default configuration):
```yaml
services:
scalardl-ledger:
volumes:
- ./fixture/ledger-key.pem:/scalar/ledger-key.pem
- ./fixture/ledger.properties.tmpl:/scalar/ledger/ledger.properties.tmpl
- ./fixture/trial-license-cert.pem:/scalar/license-cert.pem
# If you have a commercial license key, you must use `commercial-license-cert.pem` instead of `trial-license-cert.pem`.
# - ./fixture/commercial-license-cert.pem:/scalar/license-cert.pem
```
- After changing the certificate file path:
```yaml
services:
scalardl-ledger:
volumes:
- ./fixture/ledger-key.pem:/scalar/ledger-key.pem
- ./fixture/ledger.properties.tmpl:/scalar/ledger/ledger.properties.tmpl
# - ./fixture/trial-license-cert.pem:/scalar/license-cert.pem
# If you have a commercial license key, you must use `commercial-license-cert.pem` instead of `trial-license-cert.pem`.
- ./fixture/commercial-license-cert.pem:/scalar/license-cert.pem
```
Set the certificate file for ScalarDL Auditor
If you have a commercial license, you must update the `docker-compose-auditor.yml` file as follows:
- Before changing the certificate file path (default configuration):
```yaml
services:
scalardl-auditor:
volumes:
- ./fixture/auditor.pem:/scalar/auditor.pem
- ./fixture/auditor-key.pem:/scalar/auditor-key.pem
- ./fixture/auditor.properties.tmpl:/scalar/auditor/auditor.properties.tmpl
- ./fixture/trial-license-cert.pem:/scalar/license-cert.pem
# If you have a commercial license key, you must use `commercial-license-cert.pem` instead of `trial-license-cert.pem`.
# - ./fixture/commercial-license-cert.pem:/scalar/license-cert.pem
```
- After changing the certificate file path:
```yaml
services:
scalardl-auditor:
volumes:
- ./fixture/auditor.pem:/scalar/auditor.pem
- ./fixture/auditor-key.pem:/scalar/auditor-key.pem
- ./fixture/auditor.properties.tmpl:/scalar/auditor/auditor.properties.tmpl
# - ./fixture/trial-license-cert.pem:/scalar/license-cert.pem
# If you have a commercial license key, you must use `commercial-license-cert.pem` instead of `trial-license-cert.pem`.
- ./fixture/commercial-license-cert.pem:/scalar/license-cert.pem
```
## Start up ScalarDL
The following command starts up ScalarDL Ledger, along with the backend Cassandra server in the Docker containers.
:::note
The first time you run this command, the required Docker images will be downloaded from GitHub Container Registry.
:::
```console
docker compose up -d
```
The following command starts up ScalarDL Ledger and ScalarDL Auditor, along with the backend Cassandra server in the Docker containers.
:::note
The first time you run this command, the required Docker images will be downloaded from GitHub Container Registry.
:::
```console
docker compose -f docker-compose.yml -f docker-compose-auditor.yml up -d
```
## Shut down ScalarDL
To shut down the containers, run the following command.
```console
docker compose down -v
```
```console
docker compose -f docker-compose.yml -f docker-compose-auditor.yml down -v
```
================================================
FILE: docs/learning-paths.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL Learning Paths
This guide provides learning paths for different roles. Depending on your role, follow the appropriate sequence of documents to gain a comprehensive understanding of ScalarDL.
## Architects
This path is designed for architects who want to design applications that use ScalarDL.
- [About ScalarDL category](./overview.mdx)
- [Quickstart category](./quickstart-overview.mdx)
- [Develop category](./develop-overview.mdx) (as necessary)
## Application developers
This path is designed for application developers who want to build applications that use ScalarDL.
- [About ScalarDL category](./overview.mdx)
- [Quickstart category](./quickstart-overview.mdx)
- [Develop category](./develop-overview.mdx)
## Infrastructure engineers
This path is designed for infrastructure engineers who want to deploy and manage ScalarDL in various environments.
- [About ScalarDL category](./overview.mdx)
- [Quickstart category](./quickstart-overview.mdx)
- [Deploy category](./deploy-overview.mdx)
- [Manage category](./manage-overview.mdx)
## Business decision makers
This path is designed for business decision makers who want to understand the strategic direction and future plans of ScalarDL.
- [ScalarDL Overview](./overview.mdx)
- [ScalarDL Roadmap](./roadmap.mdx)
================================================
FILE: docs/libraries-and-tools.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Libraries and Tools for ScalarDL
ScalarDL provides various libraries and tools to help you build and operate scalable and reliable applications. Below are some key libraries and tools available.
## Libraries
The following libraries are available for ScalarDL.
| Library | Edition | Maven Package | Container Image | Reference |
|-------------------------------------|------------------------|-----------------------------------------------------------------------------------------------------------------------|-----------------|---------------------------------------------------------------------------------------------------------|
| ScalarDL Java Client SDK | Community & Enterprise | [Maven Central Repository](https://central.sonatype.com/artifact/com.scalar-labs/scalardl-java-client-sdk) | N/A | [Documentation](./how-to-write-applications.mdx#use-the-scalardl-client-sdk) |
| ScalarDL HashStore Java Client SDK | Community & Enterprise | [Maven Central Repository](https://central.sonatype.com/artifact/com.scalar-labs/scalardl-hashstore-java-client-sdk) | N/A | [Documentation](./how-to-write-applications-with-hashstore.mdx#use-the-scalardl-hashstore-client-sdk) |
| ScalarDL TableStore Java Client SDK | Community & Enterprise | [Maven Central Repository](https://central.sonatype.com/artifact/com.scalar-labs/scalardl-tablestore-java-client-sdk) | N/A | [Documentation](./how-to-write-applications-with-tablestore.mdx#use-the-scalardl-tablestore-client-sdk) |
## Tools
The following tools are available for ScalarDL.
| Tool | Edition | Maven Package | Container Image | Reference |
|-----------------------------|------------------------|---------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------|
| ScalarDL Client Command | Community & Enterprise | N/A | [GitHub](https://github.com/scalar-labs/scalardl/pkgs/container/scalardl-client) | [Documentation](./scalardl-command-reference.mdx) |
| ScalarDL Schema Loader | Community & Enterprise | N/A | [GitHub](https://github.com/orgs/scalar-labs/packages/container/package/scalardl-schema-loader) | [Documentation](./schema-loader.mdx) |
| Helm Charts | Community & Enterprise | N/A | N/A | [Documentation](./helm-charts/getting-started-scalar-helm-charts.mdx) |
| Scalar Admin for Kubernetes | Community & Enterprise | [Maven Central Repository](https://central.sonatype.com/artifact/com.scalar-labs/scalar-admin-for-kubernetes) | [GitHub](https://github.com/orgs/scalar-labs/packages/container/package/scalar-admin-for-kubernetes) | [Documentation](./helm-charts/how-to-deploy-scalar-admin-for-kubernetes.mdx) |
### Components
The following components are available for ScalarDL.
| Component | Edition | Container Image | Reference |
|-------------------------|------------|------------------------------------------------------------------------------------------------|-----------------------------|
| ScalarDL Ledger | Community | [GitHub](https://github.com/orgs/scalar-labs/packages/container/package/scalardl-ledger) | Documentation (coming soon) |
| ScalarDL Ledger (BYOL) | Enterprise | [GitHub](https://github.com/orgs/scalar-labs/packages/container/package/scalardl-ledger-byol) | Documentation (coming soon) |
| ScalarDL Auditor (BYOL) | Enterprise | [GitHub](https://github.com/orgs/scalar-labs/packages/container/package/scalardl-auditor-byol) | Documentation (coming soon) |
================================================
FILE: docs/manage-backup-and-restore-overview.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Back Up and Restore Databases
This guide explains how to back up and restore databases that are used by ScalarDL through ScalarDB.
:::note
ScalarDL uses ScalarDB in its internal to access backend databases. So, you must back up and restore databases that are managed by ScalarDB if you want to back up and restore ScalarDL.
:::
## Basic guidelines to back up and restore databases
Before performing a backup, be sure to read [A Guide on How to Backup and Restore Data in ScalarDL](backup-restore.mdx).
## Back up databases when using ScalarDB in a Kubernetes environment
For details on how to back up databases in a Kubernetes environment, see [Back up a NoSQL database in a Kubernetes environment](scalar-kubernetes/BackupNoSQL.mdx).
## Restore databases when using ScalarDB in a Kubernetes environment
For details on how to restore databases in a Kubernetes environment, see [Restore databases in a Kubernetes environment](scalar-kubernetes/RestoreDatabase.mdx).
================================================
FILE: docs/manage-contract-and-function-lifecycle.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Manage the Contract and Function Lifecycle
import JavadocLink from '/src/theme/JavadocLink.js';
This document explains the lifecycle of contracts and functions in ScalarDL—from creating and registering them to updating them when bug fixes or feature additions are needed.
## Create a contract or function
In ScalarDL, you implement business logic as two types of Java programs: contracts and functions. Contracts manage tamper-evident asset records in the Ledger, while functions work alongside contracts to manage mutable records in an external database through ScalarDB.
To create a contract or function, write a Java class that extends one of the predefined base classes, such as for contracts or for functions.
For details on how to write contracts and functions, see the following:
- [A Guide on How to Write a Good Contract for ScalarDL](how-to-write-contract.mdx)
- [A Guide on How to Write Function for ScalarDL](how-to-write-function.mdx)
## Register a contract or function
After creating a contract or function, you need to register it with ScalarDL before you can use it.
To register a contract:
```console
scalardl register-contract --properties client.properties --contract-id StateUpdater --contract-binary-name com.org1.contract.StateUpdater --contract-class-file build/classes/java/main/com/org1/contract/StateUpdater.class
```
To register a function:
```console
scalardl register-function --properties client.properties --function-id test-function --function-binary-name com.example.function.TestFunction --function-class-file /path/to/TestFunction.class
```
For details on registration commands and options, see [ScalarDL Client Command Reference](scalardl-command-reference.mdx).
### Contract registration constraints
When registering a contract, note the following constraints:
- **Unique contract ID:** Each contract must have a unique contract ID. If you try to register a contract with an ID that already exists, the registration will fail.
- **Consistent binary name and byte code:** If a binary name has already been registered with a certain byte code, you cannot register a different byte code under the same binary name. However, you can register the same binary name and byte code under a different client or a different contract ID.
### Function registration constraints
Unlike contracts, functions can be re-registered with the same function ID. The behavior depends on how you access ScalarDL:
- **Privileged port (default: 50052):** Functions can always be registered and overwritten without restrictions.
- **Non-privileged port (default: 50051):** Function registration and overwriting are controlled by administrator settings. For details, see [Access Namespaces in a Restricted Manner](access-namespaces-in-a-restricted-manner.mdx).
## Update a contract or function
Contracts and functions have fundamentally different update mechanisms because they serve different architectural roles in ScalarDL. Contracts manage tamper-evident asset records in the Ledger, and ScalarDL needs to be able to replay the full history of asset updates to validate consistency with past contract executions. For this reason, contracts are immutable (append-only). Functions, on the other hand, manage mutable records in an external database through ScalarDB, so there is no need to preserve the history of past function versions, and they can be overwritten.
### Update a contract
Since contracts are immutable, you cannot modify or overwrite an existing contract. Instead, you must register a new version of the contract with a **new contract ID** and a **new binary name**.
#### Versioning best practices
There are two common approaches for versioning contracts:
**Package-based versioning (recommended for production):** Include the version number in the Java package name. The [predefined contracts](https://github.com/scalar-labs/scalardl/tree/master/generic-contracts/src/main/java/com/scalar/dl/genericcontracts) used internally by ScalarDL abstractions such as HashStore and TableStore also follow this approach.
For example, if your original contract is in `com.example.contract.v1.StateUpdater`, the updated version would be in `com.example.contract.v2.StateUpdater`. Similarly, the contract ID should reflect the version, such as `v1.StateUpdater` and `v2.StateUpdater`.
```console
scalardl register-contract --properties client.properties --contract-id v2.StateUpdater --contract-binary-name com.example.contract.v2.StateUpdater --contract-class-file build/classes/java/main/com/example/contract/v2/StateUpdater.class
```
**Class-name-based versioning (suitable for smaller scale or testing):** Append the version number directly to the class name, such as `StateUpdaterV2`. This approach is simpler but can become less organized for large-scale projects.
```console
scalardl register-contract --properties client.properties --contract-id StateUpdaterV2 --contract-binary-name com.example.contract.StateUpdaterV2 --contract-class-file build/classes/java/main/com/example/contract/StateUpdaterV2.class
```
#### Update your application code
After registering the new contract version, update your application code to use the new contract ID. For example, if you use , update the contract ID passed to the `executeContract` method.
:::note
Old contract versions remain registered in ScalarDL. This is by design—ScalarDL needs them for asset validation and history replay. Do not attempt to remove old contract versions.
:::
### Update a function
Since functions are mutable, you can update a function by re-registering it with the same function ID. The new byte code will overwrite the old one.
```console
scalardl register-function --properties client.properties --function-id test-function --function-binary-name com.example.function.TestFunction --function-class-file /path/to/TestFunction.class
```
When overwriting a function, you can also change the binary name if needed. The function ID is the only identifier that must remain the same.
:::note
In multi-tenant (namespace) configurations, function registration and overwriting through the non-privileged port are controlled by administrator settings. For details, see [Access Namespaces in a Restricted Manner](access-namespaces-in-a-restricted-manner.mdx).
:::
### Execute updated contracts and functions
After updating a contract, use the **new contract ID** when executing it. The old contract ID still references the old version.
```console
scalardl execute-contract --properties client.properties --contract-id v2.StateUpdater --contract-argument '{"asset_id":"some_asset", "state":3}'
```
After updating a function, you can use the **same function ID** as before, and the updated function will be executed automatically.
```console
scalardl execute-contract --properties client.properties --contract-id v2.StateUpdater --contract-argument '{"asset_id":"some_asset", "state":3}' --function-id test-function --function-argument '{...}'
```
For details on executing contracts and functions, see the following:
- [Write a ScalarDL Application in Java](how-to-write-applications.mdx)
- [ScalarDL Client Command Reference](scalardl-command-reference.mdx)
## See also
- [A Guide on How to Write a Good Contract for ScalarDL](how-to-write-contract.mdx)
- [A Guide on How to Write Function for ScalarDL](how-to-write-function.mdx)
- [ScalarDL Client Command Reference](scalardl-command-reference.mdx)
- [Write a ScalarDL Application in Java](how-to-write-applications.mdx)
- [Access Namespaces in a Restricted Manner](access-namespaces-in-a-restricted-manner.mdx)
================================================
FILE: docs/manage-monitor-overview.mdx
================================================
---
tags:
- Enterprise
displayed_sidebar: docsEnglish
---
# Monitor Overview
Scalar Manager is a centralized management and monitoring solution for ScalarDL within Kubernetes cluster environments that allows you to:
- Check the availability of ScalarDL.
- Schedule or execute pausing jobs that create transactionally consistent periods in the databases used by ScalarDL.
- Check the time-series metrics and logs of ScalarDL through Grafana dashboards.
For more details about Scalar Manager, see [Scalar Manager Overview](scalar-manager/overview.mdx).
:::note
ScalarDL uses ScalarDB for its data management and the Function feature, so you may experience a case where you're using both ScalarDL and ScalarDB in your deployment. In such a case, you may also want to monitor ScalarDB in addition to ScalarDL.
:::
## Deploy Scalar Manager
You can deploy Scalar Manager by using a Helm Chart.
For details on how to deploy Scalar Manager, see [Deploy Scalar Manager](helm-charts/getting-started-scalar-manager.mdx).
================================================
FILE: docs/manage-namespaces.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Manage Namespaces
:::warning
The namespace feature is currently in Public Preview. The feature and related documentation are subject to change.
:::
This document explains how to use namespaces to organize and isolate assets in ScalarDL.
## Overview
Namespaces allow you to logically group and isolate resources within a Ledger. Each namespace contains its own set of:
- **Assets:** The immutable, tamper-evident data stored in the ledger.
- **Credentials:** Certificates or secret keys used for authentication.
- **Contracts:** The business logic that manages assets in the ledger.
- **Functions:** The business logic that works with contracts to manage mutable records in an external database.
By default, all resources are stored in a namespace called `default`. You can create additional namespaces to separate resources for different use cases, such as multi-tenancy, data lifecycle management, or cost optimization.
There are two access models for namespaces:
- **Cross-namespace access model:** A single application accesses assets across multiple namespaces.
- **Restricted access model:** Multiple independent applications each have exclusive access to assets within their own namespace.
## Cross-namespace access model
The cross-namespace access model is suitable for use cases such as the following:
- **Efficient data lifecycle management:** Separate data into namespaces by time period (for example, 1 year), and then bulk-delete data by namespace after the legally required retention period (for example, 10 years) has passed.
- **Cost optimization through storage tiering:** Prepare namespaces on multiple storage systems with different performance characteristics and costs, and store data in different namespaces based on access frequency and importance.
To perform cross-namespace data access, implement contracts by using namespace-aware interfaces and register those contracts in the `default` namespace. Contracts registered in the `default` namespace have a global access scope, allowing them to get, put, and scan assets in any namespace.
For details on developing namespace-aware contracts, see [Manage assets with a namespace](how-to-write-contract.mdx#manage-assets-with-a-namespace).
## Restricted access model
The restricted access model is suitable for use cases such as the following:
- **SaaS applications:** Host multiple customers running the same application on a shared ScalarDL cluster while ensuring each customer's data and contracts are completely isolated from one another.
- **Infrastructure consolidation:** Run multiple independent applications from different departments or business units on a single cluster, reducing infrastructure costs while maintaining secure isolation between each application's data and contracts.
ScalarDL supports these scenarios by restricting access to each namespace so that it is independently managed and inaccessible from other namespaces. To set up a namespace with restricted access, first create a namespace, and then register the certificates or secrets of tenant clients that will use each namespace. Then, register contracts and functions for their application through the registered clients. Only clients registered in a namespace can register and execute contracts and functions or validate assets within that namespace.
Unlike contracts registered in the `default` namespace, contracts registered in namespaces with restricted access have only a local access scope and cannot access assets in other namespaces.
For details on how to set up namespaces and access them in a restricted manner, see [Access Namespaces in a Restricted Manner](access-namespaces-in-a-restricted-manner.mdx).
## See also
- [A Guide on How to Write a Good Contract](how-to-write-contract.mdx)
- [Access Namespaces in a Restricted Manner](access-namespaces-in-a-restricted-manner.mdx)
- [ScalarDL Client Command Reference](scalardl-command-reference.mdx)
================================================
FILE: docs/manage-overview.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Manage Overview
In this category, you can follow guides to help you manage ScalarDL.
- For details on how to scale ScalarDL, see [Scale](scalar-kubernetes/HowToScaleScalarDL.mdx).
- For details on how to upgrade ScalarDL, see [Upgrade](scalar-kubernetes/HowToUpgradeScalarDL.mdx).
## Monitor
In this sub-category, you can learn how to monitor your ScalarDL deployment.
For an overview of this sub-category, see [Monitor Overview](manage-monitor-overview.mdx).
## Back up and restore
In this sub-category, you can learn how to back up and restore the databases that are connected to your ScalarDL deployment.
For an overview of this sub-category, see [Back Up and Restore Databases](manage-backup-and-restore-overview.mdx).
================================================
FILE: docs/onboarding.mdx
================================================
---
id: onboarding
title: Redirecting ...
---
import {useEffect} from 'react';
import {useLocation} from '@docusaurus/router';
export default function Redirect() {
const location = useLocation();
useEffect(() => {
let path = location.pathname;
if (path.startsWith('/en-us/')) {
path = path.replace('/en-us/', '/ja-jp/');
} else if (!path.startsWith('/ja-jp/')) {
path = `/ja-jp${path}`;
}
// 🔥 Force full reload (fixes broken page issue)
window.location.replace(path);
}, [location]);
return This page doesn't exist in English. Redirecting to Japanese version...
;
}
================================================
FILE: docs/overview.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL Overview
This page describes what ScalarDL is and its primary use cases.
## What is ScalarDL?
ScalarDL is middleware for realizing a tamper-evident database system by detecting arbitrary faults (that is, Byzantine faults), such as data tampering and malicious attacks, in transactional database systems.
It achieves such detection in a scalable and practical way like no other with its novel consensus algorithm.
Since ScalarDL uses [ScalarDB](https://scalardb.scalar-labs.com/docs/) for database interactions, it inherits the database-agnostic property of ScalarDB, allowing it to work on a wide range of databases, such as relational and NoSQL databases.
For details on which databases ScalarDB supports, refer to [Supported Databases](https://scalardb.scalar-labs.com/docs/latest/requirements#databases/).
## Why ScalarDL?
Several solutions, such as public blockchains, private blockchains, and ledger databases, deal with data tampering and malicious attacks, but they are limited in practicality, scalability, or correctness:
- Public blockchains (like Bitcoin and Ethereum) are designed to mask Byzantine faults by composing a system with a large number (often thousands) of separately administered nodes that share a copy of data. However, copying data between many nodes makes the system not scalable. Moreover, managing and operating a system based on a public peer-to-peer network is essentially difficult, especially in enterprise systems, since system administrators have no control over it.
- Private blockchains (like Hyperledger Fabric) are designed to mask Byzantine faults in enterprises by composing a system with at least four separately administered nodes (or subsystems) that share a copy of data. However, not only copying data between many nodes makes the system unable to be scalable but managing four separately administered nodes is not necessarily practical, especially in enterprise systems.
- Ledger databases (like Amazon QLDB and Oracle Database Blockchain Table) do not guarantee they will deal with Byzantine faults because they are designed to run in a single administrative domain.
ScalarDL, on the other hand, stands out from these solutions. It effectively handles Byzantine faults with just two separately administered nodes (subsystems), offering a scalable, practical, and guaranteed approach that is not found in other solutions.
The following table summarizes how ScalarDL is different from the other solutions.
| | How to deal with Byzantine faults | Number of administrative domains | Performance (TPS) | Scalability |
| :--: | :--: | :--: | :--: | :--: |
| Public blockchains (like Bitcoin and Ethereum) | Masking (N>2f*) | Thousands or more | Up to 100 | Low scalability |
| Private blockchains (like Hyperledger Fabric) | Masking (N>3f*) | 4 or more | Up to a few thousands | Low scalability |
| Ledger databases (like Amazon QLDB and Oracle Database Blockchain Table) | No guarantee | 1 | Up to a few thousands | Limited scalability (due to the scale-up approach) |
| **ScalarDL** | **Detection (N>f\*)** | **2** | **Up to tens of thousands (could be more, depending on the underlying computing resources)** | **High scalability**|
\* N is the number of nodes (or subsystems) composing a system, and f is the number of faulty nodes. The systems work correctly as long as the specified condition is met.
## ScalarDL use cases
ScalarDL can be used in various ways. Here are the primary use cases of ScalarDL.
### Guaranteeing the authenticity of data
There are several regulations and laws that require the authenticity of data. For example, regulations on data protection and privacy (for example, GDPR and CCPA/CPRA), laws for digital documents around finance and tax affairs, prior user rights for intellectual property, and vehicle regulations around over-the-air (OTA) software updates in WP.29.
ScalarDL guarantees the authenticity of data with its real-time Byzantine fault detection capability.
### Managing the traceability of data
Data traceability is essential for enterprises. For example, many industries are subject to strict regulations that require manufacturers to maintain accurate records of their products' origins and destinations. Data traceability systems allow manufacturers to demonstrate compliance with these regulations.
ScalarDL preserves data by using its tamper-evident, append-only ledger; thus, it correctly manages the traceability of data.
## Further reading
* [ScalarDL Technical Overview](https://speakerdeck.com/scalar/scalar-dl-technical-overview)
* [ScalarDL Research Paper](https://dl.acm.org/doi/abs/10.14778/3523210.3523212) [VLDB'22]
================================================
FILE: docs/quickstart-overview.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Quickstart Overview
In this category, you can follow quickstart tutorials for how to get started with ScalarDL.
ScalarDL offers two abstracted data stores for easy, seamless interaction with the ledger: HashStore and TableStore.
* HashStore provides interfaces for ensuring the authenticity of objects and collections, making it ideal for chain-of-custody and similar applications.
* TableStore offers an SQL-compatible interface for verifying table authenticity, enabling developers to build versatile, tamper-evident applications with familiar data models and interfaces.
To get started, refer to the following guides:
* [Get Started with ScalarDL HashStore](getting-started-hashstore.mdx)
* [Get Started with ScalarDL TableStore](getting-started-tablestore.mdx)
ScalarDL also includes primitive interfaces for more customized interactions with the ledger. To explore this approach, see [Get Started with ScalarDL Ledger](getting-started.mdx).
================================================
FILE: docs/requirements.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Requirements
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import JDKVersions from '/src/components/en-us/_prerequisites-jdk-versions.mdx';
This page describes the required tools and their versions to use ScalarDL correctly.
## Client SDK
Because ScalarDL is written in Java, the easiest way to interact with ScalarDL is to use the [Java client SDK](getting-started.mdx#download-the-client-sdk).
### Java
The following Java Development Kits (JDKs) are verified and supported:
### Other languages
ScalarDL uses gRPC, so you can create your own client by using the generated clients of your preferred languages.
## Databases
ScalarDL is middleware that runs on top of the following databases and their versions.
### Relational databases
| Version | Oracle Database 23ai | Oracle Database 21c | Oracle Database 19c |
|:------------------|:---------------------|:--------------------|:--------------------|
| **ScalarDL 3.13** | ✅ | ✅ | ✅ |
| **ScalarDL 3.12** | ✅ | ✅ | ✅ |
| **ScalarDL 3.11** | ✅ | ✅ | ✅ |
| **ScalarDL 3.10** | ✅ | ✅ | ✅ |
| Version | Db2 12.1 | Db2 11.5 |
|:------------------|:---------|:---------|
| **ScalarDL 3.13** | ✅ | ✅ |
| **ScalarDL 3.12** | ✅ | ✅ |
| **ScalarDL 3.11** | ❌ | ❌ |
| **ScalarDL 3.10** | ❌ | ❌ |
| Version | MySQL 8.4 | MySQL 8.0 |
|:------------------|:----------|:----------|
| **ScalarDL 3.13** | ✅ | ✅ |
| **ScalarDL 3.12** | ✅ | ✅ |
| **ScalarDL 3.11** | ✅ | ✅ |
| **ScalarDL 3.10** | ✅ | ✅ |
| Version | PostgreSQL 17 | PostgreSQL 16 | PostgreSQL 15 | PostgreSQL 14 | PostgreSQL 13 |
|:------------------|:--------------|:--------------|:--------------|:--------------|:--------------|
| **ScalarDL 3.13** | ✅ | ✅ | ✅ | ✅ | ✅ |
| **ScalarDL 3.12** | ✅ | ✅ | ✅ | ✅ | ✅ |
| **ScalarDL 3.11** | ✅ | ✅ | ✅ | ✅ | ✅ |
| **ScalarDL 3.10** | ✅ | ✅ | ✅ | ✅ | ✅ |
| Version | Aurora MySQL 3 | Aurora MySQL 2 |
|:------------------|:----------------|:----------------|
| **ScalarDL 3.13** | ✅ | ✅ |
| **ScalarDL 3.12** | ✅ | ✅ |
| **ScalarDL 3.11** | ✅ | ✅ |
| **ScalarDL 3.10** | ✅ | ✅ |
| Version | Aurora PostgreSQL 17 | Aurora PostgreSQL 16 | Aurora PostgreSQL 15 | Aurora PostgreSQL 14 | Aurora PostgreSQL 13 |
|:------------------|:---------------------|:---------------------|:---------------------|:---------------------|:---------------------|
| **ScalarDL 3.13** | ✅ | ✅ | ✅ | ✅ | ✅ |
| **ScalarDL 3.12** | ✅ | ✅ | ✅ | ✅ | ✅ |
| **ScalarDL 3.11** | ✅ | ✅ | ✅ | ✅ | ✅ |
| **ScalarDL 3.10** | ✅ | ✅ | ✅ | ✅ | ✅ |
| Version | MariaDB 11.4 | MariaDB 10.11 |
|:------------------|:--------------|:--------------|
| **ScalarDL 3.13** | ✅ | ✅ |
| **ScalarDL 3.12** | ✅ | ✅ |
| **ScalarDL 3.11** | ✅ | ✅ |
| **ScalarDL 3.10** | ✅ | ✅ |
| Version | TiDB 8.5 | TiDB 7.5 | TiDB 6.5 |
|:------------------|:---------|:---------|----------|
| **ScalarDL 3.13** | ✅ | ✅ | ✅ |
| **ScalarDL 3.12** | ❌ | ❌ | ❌ |
| **ScalarDL 3.11** | ❌ | ❌ | ❌ |
| **ScalarDL 3.10** | ❌ | ❌ | ❌ |
| Version | AlloyDB 16 | AlloyDB 15 |
|:------------------|:-----------|:-----------|
| **ScalarDL 3.13** | ✅ | ✅ |
| **ScalarDL 3.12** | ❌ | ❌ |
| **ScalarDL 3.11** | ❌ | ❌ |
| **ScalarDL 3.10** | ❌ | ❌ |
| Version | SQL Server 2022 | SQL Server 2019 | SQL Server 2017 |
|:------------------|:-----------------|:-----------------|:-----------------|
| **ScalarDL 3.13** | ✅ | ✅ | ✅ |
| **ScalarDL 3.12** | ✅ | ✅ | ✅ |
| **ScalarDL 3.11** | ✅ | ✅ | ✅ |
| **ScalarDL 3.10** | ✅ | ✅ | ✅ |
| Version | SQLite 3 |
|:------------------|:----------|
| **ScalarDL 3.13** | ✅ |
| **ScalarDL 3.12** | ✅ |
| **ScalarDL 3.11** | ✅ |
| **ScalarDL 3.10** | ✅ |
| Version | YugabyteDB 2 |
|:------------------|:-------------|
| **ScalarDL 3.13** | ✅ |
| **ScalarDL 3.12** | ✅ |
| **ScalarDL 3.11** | ✅ |
| **ScalarDL 3.10** | ✅ |
### NoSQL databases
| Version | DynamoDB |
|:------------------|:----------|
| **ScalarDL 3.13** | ✅ |
| **ScalarDL 3.12** | ✅ |
| **ScalarDL 3.11** | ✅ |
| **ScalarDL 3.10** | ✅ |
| Version | Cassandra 5.0 | Cassandra 4.1 | Cassandra 3.11 | Cassandra 3.0 |
|:------------------|:---------------|:---------------|:----------------|:---------------|
| **ScalarDL 3.13** | ✅ | ✅ | ✅ | ✅ |
| **ScalarDL 3.12** | ✅ | ✅ | ✅ | ✅ |
| **ScalarDL 3.11** | ✅ | ✅ | ✅ | ✅ |
| **ScalarDL 3.10** | ✅ | ✅ | ✅ | ✅ |
| Version | Cosmos DB for NoSQL |
|:------------------|:---------------------|
| **ScalarDL 3.13** | ✅ |
| **ScalarDL 3.12** | ✅ |
| **ScalarDL 3.11** | ✅ |
| **ScalarDL 3.10** | ✅ |
:::note
ScalarDL uses ScalarDB to abstract underlying databases. For details on how to configure each database, see [Configurations for the Underlying Databases of ScalarDB](https://scalardb.scalar-labs.com/docs/latest/database-configurations).
The following list shows the versions of ScalarDB used in ScalarDL internally. This version list will help you if:
- You want to know what available backend databases you can use in ScalarDL. For details about which backend databases are supported and can be used in ScalarDL based on the version of ScalarDB, see the [list of databases that ScalarDB supports](https://scalardb.scalar-labs.com/docs/latest/requirements#databases/).
- You want to know what ScalarDB APIs are available for the `Function` feature in ScalarDL.
| ScalarDL version | ScalarDB version |
|:------------------------------|:-----------------|
| 3.13 | 3.17 |
| 3.12 | 3.16 |
| 3.11 | 3.15 |
| 3.10 | 3.14 |
:::
## Required ports
ScalarDL requires the following ports to be accessible. These default port numbers can be configured as needed:
- **ScalarDL Ledger**
- 50051 (normal request)
- 50052 (privileged request)
- 50053 (pause request)
- 8080 (metrics)
- **ScalarDL Auditor**
- 40051 (normal request)
- 40052 (privileged request)
- 40053 (pause request)
- 8080 (metrics)
- **ScalarDL Gateway**
- 30051 (normal request)
- 30052 (privileged request)
- 30053 (pause request)
- 8080 (metrics)
## Kubernetes
ScalarDL is provided as a Pod on the Kubernetes platform in production environments. ScalarDL supports the following platforms and tools.
### Platform
- **[Kubernetes](https://kubernetes.io/):** 1.32 - 1.35
- **[Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/)**
- **[Azure Kubernetes Service (AKS)](https://azure.microsoft.com/en-us/products/kubernetes-service)**
- **[Red Hat OpenShift](https://www.redhat.com/en/technologies/cloud-computing/openshift):** TBD
### Package manager
- **[Helm](https://helm.sh/):** 3.5+
================================================
FILE: docs/roadmap.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL Roadmap
This roadmap provides a look into the proposed future of ScalarDL. The purpose of this roadmap is to provide visibility into what changes may be coming so that you can more closely follow progress, learn about key milestones, and give feedback during development. This roadmap will be updated as new versions of ScalarDL are released.
:::warning
During the course of development, this roadmap is subject to change based on user needs and feedback. **Do not schedule your release plans according to the contents of this roadmap.**
If you have a feature request or want to prioritize feature development, please create an issue in [GitHub](https://github.com/scalar-labs/scalardl/issues).
:::
### CY2026 Q2
#### Improvements
- **Coordinator log purging**
- ScalarDL will automatically purge coordinator logs after transactions are completed so that users can manage their storage in a more cost-effective way.
#### Usability
- **Enable read operations during a paused duration**
- Users will be able to issue read operations even during a paused duration so that they can still read data while taking backups.
#### Cloud support
- **Google Cloud Marketplace support for ScalarDL**
- Users will be able to deploy ScalarDL by using the Google Cloud Marketplace offering, which enables users to use a pay-as-you-go subscription model.
### CY2026 Q3
#### New capabilities
- **Lifecycle management for assets**
- Users will be able to better manage the lifecycle of assets, ensuring they are preserved securely for an extended period.
#### Improvements
- **Encryption**
- Users will be able to encrypt their data so that they can manage their data in a more secure way.
- **Elimination of out-of-memory errors due to large scans**
- Users will be able to issue large scans without experiencing out-of-memory errors.
#### Cloud support
- **Azure Marketplace support for ScalarDL**
- Users will be able to deploy ScalarDL by using the Azure Marketplace offering, which enables users to use a pay-as-you-go subscription model.
- **Red Hat Ecosystem Catalog integration for ScalarDL**
- Users will be able to deploy ScalarDL from Red Hat Ecosystem Catalog, which enables users to use ScalarDL as Red Hat-certified third-party products and services.
### CY2026 Q4
#### Improvements
- **Performance optimizations**
- Users will be able to execute requests faster so that they can create ScalarDL applications in a more cost-effective way.
### CY2026 Q4 -
- **Lazy validation**
- Users will be able to validate the authenticity of their data lazily so that they can manage their data in a cost-effective way if their data doesn't need to be validated in real time.
### CY2027
#### New capabilities
- **New execution engine**
- Users will be able to execute requests more efficiently, ensuring better performance and resource utilization.
================================================
FILE: docs/scalardl-auditor-status-codes.mdx
================================================
---
tags:
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL Auditor Error Codes
This page provides a list of error codes in ScalarDL Auditor.
## Error code classes and descriptions
| Class | Description |
|:-------------------|:-----------------------------------------|
| `DL-AUDITOR-3xxxx` | Errors for the validation error category |
| `DL-AUDITOR-4xxxx` | Errors for the user error category |
| `DL-AUDITOR-5xxxx` | Errors for the internal error category |
## `DL-AUDITOR-3xxxx` status codes
The following are status codes and messages for the validation error category.
### `DL-AUDITOR-304001`
**Message**
```markdown
The nonce has already been used.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-AUDITOR-305001`
**Message**
```markdown
The request has been tampered with.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-AUDITOR-305002`
**Message**
```markdown
The specified asset proof doesn't exist in Ledger.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-AUDITOR-305003`
**Message**
```markdown
The specified request proof doesn't exist.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-AUDITOR-305004`
**Message**
```markdown
Hash validation failed.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-AUDITOR-305005`
**Message**
```markdown
The specified lock entry doesn't exist. A bug might exist, or tampering might have occurred.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-AUDITOR-305006`
**Message**
```markdown
An invalid asset proof is given. Namespace: %s; Asset ID: %s
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-AUDITOR-305007`
**Message**
```markdown
The expected asset record doesn't exist.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-AUDITOR-305008`
**Message**
```markdown
The specified asset and the asset lock are inconsistent.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-AUDITOR-305009`
**Message**
```markdown
The specified lock type is not supported. Type: %s
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-AUDITOR-305010`
**Message**
```markdown
readUnlock is used for unlocked or write-locked assets.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-AUDITOR-305011`
**Message**
```markdown
writeUnlock is used for unlocked or read-locked assets.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
## `DL-AUDITOR-4xxxx` status codes
The following are status codes and messages for the user error category.
### `DL-AUDITOR-407001`
**Message**
```markdown
The lock must be validated before it can be released.
```
**Solution**
```markdown
Validate the lock before attempting to release it.
```
### `DL-AUDITOR-409001`
**Message**
```markdown
The specified asset is not found.
```
**Solution**
```markdown
Verify the asset ID and namespace are correct and the asset has been created.
```
### `DL-AUDITOR-414001`
**Message**
```markdown
%s must be set if HMAC authentication is used.
```
**Solution**
```markdown
Set 'scalar.dl.auditor.authentication.hmac.cipher_key' in the Auditor configuration file (e.g., auditor.properties). Use an unpredictable and long value for security.
```
### `DL-AUDITOR-414002`
**Message**
```markdown
Authentication between Ledger and Auditor is not correctly configured. Set %s along with a private key with %s or %s if you use digital signature authentication.
```
**Solution**
```markdown
For digital signature authentication, set these properties in auditor.properties: 'scalar.dl.auditor.cert_holder_id' and either 'scalar.dl.auditor.private_key_path' (path to PEM file) or 'scalar.dl.auditor.private_key_pem' (PEM-encoded data). Ensure the authentication method matches the Ledger configuration.
```
### `DL-AUDITOR-414003`
**Message**
```markdown
Authentication between Ledger and Auditor is not correctly configured. Set %s if you use HMAC authentication.
```
**Solution**
```markdown
For HMAC authentication between Ledger and Auditor, set 'scalar.dl.auditor.servers.authentication.hmac.secret_key' in auditor.properties with a shared secret. This must match the Ledger's corresponding HMAC secret key.
```
## `DL-AUDITOR-5xxxx` status codes
The following are status codes and messages for the internal error category.
### `DL-AUDITOR-500001`
**Message**
```markdown
Binding the request proof failed. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify your database configuration and connection.
```
### `DL-AUDITOR-500002`
**Message**
```markdown
Getting the request proof failed. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify your database configuration and connection.
```
### `DL-AUDITOR-500003`
**Message**
```markdown
Binding the asset record failed. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify your database configuration and connection.
```
### `DL-AUDITOR-500004`
**Message**
```markdown
Retrieving the asset records failed. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify your database configuration and connection.
```
### `DL-AUDITOR-500005`
**Message**
```markdown
Getting the asset lock failed. Namespace: %s; Asset ID: %s; Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify your database configuration and connection.
```
### `DL-AUDITOR-504001`
**Message**
```markdown
The specified lock entry is currently held by a writer.
```
**Solution**
```markdown
Retry the operation.
```
### `DL-AUDITOR-504002`
**Message**
```markdown
The specified asset record is in use.
```
**Solution**
```markdown
Retry the operation.
```
### `DL-AUDITOR-504003`
**Message**
```markdown
The entry has already been recovered, or an issue might have occurred.
```
**Solution**
```markdown
Retry the operation. Contact your system administrator to check for any signs of malicious activity if the issue persists.
```
================================================
FILE: docs/scalardl-client-status-codes.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL Client Error Codes
This page provides a list of error codes in ScalarDL clients.
## Error code classes and descriptions
| Class | Description |
|:------------------|:-----------------------------------------|
| `DL-CLIENT-3xxxx` | Errors for the validation error category |
| `DL-CLIENT-4xxxx` | Errors for the user error category |
| `DL-CLIENT-5xxxx` | Errors for the internal error category |
## `DL-CLIENT-3xxxx` status codes
The following are status codes and messages for the validation error category.
### `DL-CLIENT-305001`
**Message**
```markdown
The results from Ledger and Auditor don't match.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
## `DL-CLIENT-4xxxx` status codes
The following are status codes and messages for the user error category.
### `DL-CLIENT-414001`
**Message**
```markdown
The specified option --asset-id is malformed. The format should be "[assetId]" or "[assetId],[startAge],[endAge]".
```
**Solution**
```markdown
Provide the asset ID in the correct format: "[assetId]" or "[assetId],[startAge],[endAge]".
```
### `DL-CLIENT-414002`
**Message**
```markdown
The specified option --asset-id contains an invalid integer.
```
**Solution**
```markdown
Provide valid integers for startAge and endAge in the asset ID.
```
### `DL-CLIENT-414003`
**Message**
```markdown
The authentication method for the client mode must be either digital-signature or hmac.
```
**Solution**
```markdown
Set the authentication method to either 'digital-signature' or 'hmac' in your configuration.
```
### `DL-CLIENT-414004`
**Message**
```markdown
The authentication method for the intermediary mode must be pass-through.
```
**Solution**
```markdown
Set the authentication method to 'pass-through' in your configuration.
```
### `DL-CLIENT-414005`
**Message**
```markdown
Both the certificate and the private key must be set to use digital signature.
```
**Solution**
```markdown
Provide both the certificate and the private key in your configuration.
```
### `DL-CLIENT-414006`
**Message**
```markdown
The secret key must be set to use HMAC authentication.
```
**Solution**
```markdown
Provide the secret key in your configuration.
```
### `DL-CLIENT-414007`
**Message**
```markdown
%s and %s are missing, but either is required.
```
**Solution**
```markdown
Provide either the entity ID or the certificate holder ID in your configuration.
```
### `DL-CLIENT-414008`
**Message**
```markdown
Digital signature authentication is not configured.
```
**Solution**
```markdown
Configure digital signature authentication with the required certificate and private key.
```
### `DL-CLIENT-414009`
**Message**
```markdown
HMAC authentication is not configured.
```
**Solution**
```markdown
Configure HMAC authentication with the required secret key.
```
### `DL-CLIENT-414010`
**Message**
```markdown
validateLedger with Auditor is not supported in the intermediary mode. Please execute the ValidateLedger contract to validate assets.
```
**Solution**
```markdown
Execute the ValidateLedger contract to validate assets in intermediary mode.
```
### `DL-CLIENT-414011`
**Message**
```markdown
The specified client mode is incorrect.
```
**Solution**
```markdown
Provide a valid client mode in your configuration.
```
### `DL-CLIENT-414012`
**Message**
```markdown
The contract ID cannot be null.
```
**Solution**
```markdown
Provide a non-null contract ID.
```
### `DL-CLIENT-414013`
**Message**
```markdown
The contract name cannot be null.
```
**Solution**
```markdown
Provide a non-null contract name.
```
### `DL-CLIENT-414014`
**Message**
```markdown
The contractBytes cannot be null.
```
**Solution**
```markdown
Provide non-null contract bytes.
```
### `DL-CLIENT-414015`
**Message**
```markdown
The contractArgument cannot be null.
```
**Solution**
```markdown
Provide a non-null contract argument.
```
### `DL-CLIENT-414016`
**Message**
```markdown
The contractPath cannot be null.
```
**Solution**
```markdown
Provide a non-null contract path.
```
### `DL-CLIENT-414017`
**Message**
```markdown
The function ID cannot be null.
```
**Solution**
```markdown
Provide a non-null function ID.
```
### `DL-CLIENT-414018`
**Message**
```markdown
The function name cannot be null.
```
**Solution**
```markdown
Provide a non-null function name.
```
### `DL-CLIENT-414019`
**Message**
```markdown
The functionBytes cannot be null.
```
**Solution**
```markdown
Provide non-null function bytes.
```
### `DL-CLIENT-414020`
**Message**
```markdown
The functionPath cannot be null.
```
**Solution**
```markdown
Provide a non-null function path.
```
### `DL-CLIENT-414021`
**Message**
```markdown
The asset ID cannot be null.
```
**Solution**
```markdown
Provide a non-null asset ID.
```
### `DL-CLIENT-414022`
**Message**
```markdown
The specified asset ages are invalid.
```
**Solution**
```markdown
Ensure that startAge is non-negative (>= 0) and endAge is greater than or equal to startAge.
```
### `DL-CLIENT-414023`
**Message**
```markdown
The specified asset type is incorrect.
```
**Solution**
```markdown
Provide a valid asset type.
```
### `DL-CLIENT-414024`
**Message**
```markdown
The specified keys are incorrect for the asset type.
```
**Solution**
```markdown
Provide valid keys for the asset type.
```
### `DL-CLIENT-414025`
**Message**
```markdown
The namespace name cannot be null.
```
**Solution**
```markdown
Provide a non-null namespace name.
```
### `DL-CLIENT-414026`
**Message**
```markdown
The entity ID cannot be null.
```
**Solution**
```markdown
Provide a non-null entity ID in your service request.
```
### `DL-CLIENT-414027`
**Message**
```markdown
The certificate in PEM format cannot be null.
```
**Solution**
```markdown
Provide a valid certificate in PEM format in your service request.
```
### `DL-CLIENT-414028`
**Message**
```markdown
The secret key cannot be null.
```
**Solution**
```markdown
Provide a non-null secret key in your service request.
```
## `DL-CLIENT-5xxxx` status codes
The following are status codes and messages for the internal error category.
### `DL-CLIENT-502001`
**Message**
```markdown
Reading the file failed. File: %s; Details: %s
```
**Solution**
```markdown
Verify that the file exists and has the correct permissions.
```
### `DL-CLIENT-502002`
**Message**
```markdown
Configuring SSL failed. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify that the SSL configuration is correct.
```
### `DL-CLIENT-502003`
**Message**
```markdown
Shutting down the channel failed. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify that the channel is in a valid state.
```
### `DL-CLIENT-502004`
**Message**
```markdown
Processing JSON failed. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify that the JSON data is well-formed.
```
### `DL-CLIENT-502005`
**Message**
```markdown
Failed to load the class file. File: %s
```
**Solution**
```markdown
Verify that the class file exists and is in the correct format.
```
### `DL-CLIENT-502006`
**Message**
```markdown
Failed to write the result to a file. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify that the file path is valid and writable.
```
================================================
FILE: docs/scalardl-command-reference.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL Client Command Reference
This page introduces `scalardl`, which is a client command for interacting with ScalarDL components.
## Overview of commands
- **Bootstrap a client**
- [`bootstrap`](#bootstrap): Bootstrap a client by registering the identity information and system contracts.
- **Register identity information**
- [`register-cert`](#register-cert): Register a specified certificate.
- [`register-secret`](#register-secret): Register a specified secret.
- **Register business logic**
- [`register-contract`](#register-contract): Register a specified contract.
- [`register-contracts`](#register-contracts): Register specified contracts.
- [`register-function`](#register-function): Register a specified function.
- [`register-functions`](#register-functions): Register specified functions.
- **Execute and list the registered business logic**
- [`execute-contract`](#execute-contract): Execute a specified contract.
- [`list-contracts`](#list-contracts): List registered contracts.
- **Manage namespaces**
- [`create-namespace`](#create-namespace): Create a namespace.
- [`list-namespaces`](#list-namespaces): List namespaces.
- [`drop-namespace`](#drop-namespace): Drop a namespace.
- **Validate a ledger**
- [`validate-ledger`](#validate-ledger): Validate a specified asset in a ledger.
- **Run commands for generic-contracts**
- [`generic-contracts`](#generic-contracts): Run commands for a generic-contracts-based setup.
## `bootstrap`
Bootstrap a client by registering the identity information and system contracts. This command performs the following:
1. Registers a certificate or secret based on the authentication method configured in the properties file.
2. Registers the `ValidateLedger` contract if Auditor is enabled.
If the identity information or the contract is already registered, the command skips the registration and continues without error.
### Options
| Option | Description |
|:---------------------------|:-------------------------------------------|
| `--config`, `--properties` | A configuration file in properties format. |
[Common utility options](#common-utility-options) are also available.
### Examples
```console
scalardl bootstrap --properties client.properties
```
## `register-cert`
Register a specified certificate.
### Options
| Option | Description |
|:---------------------------|:---------------------------------------------------------------|
| `--config`, `--properties` | A configuration file in properties format. |
| `--namespace` | A namespace where the certificate is registered. |
| `--entity-id` | An entity ID for the certificate. |
| `--cert-path` | A path to a PEM-formatted certificate file. |
| `--cert-version` | The version of the certificate (default: 1). |
When `--namespace` is specified, `--entity-id` and `--cert-path` are also required. When `--namespace` is not specified, the identity information from the properties file is used.
[Common utility options](#common-utility-options) are also available.
### Examples
Register a certificate by using identity information from the properties file.
```console
scalardl register-cert --properties client.properties
```
Register a certificate to a specific namespace.
```console
scalardl register-cert --properties client.properties --namespace my_namespace --entity-id my_entity --cert-path /path/to/cert.pem
```
## `register-secret`
Register a specified secret.
### Options
| Option | Description |
|:---------------------------|:---------------------------------------------------------------|
| `--config`, `--properties` | A configuration file in properties format. |
| `--namespace` | A namespace where the secret is registered. |
| `--entity-id` | An entity ID for the secret. |
| `--secret-key` | A secret key for HMAC authentication. |
| `--secret-key-version` | The version of the secret key (default: 1). |
When `--namespace` is specified, `--entity-id` and `--secret-key` are also required. When `--namespace` is not specified, the identity information from the properties file is used.
[Common utility options](#common-utility-options) are also available.
### Examples
Register a secret by using identity information from the properties file.
```console
scalardl register-secret --properties client.properties
```
Register a secret to a specific namespace.
```console
scalardl register-secret --properties client.properties --namespace my_namespace --entity-id my_entity --secret-key my-secret-key
```
## `register-contract`
Register a specified contract.
### Options
| Option | Description |
|:---------------------------|:-----------------------------------------------------------------------------------------------|
| `--config`, `--properties` | A configuration file in properties format. |
| `--contract-binary-name` | A binary name of a contract to register. |
| `--contract-class-file` | A contract class file to register. |
| `--contract-id` | An ID of a contract to register. |
| `--contract-properties` | Contract properties in a serialized format. |
| `--deserialization-format` | A deserialization format for contract properties. Valid values: JSON or STRING (default: JSON) |
[Common utility options](#common-utility-options) are also available.
### Examples
```console
scalardl register-contract --properties client.properties --contract-id StateUpdater --contract-binary-name com.org1.contract.StateUpdater --contract-class-file build/classes/java/main/com/org1/contract/StateUpdater.class
```
## `register-contracts`
Register specified contracts.
### Options
| Option | Description |
|:---------------------------|:-------------------------------------------------------|
| `--config`, `--properties` | A configuration file in properties format. |
| `--contracts-file` | A file that includes contracts to register in TOML format. |
[Common utility options](#common-utility-options) are also available.
### Examples
```console
scalardl register-contracts --properties client.properties --contracts-file /path/to/contracts-file
```
An example of the contracts file is as follows.
```toml
[[contracts]]
contract-id = "StateUpdater"
contract-binary-name = "com.org1.contract.StateUpdater"
contract-class-file = "build/classes/java/main/com/org1/contract/StateUpdater.class"
[[contracts]]
contract-id = "StateReader"
contract-binary-name = "com.org1.contract.StateReader"
contract-class-file = "build/classes/java/main/com/org1/contract/StateReader.class"
```
## `register-function`
Register a specified function.
### Options
| Option | Description |
|:---------------------------|:-----------------------------------------------------------------------------------------------|
| `--config`, `--properties` | A configuration file in properties format. |
| `--function-binary-name` | A binary name of a function to register. |
| `--function-class-file` | A function class file to register. |
| `--function-id` | An ID of a function to register. |
[Common utility options](#common-utility-options) are also available.
### Examples
```console
scalardl register-function --properties client.properties --function-id test-function --function-binary-name com.example.function.TestFunction --function-class-file /path/to/TestFunction.class
```
## `register-functions`
Register specified functions.
### Options
| Option | Description |
|:---------------------------|:-------------------------------------------------------|
| `--config`, `--properties` | A configuration file in properties format. |
| `--functions-file` | A file that includes functions to register in TOML format. |
[Common utility options](#common-utility-options) are also available.
### Examples
```console
scalardl register-functions --properties client.properties --functions-file /path/to/functions-file
```
An example of the functions file is as follows.
```toml
[[functions]]
function-id = "TestFunction1"
function-binary-name = "com.org1.function.TestFunction1"
function-class-file = "build/classes/java/main/com/org1/function/TestFunction1.class"
[[functions]]
function-id = "TestFunction2"
function-binary-name = "com.org1.function.TestFunction2"
function-class-file = "build/classes/java/main/com/org1/function/TestFunction2.class"
```
## `execute-contract`
Execute a specified contract.
### Options
| Option | Description |
|:---------------------------|:---------------------------------------------------------------------------------------------------------|
| `--config`, `--properties` | A configuration file in properties format. |
| `--contract-argument` | An argument for a contract to execute in a serialized format. |
| `--contract-id` | An ID of a contract to execute. |
| `--deserialization-format` | A deserialization format for contract and function arguments. Valid values: JSON or STRING (default: JSON) |
| `--function-id` | An ID of a function to execute. |
[Common utility options](#common-utility-options) are also available.
### Examples
Execute a contract without a function.
```console
scalardl execute-contract --properties client.properties --contract-id StateUpdater --contract-argument '{"asset_id":"some_asset", "state":3}'
```
Execute a contract with a function.
```console
scalardl execute-contract --properties client.properties --contract-id TestContract --contract-argument '{...}' --function-id TestFunction --function-argument '{...}'
```
## `list-contracts`
List registered contracts.
### Options
| Option | Description |
|:---------------------------|:-------------------------------------------|
| `--config`, `--properties` | A configuration file in properties format. |
| `--contract-id` | The ID of a contract to show. |
[Common utility options](#common-utility-options) are also available.
### Examples
List all contracts registered by the specified entity.
```console
scalardl list-contracts --properties client.properties
```
Show a specified contract only.
```console
scalardl list-contracts --properties client.properties --contract-id StateUpdater
```
## `create-namespace`
:::warning
The namespace feature is currently in Public Preview. The feature and related documentation are subject to change.
:::
Create a namespace. A namespace name must start with an alphabetic character and can only contain alphanumeric characters and underscores (pattern: `[a-zA-Z][a-zA-Z0-9_]*`). The default namespace `default` is reserved and cannot be created or dropped.
### Options
| Option | Description |
|:---------------------------|:-------------------------------------------|
| `--config`, `--properties` | A configuration file in properties format. |
| `--namespace` | A name for the namespace that will be created. |
[Common utility options](#common-utility-options) are also available.
### Examples
```console
scalardl create-namespace --properties client.properties --namespace my_namespace
```
## `list-namespaces`
:::warning
The namespace feature is currently in Public Preview. The feature and related documentation are subject to change.
:::
List namespaces.
### Options
| Option | Description |
|:---------------------------|:----------------------------------------------|
| `--config`, `--properties` | A configuration file in properties format. |
| `--pattern` | A pattern to filter namespaces (partial match). |
[Common utility options](#common-utility-options) are also available.
### Examples
List all namespaces.
```console
scalardl list-namespaces --properties client.properties
```
List namespaces that match a specified pattern.
```console
scalardl list-namespaces --properties client.properties --pattern my_
```
## `drop-namespace`
:::warning
The namespace feature is currently in Public Preview. The feature and related documentation are subject to change.
:::
Drop a namespace. This command requires confirmation by typing the namespace name.
### Options
| Option | Description |
|:---------------------------|:-------------------------------------------|
| `--config`, `--properties` | A configuration file in properties format. |
| `--namespace` | The name of the namespace to drop. |
[Common utility options](#common-utility-options) are also available.
### Examples
```console
scalardl drop-namespace --properties client.properties --namespace my_namespace
```
## `validate-ledger`
Validate a specified asset in a ledger.
### Options
| Option | Description |
|:---------------------------|:---------------------------------------------------------------------------------------|
| `--config`, `--properties` | A configuration file in properties format. |
| `--namespace` | The namespace of the asset. If not specified, the `scalar.dl.client.context.namespace` value in the properties file will be used. If that is also not configured, the `default` namespace will be used. |
| `--asset-id` | The ID of an asset or the ID and the ages of an asset. Format: 'ASSET_ID', the ID of an asset to validate, or 'ASSET_ID,START_AGE,END_AGE', the ID and the ages of an asset to validate. |
[Common utility options](#common-utility-options) are also available.
### Examples
Validate an asset for all ages.
```console
scalardl validate-ledger --properties client.properties --asset-id 'some_asset'
```
Validate an asset from age 0 to age 10 only.
```console
scalardl validate-ledger --properties client.properties --asset-id 'some_asset,0,10'
```
## `generic-contracts`
:::tip
Although generic contracts were introduced in ScalarDL 3.10, HashStore, released in ScalarDL 3.12, provides a higher-level abstraction that wraps generic contracts. For most use cases, using HashStore is simpler and more efficient than using generic contracts directly. For details, see [Get Started with ScalarDL HashStore](./getting-started-hashstore.mdx) in the latest version of ScalarDL.
:::
Run commands for a generic-contracts-based setup, which are almost the same subcommands for the `scalardl` command. The only difference is in the `validate-ledger` subcommand, where you can specify assets by object IDs of the generic-contracts context instead of the raw asset IDs. For the other subcommands, see each corresponding command in the following [Subcommands](#subcommands) section.
:::tip
You can also use the `scalardl-gc` top-level command and the `gc` subcommand as aliases of the `generic-contracts` subcommand.
:::
### Subcommands
| Subcommand | Description |
|:------------------------------------------------------------|:----------------------------------------|
| [`register-cert`](#register-cert) | Register a specified certificate. |
| [`register-secret`](#register-secret) | Register a specified secret. |
| [`register-contract`](#register-contract) | Register a specified contract. |
| [`register-contracts`](#register-contracts) | Register multiple specified contracts. |
| [`register-function`](#register-function) | Register a specified function. |
| [`register-functions`](#register-functions) | Register multiple specified functions. |
| [`execute-contract`](#execute-contract) | Execute a specified contract. |
| [`list-contracts`](#list-contracts) | List the registered contracts. |
| [`validate-ledger`](#validate-ledger-for-generic-contracts) | Validate a specified asset in a ledger. |
### `validate-ledger` for generic contracts
Validate a specified [asset](data-modeling.mdx#asset) in a ledger.
:::note
Generic contracts internally assign a dedicated asset ID to an [asset record](data-modeling.mdx#asset-record) that represents an object or collection. The asset ID consists of a prefix for the asset type and keys; for example, a prefix `o_` and an object ID for an object. Therefore, you will see such raw asset IDs after running the `validate-ledger` command.
:::
#### Options
| Option | Description |
|:---------------------------|:---------------------------------------------------------------------|
| `--config`, `--properties` | A configuration file in the .properties format. |
| `--object-id` | The ID of an object created by the `object.Put` contract. |
| `--collection-id` | The ID of a collection created by the `collection.Create` contract. |
| `--start-age` | The validation start age of the asset (optional). |
| `--end-age` | The validation end age of the asset (optional). |
[Common utility options](#common-utility-options) are also available.
### Examples for using subcommands
Register a specified certificate. For available options, see [`register-cert`](#register-cert).
```console
scalardl generic-contracts register-cert --properties client.properties
```
Register a specified secret. For available options, see [`register-secret`](#register-secret).
```console
scalardl generic-contracts register-secret --properties client.properties
```
Register a specified contract. For available options, see [`register-contract`](#register-contract).
```console
scalardl generic-contracts register-contract --properties client.properties --contract-id object.Put --contract-binary-name com.scalar.dl.genericcontracts.object.Put --contract-class-file /path/to/Put.class
```
Register specified contracts. For available options, see [`register-contracts`](#register-contracts).
```console
scalardl generic-contracts register-contracts --properties client.properties --contracts-file /path/to/contracts-file
```
Register a specified function. For available options, see [`register-function`](#register-function).
```console
scalardl generic-contracts register-function --properties client.properties --function-id object.PutToMutableDatabase --function-binary-name com.scalar.dl.genericcontracts.object.PutToMutableDatabase --function-class-file /path/to/PutToMutableDatabase.class
```
Register specified functions. For available options, see [`register-functions`](#register-functions).
```console
scalardl generic-contracts register-functions --properties client.properties --functions-file /path/to/functions-file
```
Execute a specified contract. For available options, see [`execute-contract`](#execute-contract).
```console
scalardl generic-contracts execute-contract --properties client.properties --contract-id object.Put --contract-argument '{"object_id": "a.txt", "hash_value": "b97a42c87a46ffebe1439f8c1cd2f86e2f9b84dad89c8e9ebb257a19b6fdfe1c", "metadata": {"note": "updated"}}'
```
List registered contracts. For available options, see [`list-contracts`](#list-contracts).
```console
scalardl generic-contracts list-contracts --properties client.properties
```
Validate an object for all ages.
```console
scalardl generic-contracts validate-ledger --properties client.properties --object-id 'a.txt'
```
Validate an object from age 0 to age 10 only.
```console
scalardl generic-contracts validate-ledger --properties client.properties --object-id 'a.txt' --start-age 0 --end-age 10
```
Validate a collection for all ages.
```console
scalardl generic-contracts validate-ledger --properties client.properties --collection-id 'audit_set'
```
Use the top-level command `scalardl-gc` as the alias of `scalardl generic-contracts`.
```console
scalardl-gc validate-ledger --properties client.properties --object-id 'a.txt'
```
Use the subcommand `scalardl gc` as the alias of `scalardl generic-contracts`.
```console
scalardl gc validate-ledger --properties client.properties --object-id 'a.txt'
```
## Common utility options
You can use the following options in all the commands above.
| Option | Description |
|:----------------------|:--------------------------------------------|
| `-g`, `--use-gateway` | A flag to use the gateway. |
| `-h`, `--help` | Display the help message of a command. |
| `--stacktrace` | Output Java Stack Trace to `stderr` stream. |
================================================
FILE: docs/scalardl-common-status-codes.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL Common Error Codes
This page provides a list of error codes common across ScalarDL.
## Error code classes and descriptions
| Class | Description |
|:------------------|:-----------------------------------------|
| `DL-COMMON-3xxxx` | Errors for the validation error category |
| `DL-COMMON-4xxxx` | Errors for the user error category |
| `DL-COMMON-5xxxx` | Errors for the internal error category |
## `DL-COMMON-3xxxx` status codes
The following are status codes and messages for the validation error category.
### `DL-COMMON-302001`
**Message**
```markdown
The format of the contract ID is invalid.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-COMMON-302002`
**Message**
```markdown
Contract validation failed. A bug might exist, or tampering might have occurred.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-COMMON-305001`
**Message**
```markdown
An unexpected record value is observed. A bug might exist, or tampering might have occurred. Details: %s
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
## `DL-COMMON-4xxxx` status codes
The following are status codes and messages for the user error category.
### `DL-COMMON-400001`
**Message**
```markdown
Signing failed. Details: %s
```
**Solution**
```markdown
Verify that your private key is valid and accessible. Check the error details for specific issues.
```
### `DL-COMMON-400002`
**Message**
```markdown
Validating signature failed. Details: %s
```
**Solution**
```markdown
Verify that the certificate matches the private key used for signing and that both are valid.
```
### `DL-COMMON-400003`
**Message**
```markdown
The request signature can't be validated.
```
**Solution**
```markdown
Verify that the certificate used for signing the request is registered and matches the private key.
```
### `DL-COMMON-400004`
**Message**
```markdown
The proof signature can't be validated.
```
**Solution**
```markdown
Verify that the proof configuration is correct and that the certificate used for signing is valid.
```
### `DL-COMMON-401001`
**Message**
```markdown
Loading the key failed. Details: %s
```
**Solution**
```markdown
If using a key file, verify that it exists at the specified path, is readable, and has the correct format. If using a PEM-formatted string, verify that the key has the correct format.
```
### `DL-COMMON-401002`
**Message**
```markdown
Loading the certificate failed. Details: %s
```
**Solution**
```markdown
If using a certificate file, verify that it exists at the specified path, is readable, and has the correct format. If using a PEM-formatted string, verify that the certificate has the correct format.
```
### `DL-COMMON-401003`
**Message**
```markdown
Creating a cipher key failed. Details: %s
```
**Solution**
```markdown
Verify that the cipher configuration is correct and that the key material is valid.
```
### `DL-COMMON-401004`
**Message**
```markdown
Invalid private key. File: %s
```
**Solution**
```markdown
Provide a valid private key file in PEM format at the specified path.
```
### `DL-COMMON-401005`
**Message**
```markdown
Invalid certificate. File: %s
```
**Solution**
```markdown
Provide a valid certificate file in PEM format at the specified path.
```
### `DL-COMMON-401006`
**Message**
```markdown
Reading the private key failed. File: %s; Details: %s
```
**Solution**
```markdown
Verify that the private key file exists, is readable, and has the correct permissions and format.
```
### `DL-COMMON-401007`
**Message**
```markdown
Reading the certificate failed. File: %s; Details: %s
```
**Solution**
```markdown
Verify that the certificate file exists, is readable, and has the correct permissions and format.
```
### `DL-COMMON-401008`
**Message**
```markdown
Creating a key store failed. Details: %s
```
**Solution**
```markdown
Verify that the key store configuration is correct and that all required files are accessible.
```
### `DL-COMMON-402001`
**Message**
```markdown
Loading the contract failed. Details: %s
```
**Solution**
```markdown
Verify that the contract class is valid and all dependencies are available. Check the error details for specific issues.
```
### `DL-COMMON-403001`
**Message**
```markdown
The specified certificate is not found.
```
**Solution**
```markdown
Before using the certificate, register it by using the register-cert command.
```
### `DL-COMMON-404001`
**Message**
```markdown
The specified contract is not found.
```
**Solution**
```markdown
Before executing the contract, register it by using the register-contract command.
```
### `DL-COMMON-405001`
**Message**
```markdown
The specified certificate is already registered.
```
**Solution**
```markdown
Use the existing certificate or register it with a new version number.
```
### `DL-COMMON-406001`
**Message**
```markdown
The specified contract is already registered.
```
**Solution**
```markdown
Use the existing contract or register it with a different contract ID.
```
### `DL-COMMON-406002`
**Message**
```markdown
The specified contract binary name has been already registered with a different byte code.
```
**Solution**
```markdown
Use a different contract ID or class name to register this version of the contract.
```
### `DL-COMMON-407001`
**Message**
```markdown
Accessing the specified namespace is not allowed. Namespace: %s, context namespace: %s
```
**Solution**
```markdown
Verify that your certificate or secret has been registered to the specified namespace, or use the appropriate context namespace for your operation.
```
### `DL-COMMON-413001`
**Message**
```markdown
The specified secret is already registered.
```
**Solution**
```markdown
Use the existing secret or register it with a new version number.
```
### `DL-COMMON-414001`
**Message**
```markdown
The specified value of the property '%s' is not a number. Value: %s
```
**Solution**
```markdown
Set the property to a valid numeric value in your configuration.
```
### `DL-COMMON-414002`
**Message**
```markdown
The specified value of the property '%s' is not a boolean. Value: %s
```
**Solution**
```markdown
Set the property to 'true' or 'false' in your configuration.
```
### `DL-COMMON-414003`
**Message**
```markdown
Reading the file failed. File: %s
```
**Solution**
```markdown
Verify that the file exists at the specified path and is readable.
```
### `DL-COMMON-414004`
**Message**
```markdown
Please set your license key to %s.
```
**Solution**
```markdown
Set your license key to the specified configuration property.
```
### `DL-COMMON-414005`
**Message**
```markdown
Please set your certificate for checking the corresponding license key to %s or %s.
```
**Solution**
```markdown
Set your certificate to one of the specified configuration properties.
```
### `DL-COMMON-414006`
**Message**
```markdown
The license key is not for the product '%s'. Please set the correct license key.
```
**Solution**
```markdown
Set the correct license key for the product in your configuration.
```
### `DL-COMMON-414007`
**Message**
```markdown
The license type of the license key must be ENTERPRISE or TRIAL. Please set the correct license key.
```
**Solution**
```markdown
Set a valid ENTERPRISE or TRIAL license key in your configuration.
```
### `DL-COMMON-414008`
**Message**
```markdown
The port and privileged port must be greater than or equal to zero.
```
**Solution**
```markdown
Set the port and privileged port to valid values (>= 0) in your configuration.
```
### `DL-COMMON-414009`
**Message**
```markdown
The private key and certificate are required.
```
**Solution**
```markdown
Provide both the private key and certificate in your configuration.
```
### `DL-COMMON-414010`
**Message**
```markdown
The certificate version must be greater than zero.
```
**Solution**
```markdown
Set the certificate version to a value greater than zero.
```
### `DL-COMMON-414011`
**Message**
```markdown
A secret key is required for HMAC authentication.
```
**Solution**
```markdown
Provide a secret key in your configuration for HMAC authentication.
```
### `DL-COMMON-414012`
**Message**
```markdown
The secret version for HMAC authentication must be greater than zero.
```
**Solution**
```markdown
Set the secret version to a value greater than zero.
```
### `DL-COMMON-414013`
**Message**
```markdown
The grpc deadline duration must be greater than or equal to zero.
```
**Solution**
```markdown
Set the gRPC deadline duration to a value greater than or equal to zero in your configuration.
```
### `DL-COMMON-414014`
**Message**
```markdown
The grpc max inbound message size must be greater than or equal to zero.
```
**Solution**
```markdown
Set the gRPC max inbound message size to a value greater than or equal to zero in your configuration.
```
### `DL-COMMON-414015`
**Message**
```markdown
The grpc max inbound metadata size must be greater than or equal to zero.
```
**Solution**
```markdown
Set the gRPC max inbound metadata size to a value greater than or equal to zero in your configuration.
```
### `DL-COMMON-414016`
**Message**
```markdown
The authentication method name is invalid. Name: %s
```
**Solution**
```markdown
Set the authentication method to a valid value (like 'digital-signature' or 'hmac') in your configuration.
```
### `DL-COMMON-414017`
**Message**
```markdown
The argument format is illegal.
```
**Solution**
```markdown
Provide the argument in the correct format. Check the documentation for the expected format.
```
### `DL-COMMON-414018`
**Message**
```markdown
The deserialization type is not supported. Type: %s
```
**Solution**
```markdown
Use a supported deserialization type. Check the documentation for valid types.
```
### `DL-COMMON-414019`
**Message**
```markdown
The namespace name is invalid. Name: %s
```
**Solution**
```markdown
Provide a valid namespace name that meets the naming requirements.
```
### `DL-COMMON-414020`
**Message**
```markdown
Namespace-aware interfaces are not supported in deprecated contracts.
```
**Solution**
```markdown
Use the non-namespace-aware interfaces or migrate to the newer contract interfaces that support namespaces.
```
### `DL-COMMON-414021`
**Message**
```markdown
The specified namespace is reserved and cannot be created or deleted. Name: %s
```
**Solution**
```markdown
Use a different namespace name that is not reserved. Reserved namespaces are managed by the system and cannot be modified.
```
### `DL-COMMON-415001`
**Message**
```markdown
The specified secret is not found.
```
**Solution**
```markdown
Before using the secret, register it by using the register-secret command.
```
### `DL-COMMON-416001`
**Message**
```markdown
The specified namespace already exists.
```
**Solution**
```markdown
Use the existing namespace or choose a different namespace name.
```
### `DL-COMMON-417001`
**Message**
```markdown
The specified namespace is not found. Namespace: %s
```
**Solution**
```markdown
Create the namespace first or verify that the namespace name is correct.
```
## `DL-COMMON-5xxxx` status codes
The following are status codes and messages for the internal error category.
### `DL-COMMON-500001`
**Message**
```markdown
Binding the certificate failed. Details: %s
```
**Solution**
```markdown
Check the database connection and ensure the database is accessible. Review the error details for more information.
```
### `DL-COMMON-500002`
**Message**
```markdown
Unbinding the certificate failed. Details: %s
```
**Solution**
```markdown
Check the database connection and ensure the database is accessible. Review the error details for more information.
```
### `DL-COMMON-500003`
**Message**
```markdown
Getting the certificate failed. Details: %s
```
**Solution**
```markdown
Check the database connection and ensure the database is accessible. Review the error details for more information.
```
### `DL-COMMON-500004`
**Message**
```markdown
Binding the secret key failed. Details: %s
```
**Solution**
```markdown
Check the database connection and ensure the database is accessible. Review the error details for more information.
```
### `DL-COMMON-500005`
**Message**
```markdown
Unbinding the secret key failed. Details: %s
```
**Solution**
```markdown
Check the database connection and ensure the database is accessible. Review the error details for more information.
```
### `DL-COMMON-500006`
**Message**
```markdown
Getting the secret key failed. Details: %s
```
**Solution**
```markdown
Check the database connection and ensure the database is accessible. Review the error details for more information.
```
### `DL-COMMON-500007`
**Message**
```markdown
Binding the contract failed. Details: %s
```
**Solution**
```markdown
Check the database connection and ensure the database is accessible. Review the error details for more information.
```
### `DL-COMMON-500008`
**Message**
```markdown
Getting the contract failed. Details: %s
```
**Solution**
```markdown
Check the database connection and ensure the database is accessible. Review the error details for more information.
```
### `DL-COMMON-500009`
**Message**
```markdown
Scanning the contracts failed. Details: %s
```
**Solution**
```markdown
Check the database connection and ensure the database is accessible. Review the error details for more information.
```
### `DL-COMMON-500010`
**Message**
```markdown
Creating the namespace table failed. Details: %s
```
**Solution**
```markdown
Check the database connection and ensure the database is accessible. Review the error details for more information.
```
### `DL-COMMON-500011`
**Message**
```markdown
Creating the namespace failed. Details: %s
```
**Solution**
```markdown
Check the database connection and ensure the database is accessible. Review the error details for more information.
```
### `DL-COMMON-500012`
**Message**
```markdown
Scanning the namespaces failed. Details: %s
```
**Solution**
```markdown
Check the database connection and ensure the database is accessible. Review the error details for more information.
```
### `DL-COMMON-500013`
**Message**
```markdown
Dropping the namespace failed. Details: %s
```
**Solution**
```markdown
Check the database connection and ensure the database is accessible. Review the error details for more information.
```
### `DL-COMMON-502001`
**Message**
```markdown
Serializing the specified json failed. Details: %s
```
**Solution**
```markdown
Check the error details and verify that the data structure is valid for JSON serialization.
```
### `DL-COMMON-502002`
**Message**
```markdown
Deserializing the specified json string failed. Details: %s
```
**Solution**
```markdown
Check the error details and verify that the JSON string is valid and well-formed.
```
### `DL-COMMON-502003`
**Message**
```markdown
The required fields are not specified.
```
**Solution**
```markdown
Provide all required fields in your request.
```
### `DL-COMMON-502004`
**Message**
```markdown
The metadata is not available since the asset has not been committed yet.
```
**Solution**
```markdown
Commit the asset before accessing its metadata.
```
### `DL-COMMON-502005`
**Message**
```markdown
The specified transaction state is invalid.
```
**Solution**
```markdown
Check the error details in the logs and verify the transaction state.
```
### `DL-COMMON-502006`
**Message**
```markdown
The contract type or instance is not supported.
```
**Solution**
```markdown
Check the error details in the logs and verify that the contract type is supported.
```
================================================
FILE: docs/scalardl-hashstore-command-reference.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL HashStore Command Reference
This page introduces `scalardl-hashstore`, which is a client command for interacting with ScalarDL HashStore.
## Overview of commands
- **Bootstrap HashStore**
- [`bootstrap`](#bootstrap): Bootstrap by registering identity and predefined contracts required to use HashStore.
- **Manage objects**
- [`get-object`](#get-object): Get an object from HashStore.
- [`put-object`](#put-object): Put an object to HashStore.
- [`compare-object-versions`](#compare-object-versions): Compare object versions.
- **Manage collections**
- [`create-collection`](#create-collection): Create a new collection.
- [`get-collection`](#get-collection): Get a collection from HashStore.
- [`add-to-collection`](#add-to-collection): Add objects to a collection.
- [`remove-from-collection`](#remove-from-collection): Remove objects from a collection.
- [`get-collection-history`](#get-collection-history): Get the history of a collection.
- **Validate the ledger**
- [`validate-ledger`](#validate-ledger): Validate a specified object or collection in HashStore.
## `bootstrap`
Bootstrap by registering identity and predefined contracts required to use HashStore.
### Options
| Option | Description |
|:---------------------------|:-------------------------------------------|
| `--config`, `--properties` | A configuration file in the .properties format. |
[Common utility options](#common-utility-options) are also available.
### Examples
```console
scalardl-hashstore bootstrap --properties client.properties
```
## `get-object`
Get an object from HashStore.
### Options
| Option | Description |
|:---------------------------|:-------------------------------------------|
| `--config`, `--properties` | A configuration file in the .properties format. |
| `--object-id` | The ID of the object to retrieve. |
[Common utility options](#common-utility-options) are also available.
### Examples
```console
scalardl-hashstore get-object --properties client.properties --object-id foo
```
## `put-object`
Put an object to HashStore.
### Options
| Option | Description |
|:---------------------------|:------------------------------------------------------------|
| `--config`, `--properties` | A configuration file in the .properties format. |
| `--object-id` | The ID of the object to store. |
| `--hash` | The hash value of the object. |
| `--metadata` | Optional metadata as a JSON string. |
| `--put-to-mutable` | Optional Put operation for a mutable database as a JSON string. |
[Common utility options](#common-utility-options) are also available.
### Examples
Put an object with a hash value.
```console
scalardl-hashstore put-object --properties client.properties --object-id foo --hash b97a42c87a46ffebe1439f8c1cd2f86e2f9b84dad89c8e9ebb257a19b6fdfe1c
```
Put an object with metadata.
```console
scalardl-hashstore put-object --properties client.properties --object-id foo --hash b97a42c87a46ffebe1439f8c1cd2f86e2f9b84dad89c8e9ebb257a19b6fdfe1c --metadata '{"note": "updated"}'
```
## `compare-object-versions`
Compare object versions.
### Options
| Option | Description |
|:---------------------------|:--------------------------------------------------------------|
| `--config`, `--properties` | A configuration file in the .properties format. |
| `--object-id` | The ID of the object to compare versions. |
| `--versions` | Object versions to compare as a JSON array. |
| `--all` | Compare all versions including stored versions in the ledger. |
| `--verbose` | Show detailed validation information. |
[Common utility options](#common-utility-options) are also available.
### Examples
Compare the latest versions specified in the arguments.
```console
scalardl-hashstore compare-object-versions --properties client.properties --object-id foo --versions '[{"version_id": "v1", "hash_value": "hash1"}, {"version_id": "v2", "hash_value": "hash2", "metadata": {"note": "updated"}}]'
```
Compare all versions stored in HashStore.
```console
scalardl-hashstore compare-object-versions --properties client.properties --object-id foo --versions '[{"version_id": "v1", "hash_value": "hash1"}, {"version_id": "v2", "hash_value": "hash2", "metadata": {"note": "updated"}}]' --all
```
Compare with the verbose output.
```console
scalardl-hashstore compare-object-versions --properties client.properties --object-id foo --versions '[{"version_id": "v1", "hash_value": "hash1"}]' --verbose
```
## `create-collection`
Create a new collection.
### Options
| Option | Description |
|:---------------------------|:-------------------------------------------|
| `--config`, `--properties` | A configuration file in the .properties format. |
| `--collection-id` | The ID of the collection to create. |
| `--object-ids` | Object IDs to include in the collection. |
[Common utility options](#common-utility-options) are also available.
### Examples
Create an empty collection.
```console
scalardl-hashstore create-collection --properties client.properties --collection-id audit_set
```
Create a collection with initial objects.
```console
scalardl-hashstore create-collection --properties client.properties --collection-id audit_set --object-ids object1 --object-ids object2
```
## `get-collection`
Get a collection from HashStore.
### Options
| Option | Description |
|:---------------------------|:-------------------------------------------|
| `--config`, `--properties` | A configuration file in the .properties format. |
| `--collection-id` | The ID of the collection to retrieve. |
[Common utility options](#common-utility-options) are also available.
### Examples
```console
scalardl-hashstore get-collection --properties client.properties --collection-id audit_set
```
## `add-to-collection`
Add objects to a collection.
### Options
| Option | Description |
|:---------------------------|:--------------------------------------------------------------------|
| `--config`, `--properties` | A configuration file in the .properties format. |
| `--collection-id` | The ID of the collection. |
| `--object-ids` | Object IDs to add to the collection. |
| `--force` | Skip validation for duplicate object IDs already in the collection. |
[Common utility options](#common-utility-options) are also available.
### Examples
Add objects to a collection.
```console
scalardl-hashstore add-to-collection --properties client.properties --collection-id audit_set --object-ids object3 --object-ids object4
```
Add an object with the force flag.
```console
scalardl-hashstore add-to-collection --properties client.properties --collection-id audit_set --object-ids object3 --force
```
## `remove-from-collection`
Remove objects from a collection.
### Options
| Option | Description |
|:---------------------------|:---------------------------------------------------------------|
| `--config`, `--properties` | A configuration file in the .properties format. |
| `--collection-id` | The ID of the collection. |
| `--object-ids` | Object IDs to remove from the collection. |
| `--force` | Skip validation for object IDs that are not in the collection. |
[Common utility options](#common-utility-options) are also available.
### Examples
Remove objects from a collection.
```console
scalardl-hashstore remove-from-collection --properties client.properties --collection-id audit_set --object-ids object1 --object-ids object2
```
Remove an object with the force flag.
```console
scalardl-hashstore remove-from-collection --properties client.properties --collection-id audit_set --object-ids object1 --force
```
## `get-collection-history`
Get the history of a collection.
### Options
| Option | Description |
|:---------------------------|:----------------------------------------------------|
| `--config`, `--properties` | A configuration file in the .properties format. |
| `--collection-id` | The ID of the collection. |
| `--limit` | Maximum number of recent history entries to return. |
[Common utility options](#common-utility-options) are also available.
### Examples
Get all histories of a collection.
```console
scalardl-hashstore get-collection-history --properties client.properties --collection-id audit_set
```
Get the limited history of a collection.
```console
scalardl-hashstore get-collection-history --properties client.properties --collection-id audit_set --limit 10
```
## `validate-ledger`
Validate a specified object or collection in HashStore.
### Options
| Option | Description |
|:---------------------------|:-------------------------------------------|
| `--config`, `--properties` | A configuration file in the .properties format. |
| `--object-id` | The ID of the object to validate. |
| `--collection-id` | The ID of the collection to validate. |
| `--start-age` | The start age for validation range. |
| `--end-age` | The end age for validation range. |
[Common utility options](#common-utility-options) are also available.
### Examples
Validate an object for all ages.
```console
scalardl-hashstore validate-ledger --properties client.properties --object-id foo
```
Validate an object from age 0 to age 10 only.
```console
scalardl-hashstore validate-ledger --properties client.properties --object-id foo --start-age 0 --end-age 10
```
Validate a collection for all ages.
```console
scalardl-hashstore validate-ledger --properties client.properties --collection-id audit_set
```
Validate a collection from age 0 to age 5 only.
```console
scalardl-hashstore validate-ledger --properties client.properties --collection-id audit_set --start-age 0 --end-age 5
```
## Common utility options
You can use the following options in all the commands above.
| Option | Description |
|:----------------------|:--------------------------------------------|
| `-g`, `--use-gateway` | A flag to use the gateway. |
| `-h`, `--help` | Display the help message of a command. |
| `--stacktrace` | Output the Java stack trace to the `stderr` stream. |
================================================
FILE: docs/scalardl-hashstore-status-codes.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL HashStore Error Codes
This page provides a list of error codes in ScalarDL HashStore.
## Error code classes and descriptions
| Class | Description |
|:----------------------|:-----------------------------------|
| `DL-HASH-STORE-4xxxx` | Errors for the user error category |
## `DL-HASH-STORE-4xxxx` status codes
The following are status codes and messages for the user error category.
### `DL-HASH-STORE-414001`
**Message**
```markdown
The PUT operation for the mutable database must have a namespace and table.
```
**Solution**
```markdown
Provide both a namespace and table name for the PUT operation.
```
### `DL-HASH-STORE-414002`
**Message**
```markdown
An unsupported data type is specified in the PUT operation. Data type: %s
```
**Solution**
```markdown
Use a supported data type for the PUT operation. Check the documentation for valid data types.
```
================================================
FILE: docs/scalardl-ledger-status-codes.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL Ledger Error Codes
This page provides a list of error codes in ScalarDL Ledger.
## Error code classes and descriptions
| Class | Description |
|:------------------|:-----------------------------------------|
| `DL-LEDGER-3xxxx` | Errors for the validation error category |
| `DL-LEDGER-4xxxx` | Errors for the user error category |
| `DL-LEDGER-5xxxx` | Errors for the internal error category |
## `DL-LEDGER-3xxxx` status codes
The following are status codes and messages for the validation error category.
### `DL-LEDGER-300001`
**Message**
```markdown
Validation failed for the hash.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-LEDGER-301001`
**Message**
```markdown
Validation failed for the previous hash.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-LEDGER-302001`
**Message**
```markdown
Validation failed for the contract.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-LEDGER-303001`
**Message**
```markdown
Validation failed for the output. Recomputed: %s; Stored: %s
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-LEDGER-304001`
**Message**
```markdown
Validation failed for nonce. %s contains the nonce '%s' more than once.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-LEDGER-305001`
**Message**
```markdown
The specified asset and the asset metadata are inconsistent.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
### `DL-LEDGER-305002`
**Message**
```markdown
The asset specified by input dependencies is not found.
```
**Solution**
```markdown
Data or program tampering, or a software bug, may have occurred. Contact your system administrator to check for any signs of malicious activity.
```
## `DL-LEDGER-4xxxx` status codes
The following are status codes and messages for the user error category.
### `DL-LEDGER-400001`
**Message**
```markdown
The request signature can't be validated.
```
**Solution**
```markdown
Verify that the certificate used to sign the request is registered and valid.
```
### `DL-LEDGER-400002`
**Message**
```markdown
The request signature from Auditor can't be validated.
```
**Solution**
```markdown
Verify that the certificate used by Auditor is registered and valid.
```
### `DL-LEDGER-407001`
**Message**
```markdown
The specified contract class is not allowed to be executed.
```
**Solution**
```markdown
Verify the contract binary name and ensure it is listed in the configuration file specified by scalar.dl.ledger.executable_contracts.
```
### `DL-LEDGER-407002`
**Message**
```markdown
A configuration mismatch is detected. Check the Auditor setting in the client or Ledger.
```
**Solution**
```markdown
Verify that the Auditor settings in the client and Ledger configurations are consistent.
```
### `DL-LEDGER-407003`
**Message**
```markdown
The Auditor signature must be included in the request when Auditor is enabled.
```
**Solution**
```markdown
Verify that the Auditor settings in the client and Ledger configurations are consistent.
```
### `DL-LEDGER-407004`
**Message**
```markdown
%s must be enabled to make auditing work.
```
**Solution**
```markdown
Verify that the Auditor settings in the client and Ledger configurations are consistent.
```
### `DL-LEDGER-407005`
**Message**
```markdown
Registering a function via a non-privileged port is not allowed. Use a privileged port or enable %s.
```
**Solution**
```markdown
Use a privileged port for function registration, or enable the appropriate configuration property to allow function registration from non-privileged ports.
```
### `DL-LEDGER-407006`
**Message**
```markdown
Overwriting an existing function is not allowed. Enable %s to allow overwriting.
```
**Solution**
```markdown
Enable the function overwrite configuration property to allow overwriting existing functions.
```
### `DL-LEDGER-409001`
**Message**
```markdown
The specified asset is not found.
```
**Solution**
```markdown
Verify the asset ID and namespace are correct and the asset has been created.
```
### `DL-LEDGER-410001`
**Message**
```markdown
The specified function is not found.
```
**Solution**
```markdown
Register the function first before executing it.
```
### `DL-LEDGER-411001`
**Message**
```markdown
Loading the function failed. Details: %s
```
**Solution**
```markdown
Check the error details and verify that the function class is valid and accessible.
```
### `DL-LEDGER-412001`
**Message**
```markdown
The function is not allowed to access the specified namespace.
```
**Solution**
```markdown
Functions cannot access system namespaces or namespaces with reserved prefixes. Disallowed namespaces: system, system_schema, system_auth, system_distributed, system_traces, coordinator. Disallowed namespace prefixes: scalar, auditor. Use a different namespace for your function operations.
```
### `DL-LEDGER-412002`
**Message**
```markdown
The database operation in the function failed. Details: %s
```
**Solution**
```markdown
Verify that the arguments passed to the database operation are valid and correct.
```
### `DL-LEDGER-414001`
**Message**
```markdown
%s must be set if HMAC authentication is used.
```
**Solution**
```markdown
Set the cipher key configuration property for HMAC authentication.
```
### `DL-LEDGER-414002`
**Message**
```markdown
%s must be set to true if Auditor is enabled.
```
**Solution**
```markdown
Set the proof configuration property to true when Auditor is enabled.
```
### `DL-LEDGER-414003`
**Message**
```markdown
Authentication between Ledger and Auditor is not correctly configured. Set a private key with %s or %s if you use digital signature authentication with Auditor enabled.
```
**Solution**
```markdown
Set the private key configuration property for digital signature authentication between Ledger and Auditor.
```
### `DL-LEDGER-414004`
**Message**
```markdown
Authentication between Ledger and Auditor is not correctly configured. Set %s if you use HMAC authentication with Auditor enabled.
```
**Solution**
```markdown
Set the required configuration property for HMAC authentication between Ledger and Auditor.
```
### `DL-LEDGER-414005`
**Message**
```markdown
Either %s or %s must be set if proof is enabled.
```
**Solution**
```markdown
Set either the private key PEM or path configuration property when proof is enabled.
```
### `DL-LEDGER-414006`
**Message**
```markdown
%s must be set to true when using the JDBC transaction manager in the Auditor mode.
```
**Solution**
```markdown
Set the transaction state management configuration property to true when using JDBC transaction manager in Auditor mode.
```
### `DL-LEDGER-414007`
**Message**
```markdown
%s must be disabled when using the Consensus Commit transaction manager for performance reasons.
```
**Solution**
```markdown
Set the transaction state management configuration property to false when using Consensus Commit transaction manager.
```
### `DL-LEDGER-414008`
**Message**
```markdown
%s must be disabled because group commit is not supported.
```
**Solution**
```markdown
Set the group commit configuration property to false as it is not supported.
```
## `DL-LEDGER-5xxxx` status codes
The following are status codes and messages for the internal error category.
### `DL-LEDGER-500001`
**Message**
```markdown
Binding the function failed. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify your database configuration and connection.
```
### `DL-LEDGER-500002`
**Message**
```markdown
Unbinding the function failed. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify your database configuration and connection.
```
### `DL-LEDGER-500003`
**Message**
```markdown
Getting the function failed. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify your database configuration and connection.
```
### `DL-LEDGER-500004`
**Message**
```markdown
Starting a transaction failed. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify your database configuration and connection.
```
### `DL-LEDGER-500005`
**Message**
```markdown
Getting the transaction state failed. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify your database configuration and connection.
```
### `DL-LEDGER-500006`
**Message**
```markdown
Putting or committing asset records failed. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify your database configuration and connection.
```
### `DL-LEDGER-500007`
**Message**
```markdown
Aborting the transaction failed. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify your database configuration and connection.
```
### `DL-LEDGER-500008`
**Message**
```markdown
Retrieving the asset records failed. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify your database configuration and connection.
```
### `DL-LEDGER-500009`
**Message**
```markdown
Retrieving the asset metadata failed. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify your database configuration and connection.
```
### `DL-LEDGER-500010`
**Message**
```markdown
Putting the asset metadata failed. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify your database configuration and connection.
```
### `DL-LEDGER-500011`
**Message**
```markdown
The database operation in the function failed due to a database error. Details: %s
```
**Solution**
```markdown
Check the error details in the logs and verify your database configuration and connection.
```
### `DL-LEDGER-501001`
**Message**
```markdown
The asset status is unknown. Details: %s
```
**Solution**
```markdown
Check the asset status manually and review the error details in the logs.
```
### `DL-LEDGER-502001`
**Message**
```markdown
The function type or instance is not supported.
```
**Solution**
```markdown
Check the error details in the logs and verify that the function type is supported.
```
### `DL-LEDGER-504001`
**Message**
```markdown
The transaction state has already been %s.
```
**Solution**
```markdown
Retry the operation.
```
### `DL-LEDGER-504002`
**Message**
```markdown
Retrieving the asset records failed due to a conflict. Details: %s
```
**Solution**
```markdown
Retry the operation.
```
### `DL-LEDGER-504003`
**Message**
```markdown
Putting the asset records failed due to a conflict. Details: %s
```
**Solution**
```markdown
Retry the operation.
```
### `DL-LEDGER-504004`
**Message**
```markdown
Committing the asset records failed due to a conflict. Details: %s
```
**Solution**
```markdown
Retry the operation.
```
### `DL-LEDGER-504005`
**Message**
```markdown
Retrieving the asset metadata failed due to a conflict. Details: %s
```
**Solution**
```markdown
Retry the operation.
```
### `DL-LEDGER-504006`
**Message**
```markdown
Putting the asset metadata failed due to a conflict. Details: %s
```
**Solution**
```markdown
Retry the operation.
```
### `DL-LEDGER-504007`
**Message**
```markdown
The database operation in the function failed due to a conflict. Details: %s
```
**Solution**
```markdown
Retry the operation.
```
================================================
FILE: docs/scalardl-tablestore-command-reference.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL TableStore Command Reference
This page introduces `scalardl-tablestore`, which is a client command for interacting with ScalarDL TableStore.
## Overview of commands
- **Bootstrap TableStore**
- [`bootstrap`](#bootstrap): Bootstrap by registering identity and predefined contracts required to use TableStore.
- **Execute a statement**
- [`execute-statement`](#execute-statement): Execute a specified statement.
- **Validate the ledger**
- [`validate-ledger`](#validate-ledger): Validate a specified record, index record, or table schema in TableStore.
## `bootstrap`
Bootstrap by registering identity and predefined contracts required to use TableStore.
### Options
| Option | Description |
|:---------------------------|:-------------------------------------------|
| `--config`, `--properties` | A configuration file in the .properties format. |
[Common utility options](#common-utility-options) are also available.
### Examples
```console
scalardl-tablestore bootstrap --properties client.properties
```
## `execute-statement`
Execute a specified statement.
### Options
| Option | Description |
|:---------------------------|:-------------------------------------------|
| `--config`, `--properties` | A configuration file in the .properties format. |
| `--statement` | A statement to interact with TableStore. |
[Common utility options](#common-utility-options) are also available.
### Examples
Execute a statement.
```console
scalardl-tablestore execute-statement --properties client.properties --statement "SELECT * FROM employee WHERE id = '1001'"
```
For details about the grammar of SQL statements, see [ScalarDL TableStore SQL Grammar](sql-grammar.mdx).
## `validate-ledger`
Validate a specified record, index record or table schema in TableStore.
### Options
| Option | Description |
|:--------------------------------|:-----------------------------------------------------------------------|
| `--config`, `--properties` | A configuration file in the .properties format. |
| `--table-name` | The name of the table. |
| `--primary-key-column-name` | The primary key column name of the record. |
| `--index-key-column-name` | The index key column name of the record. |
| `--column-value` | The column value of the primary key or the index key as a JSON string. |
| `--start-age` | The start age for the validation range. |
| `--end-age` | The end age for the validation range. |
[Common utility options](#common-utility-options) are also available.
### Examples
Validate a record with primary key for all ages.
```console
scalardl-tablestore validate-ledger --properties client.properties --table-name employee --primary-key-column-name id --column-value '"1001"'
```
Validate a record with primary key from age 0 to age 10 only.
```console
scalardl-tablestore validate-ledger --properties client.properties --table-name employee --primary-key-column-name id --column-value '"1001"' --start-age 0 --end-age 10
```
Validate an index record.
```console
scalardl-tablestore validate-ledger --properties client.properties --table-name employee --index-key-column-name department --column-value '"sales"'
```
Validate a table schema.
```console
scalardl-tablestore validate-ledger --properties client.properties --table-name employee
```
## Common utility options
You can use the following options in all the commands above.
| Option | Description |
|:----------------------|:--------------------------------------------|
| `-g`, `--use-gateway` | A flag to use the gateway. |
| `-h`, `--help` | Display the help message of a command. |
| `--stacktrace` | Output the Java stack trace to the `stderr` stream. |
================================================
FILE: docs/scalardl-tablestore-status-codes.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL TableStore Error Codes
This page provides a list of error codes in ScalarDL TableStore.
## Error code classes and descriptions
| Class | Description |
|:-----------------------|:-----------------------------------|
| `DL-TABLE-STORE-4xxxx` | Errors for the user error category |
## `DL-TABLE-STORE-4xxxx` status codes
The following are status codes and messages for the user error category.
### `DL-TABLE-STORE-414001`
**Message**
```markdown
Syntax error. Line=%d, Offset=%d, Length=%d, Code=%s
```
**Solution**
```markdown
Fix the syntax error at the specified location in your query.
```
### `DL-TABLE-STORE-414002`
**Message**
```markdown
Syntax error. The primary key column must be specified only once in a table.
```
**Solution**
```markdown
Fix the primary key specification to specify each primary key column only once.
```
### `DL-TABLE-STORE-414003`
**Message**
```markdown
Syntax error. The specified column constraint is invalid.
```
**Solution**
```markdown
Fix the column constraints to use valid syntax.
```
### `DL-TABLE-STORE-414004`
**Message**
```markdown
Syntax error. The specified data type is invalid.
```
**Solution**
```markdown
Fix the data type to use a valid type.
```
### `DL-TABLE-STORE-414005`
**Message**
```markdown
Syntax error. The specified INSERT statement is invalid.
```
**Solution**
```markdown
Fix the syntax error in the INSERT statement.
```
### `DL-TABLE-STORE-414006`
**Message**
```markdown
Syntax error. The specified statement is invalid.
```
**Solution**
```markdown
Fix the syntax error in the statement.
```
### `DL-TABLE-STORE-414007`
**Message**
```markdown
Syntax error. The specified expression is invalid. Expression: %s
```
**Solution**
```markdown
Fix the syntax error in the expression.
```
### `DL-TABLE-STORE-414008`
**Message**
```markdown
Syntax error. The specified literal is invalid. Literal: %s
```
**Solution**
```markdown
Fix the syntax error in the literal.
```
### `DL-TABLE-STORE-414009`
**Message**
```markdown
Syntax error. The specified format of the update target column is invalid.
```
**Solution**
```markdown
Fix the update target column format to use valid syntax.
```
### `DL-TABLE-STORE-414010`
**Message**
```markdown
Syntax error. The specified table is invalid. Table: %s
```
**Solution**
```markdown
Fix the syntax error in the table specification.
```
### `DL-TABLE-STORE-414011`
**Message**
```markdown
Syntax error. The specified column is invalid. Column: %s
```
**Solution**
```markdown
Fix the syntax error in the column specification.
```
### `DL-TABLE-STORE-414012`
**Message**
```markdown
Syntax error. The specified condition is invalid. Condition: %s
```
**Solution**
```markdown
Fix the syntax error in the condition.
```
### `DL-TABLE-STORE-414013`
**Message**
```markdown
Syntax error. The specified JOIN condition is invalid. Condition: %s
```
**Solution**
```markdown
Fix the syntax error in the JOIN condition.
```
### `DL-TABLE-STORE-414014`
**Message**
```markdown
Syntax error. The specified JOIN type is invalid.
```
**Solution**
```markdown
Fix the syntax error in the JOIN type.
```
### `DL-TABLE-STORE-414015`
**Message**
```markdown
Syntax error. The specified projection is invalid. Projection: %s
```
**Solution**
```markdown
Fix the syntax error in the projection.
```
### `DL-TABLE-STORE-414016`
**Message**
```markdown
Syntax error. The specified LIMIT clause is invalid.
```
**Solution**
```markdown
Fix the syntax error in the LIMIT clause.
```
### `DL-TABLE-STORE-414017`
**Message**
```markdown
Syntax error. The specified SELECT statement is invalid.
```
**Solution**
```markdown
Fix the syntax error in the SELECT statement.
```
### `DL-TABLE-STORE-414018`
**Message**
```markdown
Syntax error. The specified WITH clause is not supported.
```
**Solution**
```markdown
Remove the WITH clause from your query as it is not supported.
```
### `DL-TABLE-STORE-414019`
**Message**
```markdown
Syntax error. The specified ORDER BY clause is not supported.
```
**Solution**
```markdown
Remove the ORDER BY clause from your query as it is not supported.
```
### `DL-TABLE-STORE-414020`
**Message**
```markdown
Syntax error. The specified OFFSET clause is not supported.
```
**Solution**
```markdown
Remove the OFFSET clause from your query as it is not supported.
```
### `DL-TABLE-STORE-414021`
**Message**
```markdown
Syntax error. The specified LET clause is not supported.
```
**Solution**
```markdown
Remove the LET clause from your query as it is not supported.
```
### `DL-TABLE-STORE-414022`
**Message**
```markdown
Syntax error. The specified EXCLUDE clause is not supported.
```
**Solution**
```markdown
Remove the EXCLUDE clause from your query as it is not supported.
```
### `DL-TABLE-STORE-414023`
**Message**
```markdown
Syntax error. The specified GROUP BY clause is not supported.
```
**Solution**
```markdown
Remove the GROUP BY clause from your query as it is not supported.
```
### `DL-TABLE-STORE-414024`
**Message**
```markdown
Syntax error. The specified HAVING clause is not supported.
```
**Solution**
```markdown
Remove the HAVING clause from your query as it is not supported.
```
### `DL-TABLE-STORE-414025`
**Message**
```markdown
Syntax error. The cross join and implicit join using comma-separated tables are not supported. Use a JOIN clause instead.
```
**Solution**
```markdown
Use a JOIN clause instead of cross join or comma-separated tables.
```
### `DL-TABLE-STORE-414026`
**Message**
```markdown
Syntax error. The specified set quantifier is not supported.
```
**Solution**
```markdown
Remove the set quantifier from your query as it is not supported.
```
### `DL-TABLE-STORE-414027`
**Message**
```markdown
The LIMIT clause is not supported except in the history query.
```
**Solution**
```markdown
Remove the LIMIT clause from your query or use it only in history queries.
```
### `DL-TABLE-STORE-414028`
**Message**
```markdown
The table alias is not supported in the information schema and history query.
```
**Solution**
```markdown
Remove the table alias from your information schema or history query.
```
### `DL-TABLE-STORE-414029`
**Message**
```markdown
Projection is not supported for the information schema query. Specify '*' instead.
```
**Solution**
```markdown
Use '*' instead of specific column projections in your information schema query.
```
### `DL-TABLE-STORE-414030`
**Message**
```markdown
The specified condition for the information schema query is invalid.
```
**Solution**
```markdown
Fix the condition in your information schema query to use valid syntax and supported operators.
```
### `DL-TABLE-STORE-414031`
**Message**
```markdown
Multiple statements are not supported.
```
**Solution**
```markdown
Execute one statement at a time instead of multiple statements in a single request.
```
================================================
FILE: docs/schema-loader.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL Schema Loader
A Docker image that loads the database schemas of ScalarDL using [Schema Tool for ScalarDB](https://scalardb.scalar-labs.com/docs/latest/schema-loader).
## How to Run
### For Cosmos DB
```console
docker run --rm [--env SCHEMA_TYPE=auditor] ghcr.io/scalar-labs/scalardl-schema-loader: \
--cosmos -h -p [-r BASE_RESOURCE_UNIT]
```
### For DynamoDB
```console
docker run --rm [--env SCHEMA_TYPE=auditor] ghcr.io/scalar-labs/scalardl-schema-loader: \
--dynamo --region -u -p [-r BASE_RESOURCE_UNIT]
```
### For Cassandra
```console
docker run --rm [--env SCHEMA_TYPE=auditor] ghcr.io/scalar-labs/scalardl-schema-loader: \
--cassandra -h -u -p [-n -R ]
```
### For using a config file
* For Ledger
```console
docker run --rm \
-v :/scalardl-schema-loader/database.properties \
ghcr.io/scalar-labs/scalardl-schema-loader: \
--config database.properties --coordinator [ [, ...]]
```
* For Auditor
```console
docker run --rm --env SCHEMA_TYPE=auditor \
-v :/scalardl-schema-loader/database.properties \
ghcr.io/scalar-labs/scalardl-schema-loader: \
--config database.properties [ [, ...]]
```
================================================
FILE: docs/sql-grammar.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# ScalarDL TableStore SQL Grammar
This page provides a list of commands supported in ScalarDL TableStore SQL.
:::note
ScalarDL TableStore SQL is a [PartiQL-based](https://partiql.org/) language and is not fully compatible with standard SQL.
:::
- DDL
- [CREATE TABLE](#create-table)
- DML
- [SELECT](#select)
- [INSERT](#insert)
- [UPDATE](#update)
- Others
- [Show tables](#show-tables)
- [Show record histories](#show-record-histories)
- Literal
- [String](#string)
- [Number](#number)
- [Boolean](#boolean)
## DDL
Data Definition Language (DDL) commands are used to define and modify the structure of database objects such as tables.
### CREATE TABLE
The `CREATE TABLE` command creates a table.
#### Grammar
```sql
CREATE TABLE (
data_type PRIMARY KEY [, data_type,] ...
)
data_type: BOOLEAN | INT | BIGINT | FLOAT | DOUBLE PRECISION | STRING
```
#### Notes
- You don't have to specify a strict schema when creating a table, but you must specify a primary key column at least.
- You can create secondary indexes by specifying index key columns.
- ScalarDL TableStore handles all numeric data types (`INT`, `BIGINT`, `FLOAT`, and `DOUBLE PRECISION`) as the `NUMBER` data type in the JSON format without distinguishing them.
#### Examples
An example of `CREATE TABLE` is as follows:
```sql
-- Create a table with a primary key ("c1") and index keys ("c2", "c3", and "c4").
CREATE TABLE tbl (
c1 INT PRIMARY KEY,
c2 STRING,
c3 FLOAT,
c4 BIGINT
);
```
## DML
Data Manipulation Language (DML) commands are used to query and modify data in tables.
### SELECT
The `SELECT` command retrieves records in tables managed by TableStore.
#### Grammar
```sql
SELECT projection [, projection] ...
FROM [AS ] [join_specification [join_specification] ...]
WHERE predicate [AND predicate ...]
projection: * | identifier
join_specification: JOIN [AS ] ON join_predicate
join_predicate: identifier = identifier
predicate: identifier operator | identifier IS [NOT] NULL
identifier: [.] | [alias.]
operator: = | <> | != | > | >= | < | <=
```
##### Notes
- For the `SELECT` clause, you can specify top-level fields in the JSON record object as projection columns.
- For the `JOIN` clause, the `join_predicate`s must include either a primary-key column or index-key column from the right table.
- For the `WHERE` clause, you can specify predicates for any columns, but you must include at least one predicate for a primary key column or index key column with the equality condition or `IS NULL` condition.
#### Examples
If you have the following table with the primary and index keys, for example:
```sql
CREATE TABLE tbl (
c1 INT PRIMARY KEY,
c2 STRING,
c3 FLOAT,
c4 BIGINT
);
```
Examples of `SELECT` are as follows:
```sql
-- With a primary key
SELECT * FROM tbl WHERE c1 = 10;
-- With a primary key and predicates for non-primary-key columns
SELECT * FROM tbl WHERE c1 = 10 AND c2 = 'aaa' AND c3 = 1.23 AND c4 < 100;
-- With projections and a primary key
SELECT c1, c2, c3, c5 FROM tbl WHERE c1 = 10;
-- With an equality predicate for an indexed column
SELECT * FROM tbl WHERE c4 = 100;
-- With an equality predicate for an indexed column and predicates for non-key columns
SELECT * FROM tbl WHERE c4 = 100 AND c5 = false;
-- With IS NULL predicates
SELECT * FROM tbl WHERE c2 IS NULL AND c3 IS NOT NULL;
-- With JOIN clause
SELECT * FROM tbl1 as t1 JOIN tbl2 as t2 on t1.c2=t2.id WHERE t1.c1=1;
```
### INSERT
The `INSERT` command inserts a new record into the specified table. If the target record already exists, an exception will be thrown. In ScalarDL TableStore, a record is represented by a JSON object. You can also specify the JSON object by using the PartiQL struct format.
#### Grammar
```sql
INSERT INTO VALUES record_specification
record_specification: `` |
```
##### Notes
You must include a primary key column in the record to be inserted.
#### Examples
Examples of `INSERT` are as follows:
```sql
-- Insert a record using the JSON format
INSERT INTO tbl VALUES `{"c1": 10, "c2": "aaa", "c3": 1.23, "c4": 100, "c5": true}`;
-- Insert a record using the PartiQL struct format
INSERT INTO tbl VALUES {'c1': 10, 'c2': 'aaa', 'c3': 1.23, 'c4': 100, 'c5': true};
```
### UPDATE
The `UPDATE` command updates existing records in the specified table. You can specify conditions in the `WHERE` clause to filter records, the same as the `SELECT` command. Still, you must include at least one predicate for a primary key column or index key column with the equality condition or `IS NULL` condition.
#### Grammar
```sql
UPDATE
SET = [, = ] ...
WHERE predicate [AND predicate ...]
predicate: operator | IS [NOT] NULL
operator: = | <> | != | > | >= | < | <=
```
##### Notes
- For the `SET` clause, if the specified column does not exist in the records, then it is newly added in the JSON object of the records.
- For the `WHERE` clause, you can specify predicates for any columns, but you must include at least one predicate for a primary key column or index key column with the equality condition or `IS NULL` condition.
#### Examples
If you have the following table, for example:
```sql
CREATE TABLE tbl (
c1 INT PRIMARY KEY,
c2 STRING,
c3 FLOAT,
c4 BIGINT
);
```
Examples of `UPDATE` with the full primary key specified are as follows:
```sql
-- Update a record with a primary key predicate
UPDATE tbl SET c4 = 200, c5 = false WHERE c1 = 10;
-- Update a record with an index key predicate
UPDATE tbl SET c4 = 200, c5 = false WHERE c2 = 'aaa';
-- Update a record with a primary key and a non-key predicate
UPDATE tbl SET c4 = 200, c5 = false WHERE c1 = 10 AND c5 = true;
```
## Others
This section covers additional commands and functions that extend beyond the standard DDL and DML categories.
### Show tables
You can show tables managed by TableStore by querying the `information_schema.tables` table.
#### Grammar
```sql
SELECT *
FROM information_schema.tables
[WHERE table_name = ]
```
#### Examples
Examples of querying the `information_schema.tables` table are as follows:
```sql
-- Show all tables in tables managed by TableStore.
SELECT * FROM information_schema.tables;
-- Show only the specified table
SELECT * FROM information_schema.tables WHERE table_name = 'tbl';
```
### Show record histories
You can show a history of the specified record by using the `history()` function.
#### Grammar
```sql
SELECT history()
FROM
WHERE predicate
[LIMIT ]
predicate: =
```
#### Notes
- You must specify a primary key in the `WHERE` clause.
- The command returns the records sorted from latest to oldest.
- With the `LIMIT` clause, the command returns the most recent `` rows sorted from latest to oldest.
#### Examples
Examples of showing a history of the specified record are as follows:
```sql
-- Show a history of the specified record
SELECT history() FROM tbl WHERE c1 = 10;
-- Show a history of the specified record with limit
SELECT history() FROM tbl WHERE c1 = 10 LIMIT 10;
```
## Literal
Literal refers to a fixed data value used when writing SQL statements. For example, `1`, `'abc'`, `1.23`, and `true` are literals.
### String
A string literal is a sequence of characters enclosed in single quotes `'`, such as `'abc'` and `'abc def'`.
### Number
Number literals include exact-value (`INTEGER` and `BIGINT`) and approximate-value (`FLOAT` and `DOUBLE PRECISION`) literals:
- An exact-value literal is a sequence of digits, such as `123` and `-5`.
- An approximate-value literal is a sequence of digits with a decimal point, such as `4.754` and `-1.2`.
### Boolean
Boolean literals are either `true` or `false` to represent boolean values.
================================================
FILE: docs/use-generic-contracts.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# Use Generic Contracts and Functions
import JDKVersions from '/src/components/en-us/_prerequisites-jdk-versions.mdx';
:::tip
Although generic contracts were introduced in ScalarDL 3.10, HashStore, released in ScalarDL 3.12, provides a higher-level abstraction that wraps generic contracts. For most use cases, using HashStore is simpler and more efficient than using generic contracts directly. For details, see [Get Started with ScalarDL HashStore](./getting-started-hashstore.mdx) in the latest version of ScalarDL.
:::
This guide explains how to use generic contracts and functions in ScalarDL.
Generic contracts and functions are predefined contracts and functions for common use cases. Currently, ScalarDL provides two functionalities: object authenticity management and collection authenticity management. You can immutably put and validate hash values of objects and manage a collection of the objects. By using generic contracts and functions, for example, you can easily develop an authenticity management application for file services or audit logging systems, without writing your own contracts and functions.
## Background
A contract in ScalarDL is a digitally signed Java-based business logic that reads and writes the asset records of a ledger database. A function in ScalarDL is also a Java-based business logic that interacts with ScalarDB and is executed with a contract in a single transaction.
You can develop various applications for your own purposes by writing contracts and functions. However, because the ScalarDL data model and interface are a little different from traditional relational database systems, writing those contracts and functions may be difficult. Therefore, ScalarDL provides predefined contracts and functions for common use cases as generic contracts and functions so that developers can focus on the application side, like the user interface.
## Use cases
Managing the authenticity of data can be categorized in two ways: managing the authenticity of objects and managing the authenticity of the collection of objects. ScalarDL generic contracts and functions support both of these so that you can easily develop authenticity management applications.
For object authenticity management, you can manage the authenticity of any kind of your objects, like files, audit logs, and even directories in your file or object storage.
For collection authenticity management, you can manage which objects exist in a collection. For example, you can create a collection of objects that need to be validated in an auditing process.
For how those functionalities are achieved by using generic contracts and functions, see the examples in [Manage object authenticity](#manage-object-authenticity) and [Manage collection authenticity](#manage-collection-authenticity) below.
## Set up an environment
In this section, you'll try using generic contracts and functions through the ScalarDL client tools to verify the authenticity of your local files. If you want to interact with generic contracts and functions in your applications, you can use the ScalarDL Client SDK APIs. For details, see [Write a ScalarDL Application with Generic Contracts](how-to-write-applications-with-generic-contracts.mdx).
### Install a JDK
In this guide, you'll only use a Java runtime environment for seeing how generic contracts and functions work. However, it is recommended that you install one of the following Java Development Kits (JDKs), which will be required to build your own ScalarDL application outside of this guide.
### Set up a ScalarDL environment
Set up a ScalarDL environment that meets your own requirements. If you want to deploy ScalarDL in a local test environment, you can deploy such an environment by using a sample Docker Compose configuration and Scalar Helm Chart. For details, see the following:
- [Getting Started with ScalarDL Ledger](getting-started.mdx)
- [Getting Started with Scalar Helm Charts](helm-charts/getting-started-scalar-helm-charts.mdx)
For a production environment, ScalarDL is available as container images. For details, see [How to get the container images of Scalar products](scalar-kubernetes/HowToGetContainerImages.mdx).
:::note
Generic contracts and functions are supported in ScalarDL version 3.10 or later versions.
:::
### Download the necessary tools and the generic contracts
Specify a version that is equal to or greater than 3.10.1 by running the following command. For available versions, see [Tags](https://github.com/scalar-labs/scalardl/tags).
```console
VERSION=X.Y.Z
```
Then, download the tools and the generic contracts by running the following commands:
```console
curl -OL https://github.com/scalar-labs/scalardl/releases/download/v$VERSION/scalardl-java-client-sdk-$VERSION.zip
unzip scalardl-java-client-sdk-$VERSION.zip
mv scalardl-java-client-sdk-$VERSION client
curl -OL https://github.com/scalar-labs/scalardl/releases/download/v$VERSION/scalardl-generic-contracts-$VERSION.zip
unzip scalardl-generic-contracts-$VERSION.zip
mv scalardl-generic-contracts-$VERSION generic-contracts
```
## Register a certificate and the generic contracts
This section describes how to register a certificate and the generic contracts.
### Configure the properties
To interact with the ScalarDL components, you need to configure the client properties. For details, see [Configure properties](getting-started.mdx#configure-properties).
### Register a certificate or secret
Prepare a certificate for registration. For details, see [How to get a certificate](ca/caclient-getting-started.mdx).
Then, register your certificate by using the ScalarDL client CLI as follows:
```console
client/bin/scalardl generic-contracts register-cert --properties client.properties
```
:::note
You can also use HMAC authentication instead of using a certificate. For details about HMAC authentication, see [ScalarDL Authentication Guide](authentication.mdx).
:::
### Register the generic contracts and functions
After registering the certificate, you can register the generic contracts and functions by running the following commands:
```console
client/bin/scalardl generic-contracts register-contracts --properties client.properties --contracts-file generic-contracts/conf/object-authenticity-management-contracts.toml
client/bin/scalardl generic-contracts register-functions --properties client.properties --functions-file generic-contracts/conf/object-authenticity-management-functions.toml
```
## Manage object authenticity
For object authenticity management, you can put a hash value of an object by using the [`object.Put` contract](generic-contracts-reference.mdx#objectput-contract). Specify the target object ID and the hash value of the object like in the following example. The object ID must be a unique ID that identifies your objects or files, for example, a key of an object or a file path. You can also put any metadata associated with the object by using the `metadata` option.
First, get the hash value of a file and put it into the tamper-evident ledger.
:::note
The `sha256sum` command is for Linux environments only. `shasum` and `certutil` are available for Mac and Windows environments, respectively. For details on getting the same SHA256 hash values, see the usage of those commands.
:::
```console
echo "Alice created this file." > a.txt
sha256sum a.txt
```
You should get the following hash value:
```console
5c7440fb2273a247f78aadefbc511c680a84e7d44004abfaedef2b145151dab0 a.txt
```
You can put the hash value by running the following command:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id object.Put \
--contract-argument '{"object_id": "a.txt", "hash_value": "5c7440fb2273a247f78aadefbc511c680a84e7d44004abfaedef2b145151dab0", "metadata": {"note": "created"}}'
```
For input and output specifications for generic contracts and functions, see the [Generic Contracts and Functions Reference Guide](generic-contracts-reference.mdx).
If the object is updated, you can put the new hash value by using the same contract. For example, the following assumes that the command below was executed:
```console
echo "Alice updated this file." >> a.txt
sha256sum a.txt
```
You should get the following result as the hash value:
```console
b97a42c87a46ffebe1439f8c1cd2f86e2f9b84dad89c8e9ebb257a19b6fdfe1c a.txt
```
You can then update the hash value as follows:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id object.Put \
--contract-argument '{"object_id": "a.txt", "hash_value": "b97a42c87a46ffebe1439f8c1cd2f86e2f9b84dad89c8e9ebb257a19b6fdfe1c", "metadata": {"note": "updated"}}'
```
You can also get the latest status of the object with the [`object.Get` contract](generic-contracts-reference.mdx#objectget-contract) by running the following command:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id object.Get \
--contract-argument '{"object_id": "a.txt"}'
```
You should get a result like the following:
```console
Contract result:
{
"object_id" : "a.txt",
"hash_value" : "b97a42c87a46ffebe1439f8c1cd2f86e2f9b84dad89c8e9ebb257a19b6fdfe1c",
"metadata" : {
"note" : "updated"
}
}
```
If you want to validate the object's authenticity, first recalculate the hash value, for example, by using the `sha256sum` command, for each version of the object that you want to validate.
Then, execute the [`object.Validate` contract](generic-contracts-reference.mdx#objectvalidate-contract) with the recalculated hash values with the version IDs in a descendant order. You can specify any number of versions. The version IDs are only used for identifying which hash values are faulty in the output, so any string values can be used. If there is no version management in your object or file storage, use an empty string for the version ID.
:::note
If you cannot get an older version in your file system, you can specify the hash value of the current version.
:::
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id object.Validate \
--contract-argument \
'{"object_id": "a.txt", "versions": [{"version_id": "v2", "hash_value": "b97a42c87a46ffebe1439f8c1cd2f86e2f9b84dad89c8e9ebb257a19b6fdfe1c"}, {"version_id": "v1", "hash_value": "5c7440fb2273a247f78aadefbc511c680a84e7d44004abfaedef2b145151dab0"}]}'
```
You should see the following result if the recalculated hash values of the object are the same as the ones in Ledger.
```console
Contract result:
{
"status" : "correct",
"faulty_versions" : [ ]
}
```
Suppose that someone tampered with the file `a.txt` as follows:
```txt
Bob created this file.
Alice updated this file
```
Now the hash value of the latest version is `1f75d715648a3b4b3a33ecd7428a3e7139d9357da7d38735c23bf38618ecf9c7`. You can execute validation by running the following command:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id object.Validate \
--contract-argument \
'{"object_id": "a.txt", "versions": [{"version_id": "v2", "hash_value": "1f75d715648a3b4b3a33ecd7428a3e7139d9357da7d38735c23bf38618ecf9c7"}, {"version_id": "v1", "hash_value": "5c7440fb2273a247f78aadefbc511c680a84e7d44004abfaedef2b145151dab0"}]}'
```
You should get a result like the following:
```console
Contract result:
{
"status" : "faulty",
"faulty_versions" : [ "v2" ]
}
```
This validation process confirms if the data outside ScalarDL has not been changed by using the tamper-evident hash values stored in ScalarDL. To validate whether the data in ScalarDL (the hash values in this case) has not been tampered with, you can use the `validate-ledger` command and the `validateLedger` API. For details, see [ScalarDL Client Command Reference](scalardl-command-reference.mdx#generic-contracts) and [Write a ScalarDL Application with Generic Contracts](how-to-write-applications-with-generic-contracts.mdx#validate-your-data).
### Synchronize the object state between ScalarDL Ledger and a ScalarDB table
Since data in ScalarDL (called "assets") is tamper-evident and append-only, data-modeling capabilities and access methods are limited. To compensate for these limitations, you can use ScalarDB in conjunction with ScalarDL for more powerful and easy-to-use modeling capabilities. Specifically, you can execute a contract by using a Java program called a "function" in a single transaction for consistency between ScalarDL and ScalarDB.
In object authenticity management, ScalarDL provides a generic function, [`object.PutToMutableDatabase`](generic-contracts-reference.mdx#objectputtomutabledatabase-function), for putting an arbitrary record into a ScalarDB table when putting an object hash value. One primary use case for `object.PutToMutableDatabase` is reflecting an object state in ScalarDL to an object management table in ScalarDB.
Think about a situation where you would like to store hash values of updated objects in ScalarDL asynchronously for performance and failure recovery reasons. In such a case, you would:
1. Create a table (for example, `objects`) in ScalarDB to manage if the hash value of an object version has already been registered.
1. List and put target objects in the `objects` table with a hash-value-not-registered status.
1. Update the state in the `objects` table after the hash value is successfully registered to ScalarDL.
The third step above can be done in an ACID manner by executing the following command for the [`object.Put` contract](generic-contracts-reference.mdx#objectput-contract) with the [`object.PutToMutableDatabase` function](generic-contracts-reference.mdx#objectputtomutabledatabase-function):
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id object.Put \
--contract-argument '{"object_id": "a.txt", "hash_value": "5c7440fb2273a247f78aadefbc511c680a84e7d44004abfaedef2b145151dab0"}' \
--function-id object.PutToMutableDatabase \
--function-argument '{...}'
```
For the function argument, you need to specify a namespace name, a table name, a partition key, a clustering key (if any), and columns, depending on your ScalarDB table schema. An example is as follows.
```json
{
"namespace": "myns",
"table": "objects",
"partition_key": [
{ "column_name": "object_id", "value": "a.txt", "data_type": "TEXT" }
],
"clustering_key": [
{ "column_name": "version", "value": "1234aef", "data_type": "TEXT" }
],
"columns": [
{ "column_name": "status", "value": 3, "data_type": "INT" },
{ "column_name": "size", "value": 10.000, "data_type": "DOUBLE" },
{ "column_name": "timestamp", "value": 123456789, "data_type": "BIGINT" },
{ "column_name": "comment", "value": "hash-registered", "data_type": "TEXT" }
]
}
```
## Manage collection authenticity
As an example of collection authenticity management, think about managing an audit set, which is a collection of objects that must be validated by using the `object.Validate` contract in an auditing process. If a system cannot guarantee that the audit set has not been changed unexpectedly, a malicious user may be able to change an object fraudulently and remove it from the audit set to avoid being revealed as a fraud. Therefore, managing the audit set is an important and major use case of collection authenticity management.
To create a collection for an audit set, use the [`collection.Create` contract](generic-contracts-reference.mdx#collectioncreate-contract) by running the following command:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id collection.Create \
--contract-argument '{"collection_id":"audit_set", "object_ids": ["a.txt", "b.txt"]}'
```
The collection ID must be a unique ID that identifies the collection. You can specify a set of object IDs in a JSON array. The object IDs are just string values, so you can specify any IDs for them. For example, you can put the collection IDs to represent the audit set in a hierarchical manner. For the input and output specifications for generic contracts and functions, see [Generic Contracts and Functions Reference Guide](generic-contracts-reference.mdx).
You can also add and remove objects to or from the collection by using the [`collection.Add` contract](generic-contracts-reference.mdx#collectionadd-contract) and the [`collection.Remove` contract](generic-contracts-reference.mdx#collectionremove-contract). To do this, run the following commands:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id collection.Add \
--contract-argument '{"collection_id":"audit_set", "object_ids": ["c.txt", "d.txt"]}'
```
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id collection.Remove \
--contract-argument '{"collection_id":"audit_set", "object_ids": ["a.txt"]}'
```
You can get the latest status of the collection by using the [`collection.Get` contract](generic-contracts-reference.mdx#collectionget-contract). To do this, run the following command:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id collection.Get \
--contract-argument '{"collection_id":"audit_set"}'
```
You should get a result like the following:
```console
Contract result:
{"object_ids": ["c.txt", "d.txt", "b.txt"]}
```
To confirm that the audit set has not been changed unexpectedly, you can check the update history of the audit set by using the [`collection.GetHistory` contract](generic-contracts-reference.mdx#collectiongethistory-contract). To do this, run the following command:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id collection.GetHistory \
--contract-argument '{"collection_id":"audit_set"}'
```
You should get a result like the following:
```console
Contract result:
{
"collection_id" : "audit_set",
"collection_events" : [ {
"operation_type" : "remove",
"age" : 2,
"object_ids" : [ "a.txt" ]
}, {
"operation_type" : "add",
"age" : 1,
"object_ids" : [ "c.txt", "d.txt" ]
}, {
"operation_type" : "create",
"age" : 0,
"object_ids" : [ "a.txt", "b.txt" ]
} ]
}
```
## See also
To interact with generic contracts and functions in your Java applications, see the following:
* [Write a ScalarDL Application with Generic Contracts](how-to-write-applications-with-generic-contracts.mdx)
* [Javadoc](javadoc/index.mdx)
To write your own contracts and functions based on generic contracts and functions, see the following:
* The source code of the generic contracts and functions, which are available in the `generic-contracts` directory previously mentioned in this guide
* [A Guide on How to Write a Good Contract](how-to-write-contract.mdx)
* [A Guide on How to Write a Good Function](how-to-write-function.mdx)
To better understand the foundation of ScalarDL, see the following:
* [ScalarDL Design Document](design.mdx)
* [ScalarDL Implementation](implementation.mdx)
================================================
FILE: docs/use-table-oriented-generic-contracts.mdx
================================================
---
tags:
- Community
- Enterprise
- Private Preview
displayed_sidebar: docsEnglish
---
# Use Table-Oriented Generic Contracts
import JDKVersions from '/src/components/en-us/_prerequisites-jdk-versions.mdx';
:::tip
Although table-oriented generic contracts were introduced in ScalarDL 3.11, TableStore, released in ScalarDL 3.12, provides a higher-level abstraction that wraps table-oriented generic contracts. For most use cases, using TableStore is simpler and more efficient than using table-oriented generic contracts directly. For details, see [Get Started with ScalarDL TableStore](./getting-started-tablestore.mdx) in the latest version of ScalarDL.
:::
Table-oriented generic contracts in ScalarDL are a type of [generic contract](use-generic-contracts.mdx) that provide a data model similar to the relational data model and a user-friendly interface for managing ledger data, enabling easy application development. This guide explains how to use table-oriented generic contracts.
:::note
The table-oriented generic contracts are currently in Private Preview, which means that future versions might have backward-incompatible updates.
:::
## Set up an environment
In this section, you'll set up the environment for using the table-oriented generic contracts through the ScalarDL client tools. If you want to interact with generic contracts in your applications, you can use the ScalarDL Client SDK APIs. For details, see [Write a ScalarDL Application with Generic Contracts](how-to-write-applications-with-generic-contracts.mdx). In addition, the SQL-based interface will be provided in the near future.
### Install a JDK
In this guide, you'll only use a Java runtime environment for seeing how generic contracts work. However, it is recommended that you install one of the following Java Development Kits (JDKs), which will be required to build your own ScalarDL application outside of this guide.
- One of the following Java Development Kits (JDKs):
### Set up a ScalarDL environment
Set up a ScalarDL environment that meets your own requirements. If you want to deploy ScalarDL in a local test environment, you can deploy such an environment by using a sample Docker Compose configuration and Scalar Helm Chart. For details, see the following:
- [Get Started with ScalarDL Ledger](getting-started.mdx)
- [Get Started with Scalar Helm Charts](helm-charts/getting-started-scalar-helm-charts.mdx)
For a production environment, ScalarDL is available as container images. For details, see [How to get the container images of Scalar products](scalar-kubernetes/HowToGetContainerImages.mdx).
:::note
The table-oriented generic contracts are supported in ScalarDL version 3.11 or later versions.
:::
### Download the necessary tools and the generic contracts
Specify a ScalarDL version that is equal to or greater than 3.11.0 by running the following command. For available versions, see [Tags](https://github.com/scalar-labs/scalardl/tags).
```console
VERSION=X.Y.Z
```
Also, specify the table-oriented generic contract version by running the following command. Use the following mapping table to identify the version corresponding to the ScalarDL version. Make sure to replace the separator `.` to `_`, for example, `1_0_0` for the version `1.0.0`.
| ScalarDL Version | Table-Oriented Generic Contract Version |
|:-----------------|:----------------------------------------|
| 3.11.0 or later | 1.0.0 |
```console
TGC_VERSION=X_Y_Z
```
Then, download the tools and the generic contracts by running the following commands:
```console
curl -OL https://github.com/scalar-labs/scalardl/releases/download/v$VERSION/scalardl-java-client-sdk-$VERSION.zip
unzip scalardl-java-client-sdk-$VERSION.zip
mv scalardl-java-client-sdk-$VERSION client
curl -OL https://github.com/scalar-labs/scalardl/releases/download/v$VERSION/scalardl-generic-contracts-$VERSION.zip
unzip scalardl-generic-contracts-$VERSION.zip
mv scalardl-generic-contracts-$VERSION generic-contracts
```
## Register a certificate and the table-oriented generic contracts
This section describes how to register a certificate and the generic contracts.
### Configure the properties
To interact with the ScalarDL components, you need to configure the client properties. For details, see [Configure properties](getting-started.mdx#configure-properties).
### Register a certificate or secret
Prepare a certificate for registration. For details, see [How to get a certificate](ca/caclient-getting-started.mdx).
Then, register your certificate by using the ScalarDL client CLI as follows:
```console
client/bin/scalardl generic-contracts register-cert --properties client.properties
```
:::note
You can also use HMAC authentication instead of using a certificate. For details about HMAC authentication, see [ScalarDL Authentication Guide](authentication.mdx).
:::
### Register the table-oriented generic contracts
After registering the certificate, you can register the table-oriented generic contracts by running the following commands:
```console
client/bin/scalardl generic-contracts register-contracts --properties client.properties --contracts-file generic-contracts/conf/table-authenticity-management-contracts.toml
```
## Interact with table-oriented generic contracts
Now you can execute the table-oriented generic contracts. In this section, you'll try the following functionalities through two sample tables (`employee` and `department`) that can be joined through the department IDs of employees.
- [Create and show tables](#create-and-show-tables)
- [Insert records](#insert-records)
- [Select records](#select-records)
- [Update records](#update-records)
- [Get record histories](#get-record-histories)
### Create and show tables
You can create the samples table by running the following commands:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Create \
--contract-argument '{"name": "employee", "key": "id", "type": "string", "indexes": [{"key": "department", "type": "string"}]}'
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Create \
--contract-argument '{"name": "department", "key": "id", "type": "string"}'
```
When creating a table, you need to specify the name and the primary key. You can additionally specify the secondary indexes. `string`, `number`, and `boolean` are supported as the data type of the primary key and index key.
You can show the created tables by running the following commands:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.ShowTables \
--contract-argument '{}'
```
You should get a result like the following:
```console
Contract result:
[ {
"name" : "employee",
"key" : "id",
"type" : "string",
"indexes" : [ {
"key" : "department",
"type" : "string"
} ]
}, {
"name" : "department",
"key" : "id",
"type" : "string",
"indexes" : [ ]
} ]
```
### Insert records
Next, insert several `employee` records by running the following commands:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Insert \
--contract-argument '{"table": "employee", "values": {"id": "1001", "name": "Alice", "department": "sales", "salary": 654.3}}'
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Insert \
--contract-argument '{"table": "employee", "values": {"id": "1002", "name": "Bob", "department": "sales", "salary": 543.2}}'
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Insert \
--contract-argument '{"table": "employee", "values": {"id": "1003", "name": "Carol", "department": "engineering", "salary": 654.3}}'
```
Insert the corresponding `department` records as well by running the following commands:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Insert \
--contract-argument '{"table": "department", "values": {"id": "sales", "location": "Shinjuku", "phone": "000-1234"}}'
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Insert \
--contract-argument '{"table": "department", "values": {"id": "engineering", "location": "Shibuya", "phone": "000-4321"}}'
```
### Select records
Then, check the inserted records. You need to specify at least a primary key or index key to select records. For example, you can get an `employee` record by specifying the primary key by running the following commands:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Select \
--contract-argument '{"table": "employee", "conditions": [ {"column": "id", "value": "1001", "operator": "EQ"} ], "projections": [ "id", "name", "department" ]}'
```
You can optionally project the columns by specifying top-level fields in the JSON record object. You should get a result like the following:
```console
Contract result:
[ {
"id" : "1001",
"name" : "Alice",
"department" : "sales"
} ]
```
You can also specify an index key to select records by running the following commands:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Select \
--contract-argument '{"table": "employee", "conditions": [ {"column": "department", "value": "sales", "operator": "EQ"} ], "projections": [ "id", "name", "department" ]}'
```
You should get a result like the following:
```console
Contract result:
[ {
"id" : "1001",
"name" : "Alice",
"department" : "sales"
}, {
"id" : "1002",
"name" : "Bob",
"department" : "sales"
} ]
```
If you want to filter records, specify additional conditions by running the following commands:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Select \
--contract-argument '{"table": "employee", "conditions": [ {"column": "department", "value": "sales", "operator": "EQ"}, {"column": "salary", "value": 600, "operator": "LT"} ]}'
```
For the additional filters, you can use operators: `EQ` (equal), `NE` (not equal), `LT` (less than), `LTE` (less than or equal), `GT` (greater than), `GTE` (greater than or equal), `IS_NULL`, and `IS_NOT_NULL`. You should get a result like the following:
```console
Contract result:
[ {
"id" : "1002",
"name" : "Bob",
"department" : "sales",
"salary" : 543.2
} ]
```
You can also join the two tables by running the following commands:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Select \
--contract-argument '{ "table": "employee", "joins": [ { "table": "department", "left": "employee.department", "right": "department.id" } ], "conditions": [ {"column": "employee.department", "value": "engineering", "operator": "EQ"} ] }'
```
You should get a result like the following:
```console
Contract result:
[ {
"employee.id" : "1003",
"employee.name" : "Carol",
"employee.department" : "engineering",
"employee.salary" : 654.3,
"department.id" : "engineering",
"department.location" : "Shibuya",
"department.phone" : "000-4321"
} ]
```
### Update records
You can update the `employee` records by running the following commands:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Update \
--contract-argument '{ "table": "employee", "values": {"salary": 754.3}, "conditions": [ {"column": "department", "value": "sales", "operator": "EQ"} ] }'
```
Make sure to specify at least a primary key or an index key to update the records, in the same way as using the `Select` contract.
### Get record histories
You can get the update history of a record by running the following commands:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.GetHistory \
--contract-argument '{ "table": "employee", "key": "1003" }'
```
You should get a result like the following:
```console
Contract result:
[ {
"age" : 1,
"values" : {
"id" : "1003",
"name" : "Carol",
"department" : "engineering",
"salary" : 754.3
}
}, {
"age" : 0,
"values" : {
"id" : "1003",
"name" : "Carol",
"department" : "engineering",
"salary" : 654.3
}
} ]
```
If you want to limit the number of versions (ages), specify the `limit` option by running the following commands:
```console
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.GetHistory \
--contract-argument '{ "table": "employee", "key": "1003", "limit": 1 }'
```
You should get the specified number of the **latest** records like the following:
```console
Contract result:
[ {
"age" : 1,
"values" : {
"id" : "1003",
"name" : "Carol",
"department" : "engineering",
"salary" : 754.3
}
} ]
```
## Validate data created by the table-oriented generic contracts
In ScalarDL, you occasionally need to validate your data to make sure all the data is in a valid state. You can use the `validate-ledger` command to validate assets created by the table-oriented generic contracts. If you want to validate them in your applications, you can use the ScalarDL Client SDK APIs. For details, see [Validate your data](how-to-write-applications-with-generic-contracts.mdx#validate-your-data).
You can validate the table schema by running the following commands:
```console
client/bin/scalardl generic-contracts validate-ledger --properties client.properties \
--table-name employee
```
You should get a result like the following:
```console
{
"status_code" : "OK",
"Ledger" : {
"id" : "tbl_employee",
"age" : 0,
"nonce" : "26af1229-1c1f-4b89-86e2-ec011da3b313",
"hash" : "ZA9yFzjIg1qeHAd7Sub8uFvt2JrTb6XSzGUktPEITr0=",
"signature" : "MEUCIAh4Xj93J/jldqbQor7AVM4ii9+suxQrZlCFnKWWDIo0AiEAiM6Yi6GO4bQ2VZg2GnqKmOFPEANrTU4g7pjBMcaX6TQ="
},
"Auditor" : null
}
```
You can validate the record by running the following commands:
```console
client/bin/scalardl generic-contracts validate-ledger --properties client.properties \
--table-name employee --primary-key-column-name id --column-value '"1001"'
```
You should get a result like the following:
```console
{
"status_code" : "OK",
"Ledger" : {
"id" : "rec_employee_id_1001",
"age" : 0,
"nonce" : "41a18e7f-314f-4aec-8984-62bf6cd355d0",
"hash" : "n7KJLuC/KOzFZLnGKEs6pOQvCbl4WSF+xplOUd9MrSo=",
"signature" : "MEUCIEHafCsSXWWtZnDbSpAwFQk4qjW1B7cXjEgdwVF8uKQeAiEAsvzEMKyuNFozAbLC/E8FEviCMLCqo9DPRQe4tVBFwIk="
},
"Auditor" : null
}
```
You can validate the index record by running the following commands:
```console
client/bin/scalardl generic-contracts validate-ledger --properties client.properties \
--table-name employee --index-key-column-name department --column-value '"sales"'
```
You should get a result like the following:
```console
{
"status_code" : "OK",
"Ledger" : {
"id" : "idx_employee_department_sales",
"age" : 0,
"nonce" : "41a18e7f-314f-4aec-8984-62bf6cd355d0",
"hash" : "n7KJLuC/KOzFZLnGKEs6pOQvCbl4WSF+xplOUd9MrSo=",
"signature" : "MEUCIEHafCsSXWWtZnDbSpAwFQk4qjW1B7cXjEgdwVF8uKQeAiEAsvzEMKyuNFozAbLC/E8FEviCMLCqo9DPRQe4tVBFwIk="
},
"Auditor" : null
}
```
:::note
Generic contracts internally assign a dedicated asset ID to an [asset record](data-modeling.mdx#asset-record). The asset ID consists of a prefix for the asset type and keys for identification; for example, a prefix `rec_`, table name, primary key column name, and column value are used for the asset ID of a record. Therefore, you will see such raw asset IDs in the result of `validate-ledger`.
:::
## See also
To interact with the table-oriented generic contracts in your Java applications, see the following:
* [Write a ScalarDL Application with Generic Contracts](how-to-write-applications-with-generic-contracts.mdx)
* [Javadocs for the ScalarDL Java Client SDK](https://javadoc.io/doc/com.scalar-labs/scalardl-java-client-sdk/latest/index.html)
================================================
FILE: docs/applications/simple-bank-account/README.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# A simple bank account application
import JDKVersions from '/src/components/en-us/_prerequisites-jdk-versions.mdx';
## Overview
This is a simple bank account application, which can be found in the [`scalardl` repository](https://github.com/scalar-labs/scalardl/tree/master/docs/applications/simple-bank-account/). The actions that a user can perform are: create an account, view an account history, deposit funds to an account, withdraw funds from an account, and transfer funds between accounts. All actions performed on an account are recorded in ScalarDL, which means that the account history is recorded in a tamper-evident way, similar to how blockchains record blocks. This means that if an account history was altered (either intentionally or not), it is possible to detect this.
To keep things simple here we are assuming that the bank holds the private key to execute all the contracts (see below for more explanation of how this works). This is probably not how you would want to use this bank application in practice. In this case a malicious account manager could actually change a user's account history, e.g., by simply recreating it and filling it with false data. A more meaningful setup is that the bank owns the private key to deposit to an account, and each user registers a withdrawal and transfer contract using their own private key. Then only the bank can move funds into an account, and only users can move funds out of their accounts.
This application uses five contracts:
- [`AccountHistory.java`](https://github.com/scalar-labs/scalardl/blob/master/docs/applications/simple-bank-account/contract/src/main/java/com/scalar/application/bankaccount/contract/AccountHistory.java)
- [`CreateAccount.java`](https://github.com/scalar-labs/scalardl/blob/master/docs/applications/simple-bank-account/contract/src/main/java/com/scalar/application/bankaccount/contract/CreateAccount.java)
- [`Deposit.java`](https://github.com/scalar-labs/scalardl/blob/master/docs/applications/simple-bank-account/contract/src/main/java/com/scalar/application/bankaccount/contract/Deposit.java)
- [`Transfer.java`](https://github.com/scalar-labs/scalardl/blob/master/docs/applications/simple-bank-account/contract/src/main/java/com/scalar/application/bankaccount/contract/Transfer.java)
- [`Withdraw.java`](https://github.com/scalar-labs/scalardl/blob/master/docs/applications/simple-bank-account/contract/src/main/java/com/scalar/application/bankaccount/contract/Withdraw.java)
These contracts will be registered by the bank and will allow the bank to, respectively, view account histories, create accounts, deposit funds to an account, transfer funds between accounts, and withdraw funds from accounts.
The overall architecture of this application can be viewed as follows. (Note again that this use case is for simplicity, and in practice may look a bit different.)

## Prerequisites for this sample application
- One of the following Java Development Kits (JDKs):
## Trying out the application
Download the [ScalarDL Client SDK](https://github.com/scalar-labs/scalardl-client-sdk). Make sure ScalarDL is running and register all the required contracts by executing
```console
./gradlew build
cd contract
SCALAR_SDK_HOME=/path/to/scalardl-client-sdk ./register
```
Run the application using IntelliJ (or the IDE of your choice), or by executing `gradle bootRun` in the project home directory. It should create a server on `localhost:8080` to which you can send HTTP requests in order to interact with the app. See the [API documentation](./docs/api_endpoints.mdx) for more information. To create HTTP requests we have found that [Postman](https://www.getpostman.com/) is quite nice.
## A short tutorial on writing a ScalarDL application
We decided to use Spring Boot to create a web service to interact with the contracts. This is, of course, not the only choice. Another choice would be to create a command line interface as was done, for example, in the [asset management application](https://github.com/indetail-blockchain/getting-started-with-scalardl). There you can also find a very nice tutorial for writing applications for ScalarDL.
In this tutorial we will not discuss the detail at the level of web services or command line interfaces, and instead focus on the interaction between our application and ScalarDL. We will discuss how to write contracts, register contracts, and then how to call these contracts from the application using the ScalarDL SDK.
### Contracts
Contracts are Java classes which extend the `JacksonBasedContract` class and override the `invoke` method. Let's take a closer look at the `Deposit.java` contract.
```java
package com.scalar.application.bankaccount.contract;
import com.fasterxml.jackson.databind.JsonNode;
import com.scalar.dl.ledger.statemachine.Asset;
import com.scalar.dl.ledger.contract.JacksonBasedContract;
import com.scalar.dl.ledger.exception.ContractContextException;
import com.scalar.dl.ledger.statemachine.Ledger;
import java.util.Optional;
import javax.annotation.Nullable;
public class Deposit extends JacksonBasedContract {
@Override
public JsonNode invoke(
Ledger ledger, JsonNode argument, @Nullable JsonNode properties) {
if (!argument.has("id") || !argument.has("amount")) {
throw new ContractContextException("a required key is missing: id and/or amount");
}
String id = argument.get("id").asText();
long amount = argument.get("amount").asLong();
if (amount < 0) {
throw new ContractContextException("amount is negative");
}
Optional> asset = ledger.get(id);
if (!asset.isPresent()) {
throw new ContractContextException("account does not exist");
}
long oldBalance = asset.get().data().get("balance").asLong();
long newBalance = oldBalance + amount;
ledger.put(id, getObjectMapper().createObjectNode().put("balance", newBalance));
return getObjectMapper()
.createObjectNode()
.put("status", "succeeded")
.put("old_balance", oldBalance)
.put("new_balance", newBalance);
}
}
```
In order for this contract to function properly the user must supply an account `id` and an `amount`. So the first thing to do is check whether the argument contains these two keys, and if not, throw a `ContractContextException`.
**Note:** `ContractContextException` is the only throwable exception in a contract and it should be thrown whenever a non-recoverable error is encountered.
So, assuming that we have an `id` and an `amount`, we do a quick non-negative check on `amount` and again throw a `ContractContextException` if it is. Now we are ready to interact with the `ledger`.
There are three methods that can be called on `ledger`: `get(String s)`, `put(String s, JsonNode jsonNode)`, and `scan(AssetFilter assetFilter)`. `get(String s)` will retrieve the asset `s` from the ledger. `put(String s, JsonNode jsonNode)` will associate the asset `s` with the data `jsonNode` and increase the age of the asset. `scan(AssetFilter assetFilter)` will return a version of the history of an asset as specified in the `AssetFilter`.
**Note:** ledger does not permit blind writes, i.e., before performing a `put` on a particular asset, we must first `get` that asset. Furthermore `scan` is only allowed in read-only contracts, which means a single contract cannot both `scan` and `put`.
The rest of the contract proceeds in a straightforward manner. We first `get` the asset from the ledger, retrieve its current balance, add the deposit amount to it, and finally `put` the asset back into the ledger with its new balance.
At the end we must return a `JsonNode`. What the `JsonNode` contains is up to the designer of the contract. Here we have decided to include a `status` message, the `old_balance`, and the `new_balance`.
If you wish, you can view the other contracts that this application uses in the [`contract` folder for this sample on GitHub](https://github.com/scalar-labs/scalardl/tree/master/docs/applications/simple-bank-account/contract/src/main/java/com/scalar/application/bankaccount/contract).
Once you have written your contracts you will need to compile them, and this can be done as
```console
./gradlew build
```
### Registering your certification and contracts
You should now have written and compiled your contracts. Before you can execute them, however, you will need to register them on the ScalarDL network. We will make use of the tools available in the [ScalarDL Client SDK](https://github.com/scalar-labs/scalardl-client-sdk) `client/bin` directory to register and execute the contracts. Please make sure you have access to this directory.
Now, you will need to have your certificate (e.g. `client.pem`) and its corresponding private key (e.g. `client-key.pem`), and ScalarDL up and running. Edit `client.properties` (found in the `conf` directory) to suit your configuration. It should contain lines that look something like:
```console
scalar.dl.client.server.host=localhost
scalar.dl.client.server.port=50051
scalar.dl.client.cert_holder_id=alice
scalar.dl.client.cert_path=conf/client.pem
scalar.dl.client.private_key_path=conf/client-key.pem
```
If everything is set up properly you should be able to register your certificate on the ScalarDL network as
```console
cd contract
${SCALAR_SDK_HOME}/client/bin/scalardl register-cert --properties ../conf/client.properties
```
You should receive status code 200 if successful.
To register your contracts you can create a `contracts.toml` file in the `conf` directory using the following format:
```toml
[[contracts]]
contract-id = "create-account"
contract-binary-name = "com.scalar.application.bankaccount.contract.CreateAccount"
contract-class-file = "build/classes/java/main/com/scalar/application/bankaccount/contract/CreateAccount.class"
[[contracts]]
contract-id = "deposit"
contract-binary-name = "com.scalar.application.bankaccount.contract.Deposit"
contract-class-file = "build/classes/java/main/com/scalar/application/bankaccount/contract/Deposit.class"
[[contracts]]
contract-id = "transfer"
contract-binary-name = "com.scalar.application.bankaccount.contract.Transfer"
contract-class-file = "build/classes/java/main/com/scalar/application/bankaccount/contract/Transfer.class"
```
In this example we will register three contracts: `CreateAccount.java`, `Deposit.java`, and `Transfer.java`. The `contract-binary-name` and `contract-class-file` are determined, but you are free to choose the `contract-id` as you wish. The `contract-id` is how you can refer to a specific contract using `ClientService`, as we will see below.
Once your toml file is written you can register all the specified contracts as
```console
${SCALAR_SDK_HOME}/client/bin/scalardl register-contracts --properties ../conf/client.properties --contracts-file ../conf/contracts.toml
```
Each successfully registered contract should return status code 200.
### Executing contracts
You can now execute any registered contracts if you would like. For example, use our register contracts to create a couple of accounts, deposit funds into one of the accounts, transfer some of these funds to the other account, and check the account history.
Create two accounts with ids `a111` and `b222`. (Contract ids can be any string.)
```console
${SCALAR_SDK_HOME}/client/bin/scalardl execute-contract --properties ../conf/client.properties --contract-id create-account --contract-argument '{"id": "a111"}'
${SCALAR_SDK_HOME}/client/bin/scalardl execute-contract --properties ../conf/client.properties --contract-id create-account --contract-argument '{"id": "b222"}'
```
Now, deposit 100 into account `a111`:
```console
${SCALAR_SDK_HOME}/client/bin/scalardl execute-contract --properties ../conf/client.properties --contract-id deposit --contract-argument '{"id": "a111", "amount": 100}'
```
Finally, transfer 25 from `a111` to `b222`:
```console
${SCALAR_SDK_HOME}/client/bin/scalardl execute-contract --properties ../conf/client.properties --contract-id transfer --contract-argument '{"from": "a111", "to": "b222", "amount": 100}'
```
You can check the balance history of account `a111` as follows:
```console
${SCALAR_SDK_HOME}/client/bin/scalardl execute-contract --properties ../conf/client.properties --contract-id account-history --contract-argument '{"id": "a111"}'
```
You should see the following output:
```console
Contract result:
{
"status" : "succeeded",
"history" : [ {
"id" : "a111",
"age" : 2,
"data" : {
"balance" : 0
}
}, {
"id" : "a111",
"age" : 1,
"data" : {
"balance" : 100
}
}, {
"id" : "a111",
"age" : 0,
"data" : {
"balance" : 0
}
} ]
}
```
If you were running the application itself, you could execute these commands using the [API endpoints](./docs/api_endpoints.mdx).
## ClientService
You should now have your contracts registered on the ScalarDL network. In order to execute these contracts from an application we will make use of `ClientService` class from the [ScalarDL Client SDK](https://github.com/scalar-labs/scalardl-client-sdk).
The Client SDK is available on [Maven Central](https://search.maven.org/search?q=a:scalardl-client-sdk), and it can be installed in your application using Gradle by adding the following dependency to your `build.gradle`:
```groovy
dependencies {
implementation group: 'com.scalar-labs', name: 'scalardl-java-client-sdk', version: '3.13.0'
}
```
The following snippet shows how you can instantiate a `ClientService` object, where `properties` should be the path to your `client.properties` file.
```java
ClientServiceFactory factory = new ClientServiceFactory();
ClientService service = factory.create(new ClientConfig(new File(properties)));
```
`ClientService` contains a method `executeContract(String contractId, JsonNode contractArgument)` which can be used to, of course, execute a contract. For example:
```java
ObjectMapper mapper = new ObjectMapper();
JsonNode argument = mapper.createObjectNode().put("id", "010-123456789");
ContractExecutionResult result = clientService.executeContract("create-account", argument);
```
will execute the `CreateAccount` contract with argument `{"id": "010-123456789"}`, as we did above. Note that we call the contract using the supplied id `create-account` that we chose when registering the contract.
The result of executing the contract is a `ContractExecutionResult`. It contains, result and proofs, each of which can be obtained respectively as
```java
result.getProofs();
result.getResult();
```
## What is next?
We hope that this has provided you with enough information to get started writing your own apps. Here are some ideas of what you can try next.
- Visit the [ScalarDL Client SDK](https://github.com/scalar-labs/scalardl-client-sdk) github page.
- The [ScalarDL Emulator](https://github.com/scalar-labs/scalardl-emulator) lets you test your contracts on an in-memory ledger.
================================================
FILE: docs/applications/simple-bank-account/docs/api_endpoints.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# API endpoints
## `GET v1/accounts`
- **Not implemented yet**
- Return a list of accounts and their balances as a JSON array
```
[
{
"account": ,
"balance":
},
...
]
```
## `GET v1/accounts/{id}?start=&end=&order=&limit=`
- Return the given account history as a JSON array
- Return `200 OK` if success
```
[
{
"account": ,
"balance": ,
"age":
},
...
]
```
## `PUT v1/accounts/{id}`
- Create the specified account with id=`{id}`
- Return `200 OK` if success
- Return `403 Bad Request` if the account already exists
## `POST v1/accounts/{id}/deposit?amount=`
- Deposit into a specified account
- Return `200 OK` if success
## `POST v1/accounts/{id}/withdraw?amount=`
- Withdraw from a specified account
- Return `200 OK` if success
- Return `403 Bad Request` if amount exceeds the balance in the account
## `POST v1/transfers?from=&to=&amount=`
- Transfer funds from one account to another
- Return `200 OK` if success
- Return `403 Bad Request` if amount exceeds the balance in the from account
## Delete an account
There is no way to do this.
================================================
FILE: docs/ca/caclient-getting-started.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# How to Get a Certificate
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
This document describes how to get a certificate to enroll in ScalarDL.
ScalarDL has several kinds of authentication methods. If you use `digital-signature` as the authentication method, you must prepare private key and certificate files. For more details on authentication methods, see [ScalarDL Authentication Guide](../authentication.mdx).
## Private key and certificate requirements
If you use [`digital-signature`](../authentication.mdx#digital-signatures) as the authentication method, you must create a private key and certificate that satisfy the following requirements:
- `SEC1` or `PKCS#8` key
- `ECDSA` as the algorithm
- `P-256` as the curve parameter
- `SHA256` as the hash function
:::note
ScalarDL does not check the expiration date of certificates. So, you can set any expiration dates to certificates that ScalarDL uses.
:::
## Create a private key and certificate file
You can create a self-signed certificate as follows:
:::note
This example creates a `SEC1` key.
:::
Prerequisites
You must install the [cfssl and cfssljson](https://github.com/cloudflare/cfssl) command-line tools for the following steps.
Create a local CA
1. Create a working directory.
```console
mkdir -p ${HOME}/scalardl/digital-signature/certs/
```
1. Change the working directory to `${HOME}/scalardl/digital-signature/certs/`.
```console
cd ${HOME}/scalardl/digital-signature/certs/
```
1. Create a JSON file that includes CA information.
```console
cat << 'EOF' > ${HOME}/scalardl/digital-signature/certs/ca.json
{
"CN": "scalardl-example-ca",
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "JP",
"ST": "Tokyo",
"L": "Shinjuku",
"O": "ScalarDL Example CA"
}
]
}
EOF
```
1. Create the CA private key and certificate files.
```console
cfssl gencert -initca ca.json | cfssljson -bare ca
```
1. Create a JSON file that includes CA configurations.
```console
cat << 'EOF' > ${HOME}/scalardl/digital-signature/certs/ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"scalardl-example-ca": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth"
]
}
}
}
}
EOF
```
Create a private key and certificate for each component
1. Create a JSON file that includes ScalarDL Ledger information.
```console
cat << 'EOF' > ${HOME}/scalardl/digital-signature/certs/ledger.json
{
"CN": "scalardl-ledger",
"hosts": [
"ledger.scalardl.example.com",
"localhost"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "JP",
"ST": "Tokyo",
"L": "Shinjuku",
"O": "ScalarDL Ledger Example"
}
]
}
EOF
```
1. Create the private key and certificate files for ScalarDL Ledger.
```console
cfssl gencert -ca ca.pem -ca-key ca-key.pem -config ca-config.json -profile scalardl-example-ca ledger.json | cfssljson -bare ledger
```
1. Confirm that the private key and certificate files were created.
```console
ls -1
```
You should see the following output:
```console
ca-config.json
ca-key.pem
ca.csr
ca.json
ca.pem
ledger-key.pem
ledger.csr
ledger.json
ledger.pem
```
In this case:
- `ledger-key.pem` is the private key file for ScalarDL Ledger.
- `ledger.pem` is the certificate file for ScalarDL Ledger.
- `ca.pem` is the root CA certificate file.
1. Create a JSON file that includes ScalarDL Auditor information.
```console
cat << 'EOF' > ${HOME}/scalardl/digital-signature/certs/auditor.json
{
"CN": "scalardl-auditor",
"hosts": [
"auditor.scalardl.example.com",
"localhost"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "JP",
"ST": "Tokyo",
"L": "Shinjuku",
"O": "ScalarDL Auditor Example"
}
]
}
EOF
```
1. Create the private key and certificate files for ScalarDL Auditor.
```console
cfssl gencert -ca ca.pem -ca-key ca-key.pem -config ca-config.json -profile scalardl-example-ca auditor.json | cfssljson -bare auditor
```
1. Confirm that the private key and certificate files were created.
```console
ls -1
```
You should see the following output:
```console
auditor-key.pem
auditor.csr
auditor.json
auditor.pem
ca-config.json
ca-key.pem
ca.csr
ca.json
ca.pem
```
In this case:
- `auditor-key.pem` is the private key file for ScalarDL Auditor.
- `auditor.pem` is the certificate file for ScalarDL Auditor.
- `ca.pem` is the root CA certificate file.
1. Create a JSON file that includes client information.
```console
cat << 'EOF' > ${HOME}/scalardl/digital-signature/certs/client.json
{
"CN": "scalardl-client",
"hosts": [
"client.scalardl.example.com",
"localhost"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "JP",
"ST": "Tokyo",
"L": "Shinjuku",
"O": "ScalarDL Client Example"
}
]
}
EOF
```
1. Create the private key and certificate files for the client.
```console
cfssl gencert -ca ca.pem -ca-key ca-key.pem -config ca-config.json -profile scalardl-example-ca client.json | cfssljson -bare client
```
1. Confirm that the private key and certificate files were created.
```console
ls -1
```
You should see the following output:
```console
ca-config.json
ca-key.pem
ca.csr
ca.json
ca.pem
client-key.pem
client.csr
client.json
client.pem
```
In this case:
- `client-key.pem` is the private key file for the client.
- `client.pem` is the certificate file for the client.
- `ca.pem` is the root CA certificate file.
Prerequisites
You must install the `openssl` command-line tool for the following steps.
Create a working directory
1. Create a working directory.
```console
mkdir -p ${HOME}/scalardl/digital-signature/certs/
```
1. Change the working directory to `${HOME}/scalardl/digital-signature/certs/`.
```console
cd ${HOME}/scalardl/digital-signature/certs/
```
Create a private key and certificate for each component
1. Create an EC parameter.
```console
openssl ecparam -name prime256v1 -out prime256v1.pem
```
1. Create a private key and CSR.
```console
openssl req -new -newkey ec:prime256v1.pem -nodes -keyout ledger-key.pem -out ledger.csr
```
1. Convert the `PKCS#8` key to the `SEC1` key.
```console
openssl ec -in ledger-key.pem -out ledger-key.pem
```
1. Create a certificate for ScalarDL Ledger.
```console
openssl x509 -req -days 3650 -signkey ledger-key.pem -in ledger.csr -out ledger.pem
```
1. Confirm that the private key and certificate files were created.
```console
ls -1
```
You should see the following output:
```console
ledger-key.pem
ledger.csr
ledger.pem
prime256v1.pem
```
In this case:
- `ledger-key.pem` is the private key file for ScalarDL Ledger.
- `ledger.pem` is the certificate file for ScalarDL Ledger.
1. Create an EC parameter.
```console
openssl ecparam -name prime256v1 -out prime256v1.pem
```
1. Create a private key and CSR.
```console
openssl req -new -newkey ec:prime256v1.pem -nodes -keyout auditor-key.pem -out auditor.csr
```
1. Convert the `PKCS#8` key to the `SEC1` key.
```console
openssl ec -in auditor-key.pem -out auditor-key.pem
```
1. Create a certificate for ScalarDL Auditor.
```console
openssl x509 -req -days 3650 -signkey auditor-key.pem -in auditor.csr -out auditor.pem
```
1. Confirm that the private key and certificate files were created.
```console
ls -1
```
You should see the following output:
```console
auditor-key.pem
auditor.csr
auditor.pem
prime256v1.pem
```
In this case:
- `auditor-key.pem` is the private key file for ScalarDL Auditor.
- `auditor.pem` is the certificate file for ScalarDL Auditor.
1. Create an EC parameter.
```console
openssl ecparam -name prime256v1 -out prime256v1.pem
```
1. Create a private key and CSR.
```console
openssl req -new -newkey ec:prime256v1.pem -nodes -keyout client-key.pem -out client.csr
```
1. Convert the `PKCS#8` key to the `SEC1` key.
```console
openssl ec -in client-key.pem -out client-key.pem
```
1. Create a certificate for the client.
```console
openssl x509 -req -days 3650 -signkey client-key.pem -in client.csr -out client.pem
```
1. Confirm that the private key and certificate files were created.
```console
ls -1
```
You should see the following output:
```console
client-key.pem
client.csr
client.pem
prime256v1.pem
```
In this case:
- `client-key.pem` is the private key file for the client.
- `client.pem` is the certificate file for the client.
You can ask your [CFSSL server](./caserver-getting-started.mdx) to create a certificate file.
Prerequisites
You must install the [cfssl and cfssljson](https://github.com/cloudflare/cfssl) command-line tools for the following steps.
Create a private key and certificate file
1. Create a private key and CSR based on the [requirements](#private-key-and-certificate-requirements) by using a tool such as CFSSL or OpenSSL. You can see an example of how to create a private key and CSR by using the `cfssl` command in the [CFSSL](?methods=self-signed&tools=cfssl) tab or the `openssl` command in the [OpenSSL](?methods=self-signed&tools=openssl) tab.
1. Request a certificate from your CFSSL server.
:::note
- The `-remote` option is needed to specify the CFSSL server endpoint URI.
- The `-bare` option for cfssljson is needed to specify a prefix for the output key files.
:::
```console
cfssl sign -remote ":" -profile "ledger" ledger.csr | cfssljson -bare ledger -
```
You will get a certificate named `ledger.pem` from the CFSSL server. You can use that certificate for ScalarDL Ledger.
```console
cfssl sign -remote ":" -profile "auditor" auditor.csr | cfssljson -bare auditor -
```
You will get a certificate named `auditor.pem` from the CFSSL server. You can use that certificate for ScalarDL Auditor.
```console
cfssl sign -remote ":" -profile "client" client.csr | cfssljson -bare client -
```
You will get a certificate named `client.pem` from the CFSSL server. You can use that certificate for the clients.
You can use a third-party CA or your private CA to create a certificate file. For details on how to create a certificate file, please ask your preferred third-party CA or private CA.
================================================
FILE: docs/ca/caserver-getting-started.mdx
================================================
---
tags:
- Community
- Enterprise
displayed_sidebar: docsEnglish
---
# How to start CA server with CFSSL
This document describes how to start CA server with CFSSL.
## Prerequisites
We basically use CFSSL components for CA server and certificate handling.
- Golang (v1.8+) installation
- [cfssl & cfssljson](https://github.com/cloudflare/cfssl) installation
## Create a Root CA certificate
Create a CSR file in json format as follows.
```
[ca-csr.json]
{
"CN": "Sample Root CA",
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "JP",
"L": "Tokyo",
"O": "Sample Root CA",
"ST": "Tokyo"
}
]
}
```
Generate a self-signed certificate and a private key based on the CSR.
```console
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
ls
ca-csr.json ca-key.pem ca.csr ca.pem
```
## Create a database for storing certificates
it needs a database for storing keys/certificate information.
CFSSL currently supports MySQL, PostgreSQL and SQLite.
We use SQLite this time for simplicity.
```console
go get bitbucket.org/liamstask/goose/cmd/goose
goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/sqlite up
```
This will create a certstore_development.db in the current location.
## Create configration files for CA server
Configure signing algorithm, endpoint url and usages e imtermediate servers etc.
It assumes the server runs in a local environment only.
```
[cfssl-config.json]
{
"signing": {
"default": {
"ocsp_url": "http://localhost:8889",
"crl_url": "http://localhost:8888/crl",
"expiry": "26280h",
"usages": [
"signing",
"key encipherment",
"client auth"
]
},
"profiles": {
"ocsp": {
"usages": ["digital signature", "ocsp signing"],
"expiry": "26280h"
},
"intermediate": {
"usages": ["cert sign", "crl sign"],
"expiry": "26280h",
"ca_constraint": {"is_ca": true}
},
"server": {
"usages": ["signing", "key encipherment", "server auth"],
"expiry": "26280h"
},
"client": {
"usages": ["signing", "key encipherment", "client auth"],
"expiry": "26280h"
}
}
}
}
```
TODO: explore more about the configuration
Then, create a config file for database to point at the database file created in the previous section.
```
[db-config.json]
{
"driver":"sqlite3",
"data_source":"certstore_development.db"
}
```
### Create an intermediate CA certificate
This step is similar to generating root ca cert.
```
[server-ca.csr.json]
{
"CN": "Sample Intermediate CA",
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "JP",
"L": "Tokyo",
"O": "Sample Intermediate CA",
"ST": "Tokyo"
}
]
}
```
The main differences are specifying the Root CA (`-ca -ca-key`) and the cfssl config (`-cfssl-config`) instead of `-initca` option.
```console
cfssl gencert -ca ca.pem -ca-key ca-key.pem -config cfssl-config.json -profile "intermediate" server-ca.csr.json | cfssljson -bare ca-server
```
### Generate a OCSP server certificate
NOTE: OCSP is an internet protocol used for obtaining the revocation status of an X.509 digital certificate.
```
[ocsp.csr.json]
{
"CN": "Sample OCSP",
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "JP",
"L": "Tokyo",
"O": "Sample OCSP",
"ST": "Tokyo"
}
]
}
```
```console
cfssl gencert -ca ca-server.pem -ca-key ca-server-key.pem -config cfssl-config.json -profile "ocsp" ocsp.csr.json | cfssljson -bare server-ocsp
```
## Start servers
It's all ready now. Let's start the servers.
### CA server
```console
cfssl serve -db-config db-config.json -ca-key ca-server-key.pem -ca ca-server.pem -config cfssl-config.json -responder server-ocsp.pem -responder-key server-ocsp-key.pem
```
### OCSP server
```console
cfssl ocsprefresh -db-config db-config.json -responder server-ocsp.pem -responder-key server-ocsp-key.pem -ca ca-server.pem
// Bundle the Root CA and Intermediate CA
cat ca.pem ca-server.pem | tee bundle.pem
// Pre-generate the OCSP response
cfssl ocspdump -db-config db-config.json > ocspdump.txt
// Start the server
cfssl ocspserve -port=8889 -responses=ocspdump.txt
```
## References
- [cfssl & cfssljson](https://github.com/cloudflare/cfssl)
- [Setup Cloudflare CFSSL with OCSP responder](https://medium.com/@vrmvrm/setup-cloudflare-cfssl-with-ocsp-responder-aba44b4134e6)
- [Revoking certificates and running OCSP responder](https://propellered.com/2017/11/19/cfssl_revoking_certs_ocsp_reponder/)
================================================
FILE: docs/helm-charts/configure-custom-values-envoy.mdx
================================================
---
tags:
- Enterprise Standard
- Enterprise Premium
displayed_sidebar: docsEnglish
---
# Configure a custom values file for Scalar Envoy
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import CertificateManagement from '/src/components/en-us/_certificate-management.mdx';
This document explains how to create your custom values file for the Scalar Envoy chart. If you want to know the details of the parameters, please refer to the [README](https://github.com/scalar-labs/helm-charts/blob/main/charts/envoy/README.md) of the Scalar Envoy chart.
## Configure custom values for Scalar Envoy chart
The Scalar Envoy chart is used via other charts (scalardb, scalardb-cluster, scalardl, and scalardl-audit), so you don't need to create a custom values file for the Scalar Envoy chart. If you want to configure Scalar Envoy, you need to add the `envoy.*` configuration to the other charts.
For example, if you want to configure the Scalar Envoy for ScalarDB Server, you can configure some Scalar Envoy configurations in the custom values file of ScalarDB as follows.
* Example (scalardb-custom-values.yaml)
```yaml
envoy:
configurationsForScalarEnvoy:
...
scalardb:
configurationsForScalarDB:
...
```
## Required configurations
### Service configurations
You must set `envoy.service.type` to specify the Service resource type of Kubernetes.
If you accept client requests from inside of the Kubernetes cluster only (for example, if you deploy your client applications on the same Kubernetes cluster as Scalar products), you can set `envoy.service.type` to `ClusterIP`. This configuration doesn't create any load balancers provided by cloud service providers.
```yaml
envoy:
service:
type: ClusterIP
```
If you want to use a load balancer provided by a cloud service provider to accept client requests from outside of the Kubernetes cluster, you need to set `envoy.service.type` to `LoadBalancer`.
```yaml
envoy:
service:
type: LoadBalancer
```
If you want to configure the load balancer via annotations, you can also set annotations to `envoy.service.annotations`.
```yaml
envoy:
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-internal: "true"
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
```
## Optional configurations
### Resource configurations (Recommended in the production environment)
If you want to control pod resources using the requests and limits of Kubernetes, you can use `envoy.resources`.
You can configure them using the same syntax as the requests and limits of Kubernetes. So, please refer to the official document [Resource Management for Pods and Containers](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for more details on the requests and limits of Kubernetes.
```yaml
envoy:
resources:
requests:
cpu: 1000m
memory: 2Gi
limits:
cpu: 2000m
memory: 4Gi
```
### Affinity configurations (Recommended in the production environment)
If you want to control pod deployment using the affinity and anti-affinity of Kubernetes, you can use `envoy.affinity`.
You can configure them using the same syntax as the affinity of Kubernetes. So, please refer to the official document [Assigning Pods to Nodes](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) for more details on the affinity configuration of Kubernetes.
```yaml
envoy:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- scalardb-cluster
- key: app.kubernetes.io/app
operator: In
values:
- envoy
topologyKey: kubernetes.io/hostname
weight: 50
```
### Prometheus and Grafana configurations (Recommended in production environments)
If you want to monitor Scalar Envoy pods using [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack), you can deploy a ConfigMap, a ServiceMonitor, and a PrometheusRule resource for kube-prometheus-stack using `envoy.grafanaDashboard.enabled`, `envoy.serviceMonitor.enabled`, and `envoy.prometheusRule.enabled`.
```yaml
envoy:
grafanaDashboard:
enabled: true
namespace: monitoring
serviceMonitor:
enabled: true
namespace: monitoring
interval: 15s
prometheusRule:
enabled: true
namespace: monitoring
```
### SecurityContext configurations (Default value is recommended)
If you want to set SecurityContext and PodSecurityContext for Scalar Envoy pods, you can use `envoy.securityContext` and `envoy.podSecurityContext`.
You can configure them using the same syntax as SecurityContext and PodSecurityContext of Kubernetes. So, please refer to the official document [Configure a Security Context for a Pod or Container](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for more details on the SecurityContext and PodSecurityContext configurations of Kubernetes.
```yaml
envoy:
podSecurityContext:
seccompProfile:
type: RuntimeDefault
securityContext:
capabilities:
drop:
- ALL
runAsNonRoot: true
allowPrivilegeEscalation: false
```
### Image configurations (Default value is recommended)
If you want to change the image repository and version, you can use `envoy.image.repository` to specify the container repository information of the Scalar Envoy container image that you want to pull.
```yaml
envoy:
image:
repository:
```
If you're using AWS, refer to [How to install Scalar products through AWS Marketplace](../scalar-kubernetes/AwsMarketplaceGuide.mdx).
### TLS configurations (optional based on your environment)
You can enable TLS in:
- Downstream connections between the client and Scalar Envoy.
- Upstream connections between Scalar Envoy and Scalar products.
#### Enable TLS in downstream connections
You can enable TLS in downstream connections by using the following configurations:
```yaml
envoy:
tls:
downstream:
enabled: true
```
##### Use your private key and certificate files
You can set your private key and certificate files by using the following configurations:
```yaml
envoy:
tls:
downstream:
enabled: true
certChainSecret: "envoy-tls-cert"
privateKeySecret: "envoy-tls-key"
```
In this case, you have to create secret resources that include private key and certificate files for Scalar Envoy as follows, replacing the contents in the angle brackets as described:
```console
kubectl create secret generic envoy-tls-cert --from-file=tls.crt=/ -n
kubectl create secret generic envoy-tls-key --from-file=tls.key=/ -n
```
For more details on how to prepare private key and certificate files, see [How to create private key and certificate files for Scalar products](../scalar-kubernetes/HowToCreateKeyAndCertificateFiles.mdx).
##### Use a trusted CA with cert-manager to manage your private key and certificate files
You can manage your private key and certificate files with cert-manager by using the following configurations, replacing the content in the angle brackets as described:
:::note
* If you want to use cert-manager, you must deploy cert-manager and prepare the `Issuers` resource. For details, see the cert-manager documentation, [Installation](https://cert-manager.io/docs/installation/) and [Issuer Configuration](https://cert-manager.io/docs/configuration/).
* By default, Scalar Helm Chart creates a `Certificate` resource that satisfies the certificate requirements of Scalar products. The default certificate configuration is recommended, but if you use a custom certificate configuration, you must satisfy the certificate requirements of Scalar products. For details, see [How to create private key and certificate files for Scalar products](../scalar-kubernetes/HowToCreateKeyAndCertificateFiles.mdx#certificate-requirements).
:::
```yaml
envoy:
tls:
downstream:
enabled: true
certManager:
enabled: true
issuerRef:
name:
dnsNames:
- envoy.scalar.example.com
```
In this case, cert-manager issues your private key and certificate files by using your trusted issuer. By using cert-manager, you don't need to mount your private key and certificate files manually.
##### Use a self-signed CA with cert-manager to manage your private key and certificate files
You can manage your private key and self-signed certificate files with cert-manager by using the following configurations:
:::note
* If you want to use cert-manager, you must deploy cert-manager. For details, see the cert-manager documentation, [Installation](https://cert-manager.io/docs/installation/).
* By default, Scalar Helm Chart creates a `Certificate` resource that satisfies the certificate requirements of Scalar products. The default certificate configuration is recommended, but if you use a custom certificate configuration, you must satisfy the certificate requirements of Scalar products. For details, see [How to create private key and certificate files for Scalar products](../scalar-kubernetes/HowToCreateKeyAndCertificateFiles.mdx#certificate-requirements).
:::
```yaml
envoy:
tls:
downstream:
enabled: true
certManager:
enabled: true
selfSigned:
enabled: true
dnsNames:
- envoy.scalar.example.com
```
In this case, Scalar Helm Charts and cert-manager issue your private key and self-signed certificate files. You don't need to mount your private key and certificate files manually.
#### Enable TLS in upstream connections
You can enable TLS in upstream connections by using the following configurations:
```yaml
envoy:
tls:
upstream:
enabled: true
```
Also, you must set root CA certificate file of upstream Scalar products. To determine which approach you should take, refer to the following decision tree:
```mermaid
flowchart TD
A[Are you using cert-manager?]
A -->|Yes| B
A -->|No| D
B[Are you using a self-signed CA with cert-manager?]
B -->|No| C[Are you using the same trusted CA for Envoy and
upstream Scalar products with cert-manager?]
C -->|No| D[You must set upstream Scalar products'
root CA certificate manually.]
C ---->|Yes| E[Scalar Helm Chart automatically sets the root CA certificate. You
don't need to set `envoy.tls.upstream.caRootCertSecret` explicitly.]
B ---->|Yes| E
```
##### Set your root CA certificate file of upstream Scalar products
You can set your root CA certificate file by using the following configurations:
```yaml
envoy:
tls:
upstream:
enabled: true
caRootCertSecret: "envoy-upstream-scalardb-cluster-root-ca"
```
In this case, you have to create secret resources that include CA certificate files as follows. You must set the root CA certificate file based on the upstream that you use (ScalarDB Cluster, ScalarDL Ledger, or ScalarDL Auditor). Be sure to replace the contents in the angle brackets as described.
```console
kubectl create secret generic envoy-upstream-scalardb-cluster-root-ca --from-file=ca.crt=/ -n
```
```console
kubectl create secret generic envoy-upstream-scalardl-ledger-root-ca --from-file=ca.crt=/ -n
```
```console
kubectl create secret generic envoy-upstream-scalardl-auditor-root-ca --from-file=ca.crt=/ -n
```
For more details on how to prepare private key and certificate files, see [How to create key and certificate files for Scalar products](../scalar-kubernetes/HowToCreateKeyAndCertificateFiles.mdx).
##### Set custom authority for TLS communications
You can set the custom authority for TLS communications by using `envoy.tls.upstream.overrideAuthority`. This value doesn't change what host is actually connected. This value is intended for testing but may safely be used outside of tests as an alternative to DNS overrides. For example, you can specify the hostname presented in the certificate chain file that you set by using `scalardbCluster.tls.certChainSecret`, `ledger.tls.certChainSecret`, or `auditor.tls.certChainSecret`, depending on which product you're using. Envoy uses this value for verifying the certificate of the TLS connection with ScalarDB Cluster or ScalarDL.
```yaml
envoy:
tls:
upstream:
enabled: true
overrideAuthority: "cluster.scalardb.example.com"
```
### Replica configurations (Optional based on your environment)
You can specify the number of replicas (pods) of Scalar Envoy using `envoy.replicaCount`.
```yaml
envoy:
replicaCount: 3
```
### Taint and toleration configurations (Optional based on your environment)
If you want to control pod deployment by using the taints and tolerations in Kubernetes, you can use `envoy.tolerations`.
You can configure taints and tolerations by using the same syntax as the tolerations in Kubernetes. For details on configuring tolerations in Kubernetes, see the official Kubernetes documentation [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/).
```yaml
envoy:
tolerations:
- effect: NoSchedule
key: scalar-labs.com/dedicated-node
operator: Equal
value: scalardb
```
================================================
FILE: docs/helm-charts/configure-custom-values-file.mdx
================================================
---
tags:
- Enterprise Standard
- Enterprise Premium
displayed_sidebar: docsEnglish
---
# Configure a custom values file for Scalar Helm Charts
When you deploy Scalar products using Scalar Helm Charts, you must prepare your custom values file based on your environment. Please refer to the following documents for more details on how to a create custom values file for each product.
* [ScalarDB Cluster](configure-custom-values-scalardb-cluster.mdx)
* [ScalarDL Ledger](configure-custom-values-scalardl-ledger.mdx)
* [ScalarDL Auditor](configure-custom-values-scalardl-auditor.mdx)
* [ScalarDL Schema Loader](configure-custom-values-scalardl-schema-loader.mdx)
* [Scalar Admin for Kubernetes](configure-custom-values-scalar-admin-for-kubernetes.mdx)
* [Scalar Manager](configure-custom-values-scalar-manager.mdx)
* [Envoy](configure-custom-values-envoy.mdx)
* [[Deprecated] ScalarDB Server](configure-custom-values-scalardb.mdx)
* [[Deprecated] ScalarDB GraphQL](configure-custom-values-scalardb-graphql.mdx)
================================================
FILE: docs/helm-charts/configure-custom-values-scalar-admin-for-kubernetes.mdx
================================================
---
tags:
- Enterprise Standard
- Enterprise Premium
displayed_sidebar: docsEnglish
---
# Configure a custom values file for Scalar Admin for Kubernetes
This document explains how to create your custom values file for the Scalar Admin for Kubernetes chart. For details on the parameters, see the [README](https://github.com/scalar-labs/helm-charts/blob/main/charts/scalar-admin-for-kubernetes/README.md) of the Scalar Admin for Kubernetes chart.
## Required configurations
This section explains the required configurations when setting up a custom values file for Scalar Admin for Kubernetes.
### Flag configurations
You must specify several flags to `scalarAdminForKubernetes.commandArgs` as an array to run Scalar Admin for Kubernetes. For more details on the flags, see [README](https://github.com/scalar-labs/scalar-admin-for-kubernetes/blob/main/README.md) of Scalar Admin for Kubernetes.
```yaml
scalarAdminForKubernetes:
commandArgs:
- -r
-
- -n
-
- -d
-
- -z
-
```
## Optional configurations
This section explains the optional configurations when setting up a custom values file for Scalar Admin for Kubernetes.
### CronJob configurations (optional based on your environment)
By default, the Scalar Admin for Kubernetes chart creates a [Job](https://kubernetes.io/docs/concepts/workloads/controllers/job/) resource to run the Scalar Admin for Kubernetes CLI tool once. If you want to run the Scalar Admin for Kubernetes CLI tool periodically by using [CronJob](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/), you can set `scalarAdminForKubernetes.jobType` to `cronjob`. Also, you can set some configurations for the CronJob resource.
```yaml
scalarAdminForKubernetes:
cronJob:
timeZone: "Etc/UTC"
schedule: "0 0 * * *"
```
### Resource configurations (recommended in production environments)
To control pod resources by using requests and limits in Kubernetes, you can use `scalarAdminForKubernetes.resources`.
You can configure requests and limits by using the same syntax as requests and limits in Kubernetes. For more details on requests and limits in Kubernetes, see [Resource Management for Pods and Containers](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/).
```yaml
scalarAdminForKubernetes:
resources:
requests:
cpu: 1000m
memory: 2Gi
limits:
cpu: 2000m
memory: 4Gi
```
### SecurityContext configurations (default value is recommended)
To set SecurityContext and PodSecurityContext for Scalar Admin for Kubernetes pods, you can use `scalarAdminForKubernetes.securityContext` and `scalarAdminForKubernetes.podSecurityContext`.
You can configure SecurityContext and PodSecurityContext by using the same syntax as SecurityContext and PodSecurityContext in Kubernetes. For more details on the SecurityContext and PodSecurityContext configurations in Kubernetes, see [Configure a Security Context for a Pod or Container](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/).
```yaml
scalarAdminForKubernetes:
podSecurityContext:
seccompProfile:
type: RuntimeDefault
securityContext:
capabilities:
drop:
- ALL
runAsNonRoot: true
allowPrivilegeEscalation: false
```
### Image configurations (default value is recommended)
If you want to change the image repository, you can use `scalarAdminForKubernetes.image.repository` to specify the container repository information of the Scalar Admin for Kubernetes image that you want to pull.
```yaml
scalarAdminForKubernetes:
image:
repository:
```
### Taint and toleration configurations (optional based on your environment)
If you want to control pod deployment by using taints and tolerations in Kubernetes, you can use `scalarAdminForKubernetes.tolerations`.
You can configure taints and tolerations by using the same syntax as the tolerations in Kubernetes. For details on configuring tolerations in Kubernetes, see the official Kubernetes documentation [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/).
```yaml
scalarAdminForKubernetes:
tolerations:
- effect: NoSchedule
key: scalar-labs.com/dedicated-node
operator: Equal
value: scalardb-cluster
```
### TLS configurations (optional based on your environment)
You can enable TLS between Scalar Admin for Kubernetes and the pause targets (ScalarDB Cluster or ScalarDL) by using the following configurations:
```yaml
scalarAdminForKubernetes:
commandArgs:
- (omit other options)
- --tls
- --ca-root-cert-path
- /tls/certs/ca.crt
- --override-authority
- cluster.scalardb.example.com
```
You can mount the `/tls/certs/ca.crt` file on a pod by using a secret resource. To mount the file, specify the name of the secret resource that includes the root CA certificate file to `scalarAdminForKubernetes.tls.caRootCertSecret` as follows:
```yaml
scalarAdminForKubernetes:
tls:
caRootCertSecret: "scalar-admin-tls-ca"
```
In this case, you have to create a secret resource that includes the root CA certificate file for the pause targets (ScalarDB Cluster or ScalarDL) as follows:
```console
kubectl create secret generic scalar-admin-tls-ca --from-file=ca.crt=/path/to/your/ca/certificate/file -n
```
================================================
FILE: docs/helm-charts/configure-custom-values-scalar-manager.mdx
================================================
---
tags:
- Enterprise Option
displayed_sidebar: docsEnglish
---
# Configure a Custom Values File for Scalar Manager
This document provides instructions on how to configure a custom values file for the Scalar Manager Helm Chart. For details about the available parameters, see the [README](https://github.com/scalar-labs/helm-charts/blob/main/charts/scalar-manager/README.md) in the Scalar Manager chart repository.
## Required configurations
This section describes the service, image, and Scalar Manager configurations that you must include in the Scalar Manager values file.
### Service configurations
You must configure `web.service.type` to define the Kubernetes Service resource type. To use a load balancer that cloud service providers offer for exposing the service, set `web.service.type` to `LoadBalancer`.
```yaml
web:
service:
type: LoadBalancer
# other web configurations
```
#### Security considerations for exposing Scalar Manager
Setting `web.service.type` to `LoadBalancer` exposes Scalar Manager externally via `HTTP` by default, which creates security risks on untrusted networks due to unencrypted traffic. If external access is not required, using a private network or properly configuring network access to your Kubernetes cluster is recommended.
Scalar Manager supports authentication and authorization mechanisms. You can configure these mechanisms to ensure authorized actions for features like scheduling jobs to pause Scalar products. For details, see [Authentication configuration for Scalar Manager](#authentication-configuration-for-scalar-manager).
### Container image configurations
You must configure `api.image.repository` and `web.image.repository`. These settings specify the Scalar Manager container images, ensuring you can pull them from the container repository.
```yaml
api:
image:
repository:
web:
image:
repository:
```
## Optional configurations
This section describes optional configurations for customizing the Scalar Manager values file.
### Scalar Manager configurations (optional based on your environment)
You can override the `api.applicationProperties` setting to modify the default Scalar Manager configurations.
```yaml
api:
applicationProperties: |
prometheus.kubernetes-service-label-name="app"
prometheus.kubernetes-service-label-value="kube-prometheus-stack-prometheus"
prometheus.kubernetes-service-port-name="http-web"
# other application properties
```
Scalar Manager includes default configurations to discover Scalar product deployments and the Prometheus service within the cluster. In most scenarios, especially when following the guides to deploy `kube-prometheus-stack` and `loki-stack`, these default configurations are sufficient and do not require modification.
#### Configurable properties in `api.applicationProperties`
The configurations for Scalar Manager are in the format of Java application properties, which are `key=value` pairs. These application properties can be set by using the `api.applicationProperties` custom value in the Scalar Manager Helm Chart.
| Name | Description | Default Value |
|:--------------------------------------------------------------------|:----------------------------------------------------------------------------|:---------------------------------------------------------------------------|
| `prometheus.kubernetes-service-label-name` | The label name used to discover the Prometheus service in Kubernetes | `app` |
| `prometheus.kubernetes-service-label-value` | The label value corresponding to `prometheus.kubernetes-service-label-name` | `kube-prometheus-stack-prometheus` |
| `prometheus.kubernetes-service-port-name` | The port name used to discover the Prometheus service port in Kubernetes | `http-web` |
| `springdoc.swagger-ui.enabled` | Whether to enable the Swagger UI or not | `false` |
| `springdoc.swagger-ui.path` | The path of the Swagger UI | `/swagger-ui.html` |
| `app.cors.allowed-origins` | The allowed origins for CORS | `*` |
| `app.cors.allowed-methods` | The allowed methods for CORS | `*` |
| `app.cors.allowed-headers` | The allowed headers for CORS | `*` |
| `authentication.providers.static-jwt.secret` | Secret key used for signing JWT tokens; minimum 32 characters | `example-jwt-secret-with-minimum-32-characters` |
| `authentication.providers.static-jwt.issuer-uri` | The issuer URI of the JWT tokens | `https://scalar-manager.example.com` |
| `authentication.providers.static-jwt.access-token-expiration-time` | The expiration time of the access token | `1h` |
| `authentication.providers.static-jwt.refresh-token-expiration-time` | The expiration time of the refresh token | `3d` |
| `app.initial-admin-user.enabled` | Whether to enable the initial admin user or not | `true` |
| `app.initial-admin-user.email` | The email address of the initial admin user | `admin@example.com` |
| `app.initial-admin-user.name` | The name of the initial admin user | `Administrator` |
| `app.initial-admin-user.password` | The password of the initial admin user | `Password@123!` |
| `spring.jpa.hibernate.ddl-auto` | The DDL mode for Hibernate | `update` |
| `spring.jpa.show-sql` | Whether to show the SQL query | `false` |
| `spring.jpa.properties.hibernate.format_sql` | Whether to format the SQL query | `false` |
| `spring.datasource.url` | The URL of the database | `jdbc:postgresql://scalar-manager-postgres-postgresql:5432/scalar-manager` |
| `spring.datasource.username` | The username of the database | `scalar-manager` |
| `spring.datasource.password` | The password of the database | `scalar-manager` |
| `spring.datasource.driver-class-name` | The driver class name of the database | `org.postgresql.Driver` |
:::note
There are more configurations that you can set in `api.applicationProperties` regarding the JPA, Hibernate, and Spring Data. If you're familiar with these configurations, you can set them to customize the database connection and the behavior of Scalar Manager.
:::
##### Authentication configuration for Scalar Manager
By default, to access Scalar Manager, you need to authenticate by using a username and password.
The following are the prerequisites for setting up authentication:
- You need to have a PostgreSQL database, either your own or one that a cloud service provider hosts. For example, you can use the [Bitnami package for PostgreSQL](https://artifacthub.io/packages/helm/bitnami/postgresql) to deploy a PostgreSQL database in your Kubernetes cluster.
- You must set the `authentication.providers.static-jwt.secret` configuration. This configuration is used for signing JWT tokens, and the minimum length of the secret is 32 characters.
The following is an example of the additional configurations you need to set in the `api.applicationProperties` to apply the above prerequisites. Be sure to change the configurations to match your environment.
```properties
# JWT configuration
# Secret key used for signing JWT tokens, minimum 32 characters
authentication.providers.static-jwt.secret=${AUTHENTICATION_PROVIDERS_STATIC_JWT_SECRET:example-jwt-secret-with-minimum-32-characters}
authentication.providers.static-jwt.issuer-uri=${AUTHENTICATION_PROVIDERS_STATIC_JWT_ISSUER_URI:https://scalar-manager.example.com}
authentication.providers.static-jwt.access-token-expiration-time=${AUTHENTICATION_PROVIDERS_STATIC_JWT_ACCESS_TOKEN_EXPIRATION_TIME:1h}
authentication.providers.static-jwt.refresh-token-expiration-time=${AUTHENTICATION_PROVIDERS_STATIC_JWT_REFRESH_TOKEN_EXPIRATION_TIME:3d}
# Initial admin configuration
app.initial-admin-user.enabled=${APP_INITIAL_ADMIN_USER_ENABLED:true}
app.initial-admin-user.email=${APP_INITIAL_ADMIN_USER_EMAIL:admin@example.com}
app.initial-admin-user.name=${APP_INITIAL_ADMIN_USER_NAME:Administrator}
app.initial-admin-user.password=${APP_INITIAL_ADMIN_USER_PASSWORD:Password@123!}
# JPA configuration
spring.jpa.hibernate.ddl-auto=${SPRING_JPA_HIBERNATE_DDL_AUTO:update}
spring.jpa.show-sql=${SPRING_JPA_SHOW_SQL:false}
spring.jpa.properties.hibernate.format_sql=${SPRING_JPA_PROPERTIES_HIBERNATE_FORMAT_SQL:false}
# Database configuration
spring.datasource.url=jdbc:postgresql://${DATABASE_HOST:scalar-manager-postgres-postgresql}:${DATABASE_PORT:5432}/${DATABASE_NAME:scalar-manager}
spring.datasource.username=${DATABASE_USERNAME:scalar-manager}
spring.datasource.password=${DATABASE_PASSWORD:scalar-manager}
spring.datasource.driver-class-name=org.postgresql.Driver
```
##### Service discovery
Scalar Manager uses labels to discover the Prometheus service in Kubernetes, and then uses the port name to connect to them. You can modify the labels and the port name by setting the `prometheus.kubernetes-service-label-name`, `prometheus.kubernetes-service-label-value`, and `prometheus.kubernetes-service-port-name` configurations.
In general, you don't need to modify these configurations. However, if you customized the labels or port names of the Prometheus service when installing their Helm Charts, you should adjust these configurations to match your customizations.
#### Configurable environment variables in `web.env`
| Name | Description | Default Value |
|:---------------------|:---------------------------------------------------------|:---------------------------------------------------------------------|
| `GRAFANA_SERVER_URL` | The URL of the Grafana service in the Kubernetes cluster | `http://scalar-monitoring-grafana.monitoring.svc.cluster.local:3000` |
Currently, the `GRAFANA_SERVER_URL` variable can be set in `web.env` to customize the proxy from the Scalar Manager web UI to the Grafana UI. By default, the variable is set to the Grafana service `scalar-monitoring-grafana` installed in the `monitoring` namespace. If you have installed Grafana in different namespace or have changed the name of the Grafana service, you will need to update the `GRAFANA_SERVER_URL` variable accordingly.
================================================
FILE: docs/helm-charts/configure-custom-values-scalardb-analytics-server.mdx
================================================
---
tags:
- Enterprise Option
displayed_sidebar: docsEnglish
---
# Configure a custom values file for ScalarDB Analytics server
import CertificateManagement from '/src/components/en-us/_certificate-management.mdx';
This document explains how to create your custom values file for the ScalarDB Analytics server chart. For details on the parameters, see the [README](https://github.com/scalar-labs/helm-charts/blob/main/charts/scalardb-analytics-server/README.md) of the ScalarDB Analytics server chart.
## Required configurations
This section describes the required image, database, and service configurations.
### Image configurations
You must set `scalarDbAnalyticsServer.image.repository`. Be sure to specify the ScalarDB Analytics server container image so that you can pull the image from the container repository.
```yaml
scalarDbAnalyticsServer:
image:
repository:
```
### Database configurations
You must set `scalarDbAnalyticsServer.properties`. For details about configuring the value of this parameter, see [ScalarDB Analytics server configuration](https://scalardb.scalar-labs.com/docs/latest/scalardb-analytics/configuration).
```yaml
scalarDbAnalyticsServer:
properties: |
scalar.db.analytics.server.db.url=jdbc:postgresql://localhost:5432/scalardb_analytics
scalar.db.analytics.server.db.username=analytics_user
scalar.db.analytics.server.db.password=your_secure_password
```
### Service configurations
You must set `scalarDbAnalyticsServer.service.type` to specify the Service resource type of Kubernetes.
If the ScalarDB Analytics server accepts client requests from inside of the Kubernetes cluster only (for example, if you deploy your client applications on the same Kubernetes cluster as Scalar products), you can set `scalarDbAnalyticsServer.service.type` to `ClusterIP`. This configuration doesn't create any load balancers provided by cloud service providers.
```yaml
scalarDbAnalyticsServer:
service:
type: ClusterIP
```
If you want to use a load balancer provided by a cloud service provider to accept client requests from outside of the Kubernetes cluster, you need to set `scalarDbAnalyticsServer.service.type` to `LoadBalancer`.
```yaml
scalarDbAnalyticsServer:
service:
type: LoadBalancer
```
If you want to configure the load balancer via annotations, you can also set annotations to `scalarDbAnalyticsServer.service.annotations`.
```yaml
scalarDbAnalyticsServer:
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-internal: "true"
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
```
## Optional configurations
This section describes the optional configurations.
### Secret configurations (recommended in production environments)
To use environment variables to set some properties (for example, credentials), you can use `scalarDbAnalyticsServer.secretName` to specify the Secret resource that includes some credentials.
For example, you can set credentials for a backend database (`scalar.db.analytics.server.db.username` and `scalar.db.analytics.server.db.password`) by using environment variables, which makes your pods more secure.
```yaml
scalarDbAnalyticsServer:
secretName: "scalardb-analytics-server-credentials-secret"
```
:::tip
The ScalarDB Analytics server automatically loads configurations from specific environment variables. The naming rule for the environment variables is as follows:
- Capitalize all characters of the property name.
- Replace periods (`.`) with underscores (`_`).
For example, if you want to set `scalar.db.analytics.server.db.username` and `scalar.db.analytics.server.db.password` via environment variables, you must set environment variables `SCALAR_DB_ANALYTICS_SERVER_DB_USERNAME` and `SCALAR_DB_ANALYTICS_SERVER_DB_PASSWORD`.
In this case, you don't need to set `scalar.db.analytics.server.db.username` and `scalar.db.analytics.server.db.password` in `scalarDbAnalyticsServer.properties`. Setting only the environment variables is enough.
For example, you can create such a secret resource that includes `SCALAR_DB_ANALYTICS_SERVER_DB_USERNAME` and `SCALAR_DB_ANALYTICS_SERVER_DB_PASSWORD` as follows:
```console
kubectl create secret generic scalardb-analytics-server-credentials-secret \
--from-literal=SCALAR_DB_ANALYTICS_SERVER_DB_USERNAME=analytics_user \
--from-literal=SCALAR_DB_ANALYTICS_SERVER_DB_PASSWORD=your_secure_password
```
:::
### SecurityContext configurations (the default value is recommended)
To set SecurityContext and PodSecurityContext for ScalarDB Analytics server pods, you can use `scalarDbAnalyticsServer.securityContext` and `scalarDbAnalyticsServer.podSecurityContext`.
You can configure SecurityContext and PodSecurityContext by using the same syntax as SecurityContext and PodSecurityContext in Kubernetes. For more details on the SecurityContext and PodSecurityContext configurations in Kubernetes, see [Configure a Security Context for a Pod or Container](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/).
```yaml
scalarDbAnalyticsServer:
podSecurityContext:
seccompProfile:
type: RuntimeDefault
securityContext:
capabilities:
drop:
- ALL
runAsNonRoot: true
allowPrivilegeEscalation: false
```
### TLS configurations (optional based on your environment)
You can enable TLS in:
- The communications between the ScalarDB Analytics server and its client.
#### Enable TLS
You can enable TLS in all ScalarDB Analytics server connections by using the following configurations:
```yaml
scalarDbAnalyticsServer:
properties: |
...(omit)...
scalar.db.analytics.server.tls.enabled=true
scalar.db.analytics.server.tls.cert_chain_path=/tls/scalardb-analytics-server/certs/tls.crt
scalar.db.analytics.server.tls.private_key_path=/tls/scalardb-analytics-server/certs/tls.key
tls:
enabled: true
```
:::note
Based on the specification of the private key and certificate that are created by cert-manager and the specification of this chart, you must set the fixed file path and file name when you enable the TLS feature. Please set the above file paths and file names as is for `scalar.db.analytics.server.tls.cert_chain_path` and `scalar.db.analytics.server.tls.private_key_path`.
:::
##### Use your private key and certificate files
You can set your private key and certificate files by using the following configurations:
```yaml
scalarDbAnalyticsServer:
tls:
enabled: true
caRootCertSecret: "scalardb-analytics-server-tls-ca"
certChainSecret: "scalardb-analytics-server-tls-cert"
privateKeySecret: "scalardb-analytics-server-tls-key"
```
In this case, you have to create secret resources that include private key and certificate files for the ScalarDB Analytics server as follows, replacing the contents in the angle brackets as described:
```console
kubectl create secret generic scalardb-analytics-server-tls-ca --from-file=ca.crt= -n
kubectl create secret generic scalardb-analytics-server-tls-cert --from-file=tls.crt= -n
kubectl create secret generic scalardb-analytics-server-tls-key --from-file=tls.key= -n
```
For more details on how to prepare private key and certificate files, see [How to create private key and certificate files for Scalar products](../scalar-kubernetes/HowToCreateKeyAndCertificateFiles.mdx).
##### Use a trusted CA with cert-manager to manage your private key and certificate files
You can manage your private key and certificate files with cert-manager by using the following configurations, replacing the content in the angle brackets as described:
:::note
* If you want to use cert-manager, you must deploy cert-manager and prepare the `Issuers` resource. For details, see the cert-manager documentation, [Installation](https://cert-manager.io/docs/installation/) and [Issuer Configuration](https://cert-manager.io/docs/configuration/).
* By default, Scalar Helm Chart creates a `Certificate` resource that satisfies the certificate requirements of Scalar products. The default certificate configuration is recommended, but if you use a custom certificate configuration, you must satisfy the certificate requirements of Scalar products. For details, see [How to create private key and certificate files for Scalar products](../scalar-kubernetes/HowToCreateKeyAndCertificateFiles.mdx#certificate-requirements).
:::
```yaml
scalarDbAnalyticsServer:
tls:
enabled: true
certManager:
enabled: true
issuerRef:
name:
dnsNames:
- server.analytics.scalardb.example.com
```
In this case, cert-manager issues your private key and certificate files by using your trusted issuer. You don't need to mount your private key and certificate files manually.
##### Use a self-signed CA with cert-manager to manage your private key and certificate files
You can manage your private key and self-signed certificate files with cert-manager by using the following configurations:
:::note
* If you want to use cert-manager, you must deploy cert-manager. For more details on how to deploy cert-manager, see [Installation](https://cert-manager.io/docs/installation/) in the official documentation for cert-manager.
* By default, Scalar Helm Chart creates a `Certificate` resource that satisfies the certificate requirements of Scalar products. The default certificate configuration is recommended, but if you use a custom certificate configuration, you must satisfy the certificate requirements of Scalar products. See [How to create private key and certificate files for Scalar products](../scalar-kubernetes/HowToCreateKeyAndCertificateFiles.mdx#certificate-requirements).
:::
```yaml
scalarDbAnalyticsServer:
tls:
enabled: true
certManager:
enabled: true
selfSigned:
enabled: true
dnsNames:
- server.analytics.scalardb.example.com
```
In this case, Scalar Helm Charts and cert-manager issue your private key and self-signed certificate files. You don't need to mount your private key and certificate files manually.
##### Set custom authority for TLS communications
You can set the custom authority for TLS communications by using `scalarDbAnalyticsServer.tls.overrideAuthority`. This value doesn't change what host is actually connected. This value is intended for testing but may safely be used outside of tests as an alternative to DNS overrides. For example, you can specify the hostname presented in the certificate chain file that you set by using `scalarDbAnalyticsServer.tls.certChainSecret`. This chart uses this value for health check requests (`startupProbe` and `livenessProbe`).
```yaml
scalarDbAnalyticsServer:
tls:
enabled: true
overrideAuthority: "server.analytics.scalardb.example.com"
```
### Affinity configurations (optional based on your environment)
To control pod deployment by using affinity and anti-affinity in Kubernetes, you can use `scalarDbAnalyticsServer.affinity`.
You can configure affinity and anti-affinity by using the same syntax for affinity and anti-affinity in Kubernetes. For more details on configuring affinity in Kubernetes, see [Assigning Pods to Nodes](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/).
```yaml
scalarDbAnalyticsServer:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- scalardb-analytics-server
- key: app.kubernetes.io/app
operator: In
values:
- scalardb-analytics-server
topologyKey: kubernetes.io/hostname
weight: 50
```
### Taint and toleration configurations (optional based on your environment)
If you want to control pod deployment by using the taints and tolerations in Kubernetes, you can use `scalarDbAnalyticsServer.tolerations`.
You can configure taints and tolerations by using the same syntax as the tolerations in Kubernetes. For details on configuring tolerations in Kubernetes, see the official Kubernetes documentation [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/).
```yaml
scalarDbAnalyticsServer:
tolerations:
- effect: NoSchedule
key: scalar-labs.com/dedicated-node
operator: Equal
value: scalardb-analytics-server
```
================================================
FILE: docs/helm-charts/configure-custom-values-scalardb-cluster.mdx
================================================
---
tags:
- Enterprise Standard
- Enterprise Premium
displayed_sidebar: docsEnglish
---
# Configure a custom values file for ScalarDB Cluster
import CertificateManagement from '/src/components/en-us/_certificate-management.mdx';
This document explains how to create your custom values file for the ScalarDB Cluster chart. For details on the parameters, see the [README](https://github.com/scalar-labs/helm-charts/blob/main/charts/scalardb-cluster/README.md) of the ScalarDB Cluster chart.
## Required configurations
### Image configurations
You must set `scalardbCluster.image.repository`. Be sure to specify the ScalarDB Cluster container image so that you can pull the image from the container repository.
```yaml
scalardbCluster:
image:
repository:
```
### Database configurations
You must set `scalardbCluster.scalardbClusterNodeProperties`. Please set `scalardb-cluster-node.properties` to this parameter. For more details on the configurations of ScalarDB Cluster, see [ScalarDB Cluster Configurations](https://scalardb.scalar-labs.com/docs/latest/scalardb-cluster/scalardb-cluster-configurations/).
```yaml
scalardbCluster:
scalardbClusterNodeProperties: |
scalar.db.cluster.membership.type=KUBERNETES
scalar.db.cluster.membership.kubernetes.endpoint.namespace_name=${env:SCALAR_DB_CLUSTER_MEMBERSHIP_KUBERNETES_ENDPOINT_NAMESPACE_NAME}
scalar.db.cluster.membership.kubernetes.endpoint.name=${env:SCALAR_DB_CLUSTER_MEMBERSHIP_KUBERNETES_ENDPOINT_NAME}
scalar.db.contact_points=localhost
scalar.db.username=${env:SCALAR_DB_USERNAME}
scalar.db.password=${env:SCALAR_DB_PASSWORD}
scalar.db.storage=cassandra
```
Note that you must always set the following three properties if you deploy ScalarDB Cluster in a Kubernetes environment by using Scalar Helm Chart. These properties are fixed values. Since the properties don't depend on individual environments, you can set the same values by copying the following values and pasting them in `scalardbCluster.scalardbClusterNodeProperties`.
```yaml
scalardbCluster:
scalardbClusterNodeProperties: |
scalar.db.cluster.membership.type=KUBERNETES
scalar.db.cluster.membership.kubernetes.endpoint.namespace_name=${env:SCALAR_DB_CLUSTER_MEMBERSHIP_KUBERNETES_ENDPOINT_NAMESPACE_NAME}
scalar.db.cluster.membership.kubernetes.endpoint.name=${env:SCALAR_DB_CLUSTER_MEMBERSHIP_KUBERNETES_ENDPOINT_NAME}
```
## Optional configurations
### Resource configurations (recommended in production environments)
To control pod resources by using requests and limits in Kubernetes, you can use `scalardbCluster.resources`.
Note that it is recommended to set at least 2vCPU / 4GB memory if you use the bring-your-own-license (BYOL) containers. Also, if you use the pay-as-you-go (PAYG) containers that the AWS Marketplace provides, you will not be able to run any containers that exceed the 2vCPU / 4GB memory configuration in `resources.limits`. If you exceed this resource limitation, the pods will automatically stop.
You can configure requests and limits by using the same syntax as requests and limits in Kubernetes. For more details on requests and limits in Kubernetes, see [Resource Management for Pods and Containers](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/).
```yaml
scalardbCluster:
resources:
requests:
cpu: 2000m
memory: 4Gi
limits:
cpu: 2000m
memory: 4Gi
```
### Secret configurations (recommended in production environments)
To use environment variables to set some properties (e.g., credentials) in `scalardbCluster.scalardbClusterNodeProperties`, you can use `scalardbCluster.secretName` to specify the Secret resource that includes some credentials.
For example, you can set credentials for a backend database (`scalar.db.username` and `scalar.db.password`) by using environment variables, which makes your pods more secure.
For more details on how to use a Secret resource, see [How to use Secret resources to pass the credentials as the environment variables into the properties file](use-secret-for-credentials.mdx).
```yaml
scalardbCluster:
secretName: "scalardb-cluster-credentials-secret"
```
### Affinity configurations (recommended in production environments)
To control pod deployment by using affinity and anti-affinity in Kubernetes, you can use `scalardbCluster.affinity`.
You can configure affinity and anti-affinity by using the same syntax for affinity and anti-affinity in Kubernetes. For more details on configuring affinity in Kubernetes, see [Assigning Pods to Nodes](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/).
```yaml
scalardbCluster:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- scalardb-cluster
- key: app.kubernetes.io/app
operator: In
values:
- scalardb-cluster
topologyKey: kubernetes.io/hostname
weight: 50
```
### Prometheus and Grafana configurations (recommended in production environments)
To monitor ScalarDB Cluster pods by using [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack), you can set `scalardbCluster.grafanaDashboard.enabled`, `scalardbCluster.serviceMonitor.enabled`, and `scalardbCluster.prometheusRule.enabled` to `true`. When you set these configurations to `true`, the chart deploys the necessary resources and kube-prometheus-stack starts monitoring automatically.
```yaml
scalardbCluster:
grafanaDashboard:
enabled: true
namespace: monitoring
serviceMonitor:
enabled: true
namespace: monitoring
interval: 15s
prometheusRule:
enabled: true
namespace: monitoring
```
### SecurityContext configurations (default value is recommended)
To set SecurityContext and PodSecurityContext for ScalarDB Cluster pods, you can use `scalardbCluster.securityContext` and `scalardbCluster.podSecurityContext`.
You can configure SecurityContext and PodSecurityContext by using the same syntax as SecurityContext and PodSecurityContext in Kubernetes. For more details on the SecurityContext and PodSecurityContext configurations in Kubernetes, see [Configure a Security Context for a Pod or Container](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/).
```yaml
scalardbCluster:
podSecurityContext:
seccompProfile:
type: RuntimeDefault
securityContext:
capabilities:
drop:
- ALL
runAsNonRoot: true
allowPrivilegeEscalation: false
```
### TLS configurations (optional based on your environment)
You can enable TLS in:
- The communications between the ScalarDB Cluster node and clients.
- The communications between all ScalarDB Cluster nodes (the cluster's internal communications).
#### Enable TLS
You can enable TLS in all ScalarDB Cluster connections by using the following configurations:
```yaml
scalardbCluster:
scalardbClusterNodeProperties: |
...(omit)...
scalar.db.cluster.tls.enabled=true
scalar.db.cluster.tls.ca_root_cert_path=/tls/scalardb-cluster/certs/ca.crt
scalar.db.cluster.node.tls.cert_chain_path=/tls/scalardb-cluster/certs/tls.crt
scalar.db.cluster.node.tls.private_key_path=/tls/scalardb-cluster/certs/tls.key
scalar.db.cluster.tls.override_authority=
tls:
enabled: true
```
##### Use your private key and certificate files
You can set your private key and certificate files by using the following configurations:
```yaml
scalardbCluster:
tls:
enabled: true
caRootCertSecret: "scalardb-cluster-tls-ca"
certChainSecret: "scalardb-cluster-tls-cert"
privateKeySecret: "scalardb-cluster-tls-key"
```
In this case, you have to create secret resources that include private key and certificate files for ScalarDB Cluster as follows, replacing the contents in the angle brackets as described:
```console
kubectl create secret generic scalardb-cluster-tls-ca --from-file=ca.crt=/ -n
kubectl create secret generic scalardb-cluster-tls-cert --from-file=tls.crt=/ -n
kubectl create secret generic scalardb-cluster-tls-key --from-file=tls.key=/ -n
```
For more details on how to prepare private key and certificate files, see [How to create private key and certificate files for Scalar products](../scalar-kubernetes/HowToCreateKeyAndCertificateFiles.mdx).
##### Use a trusted CA with cert-manager to manage your private key and certificate files
You can manage your private key and certificate files with cert-manager by using the following configurations, replacing the content in the angle brackets as described:
:::note
* If you want to use cert-manager, you must deploy cert-manager and prepare the `Issuers` resource. For details, see the cert-manager documentation, [Installation](https://cert-manager.io/docs/installation/) and [Issuer Configuration](https://cert-manager.io/docs/configuration/).
* By default, Scalar Helm Chart creates a `Certificate` resource that satisfies the certificate requirements of Scalar products. The default certificate configuration is recommended, but if you use a custom certificate configuration, you must satisfy the certificate requirements of Scalar products. For details, see [How to create private key and certificate files for Scalar products](../scalar-kubernetes/HowToCreateKeyAndCertificateFiles.mdx#certificate-requirements).
:::
```yaml
scalardbCluster:
tls:
enabled: true
certManager:
enabled: true
issuerRef:
name:
dnsNames:
- cluster.scalardb.example.com
```
In this case, cert-manager issues your private key and certificate files by using your trusted issuer. You don't need to mount your private key and certificate files manually.
##### Use a self-signed CA with cert-manager to manage your private key and certificate files
You can manage your private key and self-signed certificate files with cert-manager by using the following configurations:
:::note
* If you want to use cert-manager, you must deploy cert-manager. For more details on how to deploy cert-manager, see the [Installation](https://cert-manager.io/docs/installation/) in the cert-manager official document.
* By default, Scalar Helm Chart creates a `Certificate` resource that satisfies the certificate requirements of Scalar products. We recommend the default certificate configuration, but if you custom certificate configuration, you must satisfy the certificate requirements of Scalar products. See [How to create private key and certificate files for Scalar products](../scalar-kubernetes/HowToCreateKeyAndCertificateFiles.mdx#certificate-requirements).
:::
```yaml
scalardbCluster:
tls:
enabled: true
certManager:
enabled: true
selfSigned:
enabled: true
dnsNames:
- cluster.scalardb.example.com
```
In this case, Scalar Helm Charts and cert-manager issue your private key and self-signed certificate files. You don't need to mount your private key and certificate files manually.
##### Set custom authority for TLS communications
You can set the custom authority for TLS communications by using `scalardbCluster.tls.overrideAuthority`. This value doesn't change what host is actually connected. This value is intended for testing but may safely be used outside of tests as an alternative to DNS overrides. For example, you can specify the hostname presented in the certificate chain file that you set by using `scalardbCluster.tls.certChainSecret`. This chart uses this value for `startupProbe` and `livenessProbe`.
```yaml
scalardbCluster:
tls:
enabled: true
overrideAuthority: "cluster.scalardb.example.com"
```
##### Set a root CA certificate for Prometheus Operator
If you set `scalardbCluster.serviceMonitor.enabled=true` and `scalardbCluster.tls.enabled=true` (in other words, if you monitor ScalarDB Cluster with TLS configuration by using Prometheus Operator), you must set the secret name to `scalardbCluster.tls.caRootCertSecretForServiceMonitor`.
```yaml
scalardbCluster:
tls:
enabled: true
caRootCertSecretForServiceMonitor: "scalardb-cluster-tls-ca-for-prometheus"
```
In this case, you have to create secret resources that include a root CA certificate for ScalarDB Cluster in the same namespace as Prometheus as follows:
```console
kubectl create secret generic scalardb-cluster-tls-ca-for-prometheus --from-file=ca.crt=/path/to/your/ca/certificate/file -n
```
### Replica configurations (optional based on your environment)
You can specify the number of ScalarDB Cluster replicas (pods) by using `scalardbCluster.replicaCount`.
```yaml
scalardbCluster:
replicaCount: 3
```
### Logging configurations (optional based on your environment)
To change the ScalarDB Cluster log level, you can use `scalardbCluster.logLevel`.
```yaml
scalardbCluster:
logLevel: INFO
```
### GraphQL configurations (optional based on your environment)
To use the GraphQL feature in ScalarDB Cluster, you can set `scalardbCluster.graphql.enabled` to `true` to deploy some resources for the GraphQL feature. Note that you also need to set `scalar.db.graphql.enabled=true` in `scalardbCluster.scalardbClusterNodeProperties` when using the GraphQL feature.
```yaml
scalardbCluster:
graphql:
enabled: true
```
Also, you can configure the `Service` resource that accepts GraphQL requests from clients.
```yaml
scalardbCluster:
graphql:
service:
type: ClusterIP
annotations: {}
ports:
graphql:
port: 8080
targetPort: 8080
protocol: TCP
```
### SQL configurations (optional based on your environment)
To use the SQL feature in ScalarDB Cluster, there is no configuration necessary for custom values files. You can use the feature by setting `scalar.db.sql.enabled=true` in `scalardbCluster.scalardbClusterNodeProperties`.
### Scalar Envoy configurations (optional based on your environment)
To use ScalarDB Cluster with `indirect` mode, you must enable Envoy as follows.
```yaml
envoy:
enabled: true
```
Also, you must set the Scalar Envoy configurations in the custom values file for ScalarDB Cluster. This is because clients need to send requests to ScalarDB Cluster via Scalar Envoy as the load balancer of gRPC requests if you deploy ScalarDB Cluster in a Kubernetes environment with `indirect` mode.
For more details on Scalar Envoy configurations, see [Configure a custom values file for Scalar Envoy](configure-custom-values-envoy.mdx).
```yaml
envoy:
configurationsForScalarEnvoy:
...
scalardbCluster:
configurationsForScalarDbCluster:
...
```
### Taint and toleration configurations (optional based on your environment)
If you want to control pod deployment by using the taints and tolerations in Kubernetes, you can use `scalardbCluster.tolerations`.
You can configure taints and tolerations by using the same syntax as the tolerations in Kubernetes. For details on configuring tolerations in Kubernetes, see the official Kubernetes documentation [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/).
```yaml
scalardbCluster:
tolerations:
- effect: NoSchedule
key: scalar-labs.com/dedicated-node
operator: Equal
value: scalardb-cluster
```
### Encryption configurations (optional based on your environment)
You can enable [encryption at rest](https://scalardb.scalar-labs.com/docs/latest/scalardb-cluster/encrypt-data-at-rest/) to protect the data in the backend databases. When you use the encryption feature, you have the following two deployment options:
1. Use HashiCorp Vault (HashiCorp Cloud Platform (HCP) Vault Dedicated) to manage and store the DEKs.
1. Use ScalarDB Cluster to manage the DEK, and store it in Kubernetes Secrets.
#### Use HashiCorp Vault
You can use HashiCorp Vault (HCP Vault Dedicated) to encrypt data as follows, replacing the contents in the angle brackets as described:
```yaml
scalardbCluster:
scalardbClusterNodeProperties: |
...(omit)...
scalar.db.cluster.encryption.enabled=true
scalar.db.cluster.encryption.type=vault
scalar.db.cluster.encryption.vault.address=https://:
scalar.db.cluster.encryption.vault.token=
scalar.db.cluster.encryption.vault.transit_secrets_engine_path=
encryption:
enabled: true
type: "vault"
```
#### Use ScalarDB Cluster and Kubernetes Secrets
You can use ScalarDB Cluster and Kubernetes Secrets to encrypt data as follows, replacing the contents in the angle brackets as described:
```yaml
scalardbCluster:
scalardbClusterNodeProperties: |
...(omit)...
scalar.db.cluster.encryption.enabled=true
scalar.db.cluster.encryption.type=self
scalar.db.cluster.encryption.self.kubernetes.secret.namespace_name=${env:SCALAR_DB_CLUSTER_ENCRYPTION_SELF_KUBERNETES_SECRET_NAMESPACE_NAME}
encryption:
enabled: true
type: "self"
```
In this case, you don't need to replace `${env:SCALAR_DB_CLUSTER_ENCRYPTION_SELF_KUBERNETES_SECRET_NAMESPACE_NAME}` since the Helm Chart for ScalarDB Cluster automatically sets the namespace information as an environment variable. Because of this, you can keep the value `${env:SCALAR_DB_CLUSTER_ENCRYPTION_SELF_KUBERNETES_SECRET_NAMESPACE_NAME}` as is.
================================================
FILE: docs/helm-charts/configure-custom-values-scalardb-graphql.mdx
================================================
---
tags:
- Enterprise Standard
- Enterprise Premium
displayed_sidebar: docsEnglish
---
# [Deprecated] Configure a custom values file for ScalarDB GraphQL
:::note
ScalarDB GraphQL Server is now deprecated. Please use [ScalarDB Cluster](configure-custom-values-scalardb-cluster.mdx) instead.
:::
This document explains how to create your custom values file for the ScalarDB GraphQL chart. If you want to know the details of the parameters, please refer to the [README](https://github.com/scalar-labs/helm-charts/blob/main/charts/scalardb-graphql/README.md) of the ScalarDB GraphQL chart.
## Required configurations
### Ingress configuration
You must set `ingress` to listen the client requests. When you deploy multiple GraphQL servers, session affinity is required to handle transactions properly. This is because GraphQL servers keep the transactions in memory, so GraphQL queries that use continued transactions must be routed to the same server that started the transaction.
For example, if you use NGINX Ingress Controller, you can set ingress configurations as follows.
```yaml
ingress:
enabled: true
className: nginx
annotations:
nginx.ingress.kubernetes.io/session-cookie-path: /
nginx.ingress.kubernetes.io/affinity: cookie
nginx.ingress.kubernetes.io/session-cookie-name: INGRESSCOOKIE
nginx.ingress.kubernetes.io/session-cookie-hash: sha1
nginx.ingress.kubernetes.io/session-cookie-max-age: "300"
hosts:
- host: ""
paths:
- path: /graphql
pathType: Exact
```
If you use ALB of AWS, you can set ingress configurations as follows.
```yaml
ingress:
enabled: true
className: alb
annotations:
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=60
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/healthcheck-path: /graphql?query=%7B__typename%7D
hosts:
- host: ""
paths:
- path: /graphql
pathType: Exact
```
### Image configurations
You must set `image.repository`. Be sure to specify the ScalarDB GraphQL container image so that you can pull the image from the container repository.
```yaml
image:
repository:
```
If you're using AWS, refer to [How to install Scalar products through AWS Marketplace](../scalar-kubernetes/AwsMarketplaceGuide.mdx).
### Database configurations
You must set `scalarDbGraphQlConfiguration`.
If you use ScalarDB Server with ScalarDB GraphQL (recommended), you must set the configuration to access the ScalarDB Server pods.
```yaml
scalarDbGraphQlConfiguration:
contactPoints:
contactPort: 60051
storage: "grpc"
transactionManager: "grpc"
namespaces:
```
## Optional configurations
### Resource configurations (Recommended in the production environment)
If you want to control pod resources using the requests and limits of Kubernetes, you can use `resources`.
Note that it is recommended to set at least 2vCPU / 4GB memory if you use the bring-your-own-license (BYOL) containers. Also, if you use the pay-as-you-go (PAYG) containers that the AWS Marketplace provides, you will not be able to run any containers that exceed the 2vCPU / 4GB memory configuration in `resources.limits`. If you exceed this resource limitation, the pods will automatically stop.
You can configure them using the same syntax as the requests and limits of Kubernetes. So, please refer to the official document [Resource Management for Pods and Containers](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for more details on the requests and limits of Kubernetes.
```yaml
resources:
requests:
cpu: 2000m
memory: 4Gi
limits:
cpu: 2000m
memory: 4Gi
```
### Affinity configurations (Recommended in the production environment)
If you want to control pod deployment using the affinity and anti-affinity of Kubernetes, you can use `affinity`.
You can configure them using the same syntax as the affinity of Kubernetes. So, please refer to the official document [Assigning Pods to Nodes](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) for more details on the affinity configuration of Kubernetes.
```yaml
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/app
operator: In
values:
- scalardb-graphql
topologyKey: kubernetes.io/hostname
weight: 50
```
### Prometheus/Grafana configurations (Recommended in the production environment)
If you want to monitor ScalarDB GraphQL pods using [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack), you can deploy a ConfigMap, a ServiceMonitor, and a PrometheusRule resource for kube-prometheus-stack using `grafanaDashboard.enabled`, `serviceMonitor.enabled`, and `prometheusRule.enabled`.
```yaml
grafanaDashboard:
enabled: true
namespace: monitoring
serviceMonitor:
enabled: true
namespace: monitoring
interval: 15s
prometheusRule:
enabled: true
namespace: monitoring
```
### SecurityContext configurations (Default value is recommended)
If you want to set SecurityContext and PodSecurityContext for ScalarDB GraphQL pods, you can use `securityContext` and `podSecurityContext`.
You can configure them using the same syntax as SecurityContext and PodSecurityContext of Kubernetes. So, please refer to the official document [Configure a Security Context for a Pod or Container](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for more details on the SecurityContext and PodSecurityContext configurations of Kubernetes.
```yaml
podSecurityContext:
seccompProfile:
type: RuntimeDefault
securityContext:
capabilities:
drop:
- ALL
runAsNonRoot: true
allowPrivilegeEscalation: false
```
### GraphQL Server configurations (Optional based on your environment)
If you want to change the path to run the graphql queries, you can use `scalarDbGraphQlConfiguration.path`. By default, you can run the graphql queries using `http://:80/graphql`.
You can also enable/disable [GraphiQL](https://github.com/graphql/graphiql/tree/main/packages/graphiql) using `scalarDbGraphQlConfiguration.graphiql`.
```yaml
scalarDbGraphQlConfiguration:
path: /graphql
graphiql: "true"
```
### TLS configurations (Optional based on your environment)
If you want to use TLS between the client and the ingress, you can use `ingress.tls`.
You must create a Secret resource that includes a secret key and a certificate file. Please refer to the official document [Ingress - TLS](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls) for more details on the Secret resource for Ingress.
```yaml
ingress:
tls:
- hosts:
- foo.example.com
- bar.example.com
- bax.example.com
secretName: graphql-ingress-tls
```
### Replica configurations (Optional based on your environment)
You can specify the number of replicas (pods) of ScalarDB GraphQL using `replicaCount`.
```yaml
replicaCount: 3
```
### Logging configurations (Optional based on your environment)
If you want to change the log level of ScalarDB GraphQL, you can use `scalarDbGraphQlConfiguration.logLevel`.
```yaml
scalarDbGraphQlConfiguration:
logLevel: INFO
```
### Taint and toleration configurations (Optional based on your environment)
If you want to control pod deployment by using the taints and tolerations in Kubernetes, you can use `tolerations`.
You can configure taints and tolerations by using the same syntax as the tolerations in Kubernetes. For details on configuring tolerations in Kubernetes, see the official Kubernetes documentation [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/).
```yaml
tolerations:
- effect: NoSchedule
key: scalar-labs.com/dedicated-node
operator: Equal
value: scalardb
```
================================================
FILE: docs/helm-charts/configure-custom-values-scalardb.mdx
================================================
---
tags:
- Enterprise Standard
- Enterprise Premium
- Deprecated
displayed_sidebar: docsEnglish
---
# [Deprecated] Configure a custom values file for ScalarDB Server
:::note
ScalarDB Server is now deprecated. Please use [ScalarDB Cluster](configure-custom-values-scalardb-cluster.mdx) instead.
:::
This document explains how to create your custom values file for the ScalarDB Server chart. If you want to know the details of the parameters, please refer to the [README](https://github.com/scalar-labs/helm-charts/blob/main/charts/scalardb/README.md) of the ScalarDB Server chart.
## Required configurations
### Scalar Envoy configurations
You must set the Scalar Envoy configurations in the custom values file for ScalarDB Server. This is because client requests are sent to ScalarDB Server via Scalar Envoy as the load balancer of gRPC requests if you deploy ScalarDB Server on a Kubernetes environment.
Please refer to the document [Configure a custom values file for Scalar Envoy](configure-custom-values-envoy.mdx) for more details on the Scalar Envoy configurations.
```yaml
envoy:
configurationsForScalarEnvoy:
...
scalardb:
configurationsForScalarDB:
...
```
### Image configurations
You must set `scalardb.image.repository`. Be sure to specify the ScalarDB Server container image so that you can pull the image from the container repository.
```yaml
scalardb:
image:
repository:
```
If you're using AWS, refer to [How to install Scalar products through AWS Marketplace](../scalar-kubernetes/AwsMarketplaceGuide.mdx).
### Database configurations
You must set `scalardb.databaseProperties`. Please set your `database.properties` to this parameter. Please refer to the [Configure ScalarDB Server](https://scalardb.scalar-labs.com/docs/latest/scalardb-server#configure-scalardb-server) for more details on the configuration of ScalarDB Server.
```yaml
scalardb:
databaseProperties: |
scalar.db.server.port=60051
scalar.db.server.prometheus_exporter_port=8080
scalar.db.server.grpc.max_inbound_message_size=
scalar.db.server.grpc.max_inbound_metadata_size=
scalar.db.contact_points=localhost
scalar.db.username=cassandra
scalar.db.password=cassandra
scalar.db.storage=cassandra
scalar.db.transaction_manager=consensus-commit
scalar.db.consensus_commit.isolation_level=SNAPSHOT
scalar.db.consensus_commit.serializable_strategy=
scalar.db.consensus_commit.include_metadata.enabled=false
```
## Optional configurations
### Resource configurations (Recommended in the production environment)
If you want to control pod resources using the requests and limits of Kubernetes, you can use `scalardb.resources`.
Note that it is recommended to set at least 2vCPU / 4GB memory if you use the bring-your-own-license (BYOL) containers. Also, if you use the pay-as-you-go (PAYG) containers that the AWS Marketplace provides, you will not be able to run any containers that exceed the 2vCPU / 4GB memory configuration in `resources.limits`. If you exceed this resource limitation, the pods will automatically stop.
You can configure them using the same syntax as the requests and limits of Kubernetes. So, please refer to the official document [Resource Management for Pods and Containers](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for more details on the requests and limits of Kubernetes.
```yaml
scalardb:
resources:
requests:
cpu: 2000m
memory: 4Gi
limits:
cpu: 2000m
memory: 4Gi
```
### Secret configurations (Recommended in the production environment)
If you want to use environment variables to set some properties (e.g., credentials) in the `scalardb.databaseProperties`, you can use `scalardb.secretName` to specify the Secret resource that includes some credentials.
For example, you can set credentials for a backend database (`scalar.db.username` and `scalar.db.password`) using environment variables, which makes your pods more secure.
Please refer to the document [How to use Secret resources to pass the credentials as the environment variables into the properties file](use-secret-for-credentials.mdx) for more details on how to use a Secret resource.
```yaml
scalardb:
secretName: "scalardb-credentials-secret"
```
### Affinity configurations (Recommended in the production environment)
If you want to control pod deployment using the affinity and anti-affinity of Kubernetes, you can use `scalardb.affinity`.
You can configure them using the same syntax as the affinity of Kubernetes. So, please refer to the official document [Assigning Pods to Nodes](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) for more details on the affinity configuration of Kubernetes.
```yaml
scalardb:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- scalardb
- key: app.kubernetes.io/app
operator: In
values:
- scalardb
topologyKey: kubernetes.io/hostname
weight: 50
```
### Prometheus/Grafana configurations (Recommended in the production environment)
If you want to monitor ScalarDB Server pods using [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack), you can deploy a ConfigMap, a ServiceMonitor, and a PrometheusRule resource for kube-prometheus-stack using `scalardb.grafanaDashboard.enabled`, `scalardb.serviceMonitor.enabled`, and `scalardb.prometheusRule.enabled`.
```yaml
scalardb:
grafanaDashboard:
enabled: true
namespace: monitoring
serviceMonitor:
enabled: true
namespace: monitoring
interval: 15s
prometheusRule:
enabled: true
namespace: monitoring
```
### SecurityContext configurations (Default value is recommended)
If you want to set SecurityContext and PodSecurityContext for ScalarDB Server pods, you can use `scalardb.securityContext` and `scalardb.podSecurityContext`.
You can configure them using the same syntax as SecurityContext and PodSecurityContext of Kubernetes. So, please refer to the official document [Configure a Security Context for a Pod or Container](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for more details on the SecurityContext and PodSecurityContext configurations of Kubernetes.
```yaml
scalardb:
podSecurityContext:
seccompProfile:
type: RuntimeDefault
securityContext:
capabilities:
drop:
- ALL
runAsNonRoot: true
allowPrivilegeEscalation: false
```
### Replica configurations (Optional based on your environment)
You can specify the number of replicas (pods) of ScalarDB Server using `scalardb.replicaCount`.
```yaml
scalardb:
replicaCount: 3
```
### Logging configurations (Optional based on your environment)
If you want to change the log level of ScalarDB Server, you can use `scalardb.storageConfiguration.dbLogLevel`.
```yaml
scalardb:
storageConfiguration:
dbLogLevel: INFO
```
### Taint and toleration configurations (Optional based on your environment)
If you want to control pod deployment by using the taints and tolerations in Kubernetes, you can use `scalardb.tolerations`.
You can configure taints and tolerations by using the same syntax as the tolerations in Kubernetes. For details on configuring tolerations in Kubernetes, see the official Kubernetes documentation [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/).
```yaml
scalardb:
tolerations:
- effect: NoSchedule
key: scalar-labs.com/dedicated-node
operator: Equal
value: scalardb
```
================================================
FILE: docs/helm-charts/configure-custom-values-scalardl-auditor.mdx
================================================
---
tags:
- Enterprise
displayed_sidebar: docsEnglish
---
# Configure a custom values file for ScalarDL Auditor
import CertificateManagement from '/src/components/en-us/_certificate-management.mdx';
This document explains how to create your custom values file for the ScalarDL Auditor chart. If you want to know the details of the parameters, please refer to the [README](https://github.com/scalar-labs/helm-charts/blob/main/charts/scalardl-audit/README.md) of the ScalarDL Auditor chart.
## Required configurations
### Scalar Envoy configurations
You must set the Scalar Envoy configurations in the custom values file for ScalarDL Auditor. This is because client requests are sent to ScalarDL Auditor via Scalar Envoy as the load balancer of gRPC requests if you deploy ScalarDL Auditor on a Kubernetes environment.
Please refer to the document [Configure a custom values file for Scalar Envoy](configure-custom-values-envoy.mdx) for more details on the Scalar Envoy configurations.
```yaml
envoy:
configurationsForScalarEnvoy:
...
auditor:
configurationsForScalarDLAuditor:
...
```
### Image configurations
You must set `auditor.image.repository`. Be sure to specify the ScalarDL Auditor container image so that you can pull the image from the container repository.
```yaml
auditor:
image:
repository:
```
For more details on the container repository for Scalar products, see [How to get the container images of Scalar products](../scalar-kubernetes/HowToGetContainerImages.mdx).
### Auditor/Database configurations
You must set `auditor.auditorProperties`. Please set your `auditor.properties` to this parameter. Please refer to the [auditor.properties](https://github.com/scalar-labs/scalar/blob/master/auditor/conf/auditor.properties) for more details on the configuration of ScalarDL Auditor.
```yaml
auditor:
auditorProperties: |
scalar.db.contact_points=localhost
scalar.db.username=cassandra
scalar.db.password=cassandra
scalar.db.storage=cassandra
scalar.dl.auditor.ledger.host=
scalar.dl.auditor.private_key_path=/keys/auditor-key-file
```
### Private key configurations
You must set a private key file to `scalar.dl.auditor.private_key_path`.
You must also mount the private key file on the ScalarDL Auditor pod.
For more details on how to mount the private key file, refer to [Mount a private key file on a pod in ScalarDL Helm Charts](mount-files-or-volumes-on-scalar-pods.mdx#mount-a-private-key-file-on-a-pod-in-scalardl-helm-charts).
## Optional configurations
### Resource configurations (Recommended in the production environment)
If you want to control pod resources using the requests and limits of Kubernetes, you can use `auditor.resources`.
Note that it is recommended to set at least 2vCPU / 4GB memory if you use the bring-your-own-license (BYOL) containers. Also, if you use the pay-as-you-go (PAYG) containers that the AWS Marketplace provides, you will not be able to run any containers that exceed the 2vCPU / 4GB memory configuration in `resources.limits`. If you exceed this resource limitation, the pods will automatically stop.
You can configure them using the same syntax as the requests and limits of Kubernetes. So, please refer to the official document [Resource Management for Pods and Containers](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for more details on the requests and limits of Kubernetes.
```yaml
auditor:
resources:
requests:
cpu: 2000m
memory: 4Gi
limits:
cpu: 2000m
memory: 4Gi
```
### Secret configurations
If you want to use environment variables to set some properties (e.g., credentials) in the `auditor.auditorProperties`, you can use `auditor.secretName` to specify the Secret resource that includes some credentials.
For example, you can set credentials for a backend database (`scalar.db.username` and `scalar.db.password`) using environment variables, which makes your pods more secure.
Please refer to the document [How to use Secret resources to pass the credentials as the environment variables into the properties file](use-secret-for-credentials.mdx) for more details on how to use a Secret resource.
```yaml
auditor:
secretName: "auditor-credentials-secret"
```
### Affinity configurations (Recommended in the production environment)
If you want to control pod deployment using the affinity and anti-affinity of Kubernetes, you can use `auditor.affinity`.
You can configure them using the same syntax as the affinity of Kubernetes. So, please refer to the official document [Assigning Pods to Nodes](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) for more details on the affinity configuration of Kubernetes.
```yaml
auditor:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- scalardl-audit
- key: app.kubernetes.io/app
operator: In
values:
- auditor
topologyKey: kubernetes.io/hostname
weight: 50
```
### Prometheus/Grafana configurations (Recommended in the production environment)
If you want to monitor ScalarDL Auditor pods using [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack), you can deploy a ConfigMap, a ServiceMonitor, and a PrometheusRule resource for kube-prometheus-stack using `auditor.grafanaDashboard.enabled`, `auditor.serviceMonitor.enabled`, and `auditor.prometheusRule.enabled`.
```yaml
auditor:
grafanaDashboard:
enabled: true
namespace: monitoring
serviceMonitor:
enabled: true
namespace: monitoring
interval: 15s
prometheusRule:
enabled: true
namespace: monitoring
```
### SecurityContext configurations (Default value is recommended)
If you want to set SecurityContext and PodSecurityContext for ScalarDL Auditor pods, you can use `auditor.securityContext` and `auditor.podSecurityContext`.
You can configure them using the same syntax as SecurityContext and PodSecurityContext of Kubernetes. So, please refer to the official document [Configure a Security Context for a Pod or Container](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for more details on the SecurityContext and PodSecurityContext configurations of Kubernetes.
```yaml
auditor:
podSecurityContext:
seccompProfile:
type: RuntimeDefault
securityContext:
capabilities:
drop:
- ALL
runAsNonRoot: true
allowPrivilegeEscalation: false
```
### TLS configurations (optional based on your environment)
You can enable TLS in:
- The communications between the ScalarDL Auditor and clients.
- The communications between the ScalarDL Ledger and ScalarDL Auditor.
#### Enable TLS
You can enable TLS in all ScalarDL Auditor connections by using the following configurations:
```yaml
auditor:
auditorProperties: |
...(omit)...
scalar.dl.auditor.server.tls.enabled=true
scalar.dl.auditor.server.tls.cert_chain_path=/tls/scalardl-auditor/certs/tls.crt
scalar.dl.auditor.server.tls.private_key_path=/tls/scalardl-auditor/certs/tls.key
scalar.dl.auditor.tls.enabled=true
scalar.dl.auditor.tls.ca_root_cert_path=/tls/scalardl-ledger/certs/ca.crt
scalar.dl.auditor.tls.override_authority=envoy.scalar.example.com
tls:
enabled: true
```
##### Use your private key and certificate files
You can set your private key and certificate files by using the following configurations:
```yaml
auditor:
tls:
enabled: true
caRootCertSecret: "scalardl-auditor-tls-ca"
certChainSecret: "scalardl-auditor-tls-cert"
privateKeySecret: "scalardl-auditor-tls-key"
```
In this case, you have to create secret resources that include private key and certificate files for ScalarDL Ledger and ScalarDL Auditor as follows, replacing the contents in the angle brackets as described:
```console
kubectl create secret generic scalardl-auditor-tls-ca --from-file=ca.crt=/ -n
kubectl create secret generic scalardl-auditor-tls-cert --from-file=tls.crt=/ -n
kubectl create secret generic scalardl-auditor-tls-key --from-file=tls.key=/ -n
kubectl create secret generic scalardl-auditor-tls-ca-for-ledger --from-file=ca.crt=/ -n
```
For more details on how to prepare private key and certificate files, see [How to create private key and certificate files for Scalar products](../scalar-kubernetes/HowToCreateKeyAndCertificateFiles.mdx).
##### Use a trusted CA with cert-manager to manage your private key and certificate files
You can manage your private key and certificate files with cert-manager by using the following configurations, replacing the content in the angle brackets as described:
:::note
* If you want to use cert-manager, you must deploy cert-manager and prepare the `Issuers` resource. For details, see the cert-manager documentation, [Installation](https://cert-manager.io/docs/installation/) and [Issuer Configuration](https://cert-manager.io/docs/configuration/).
* By default, Scalar Helm Chart creates a `Certificate` resource that satisfies the certificate requirements of Scalar products. The default certificate configuration is recommended, but if you use a custom certificate configuration, you must satisfy the certificate requirements of Scalar products. For details, see [How to create private key and certificate files for Scalar products](../scalar-kubernetes/HowToCreateKeyAndCertificateFiles.mdx#certificate-requirements).
:::
```yaml
auditor:
tls:
enabled: true
certManager:
enabled: true
issuerRef:
name:
dnsNames:
- auditor.scalardl.example.com
```
In this case, cert-manager issues your private key and certificate files by using your trusted issuer. You don't need to mount private key and certificate files manually.
##### Use a self-signed CA with cert-manager to manage your private key and certificate files
You can manage your private key and self-signed certificate files with cert-manager by using the following configurations:
:::note
* If you want to use cert-manager, you must deploy cert-manager. For details, see the cert-manager documentation, [Installation](https://cert-manager.io/docs/installation/).
* By default, Scalar Helm Chart creates a `Certificate` resource that satisfies the certificate requirements of Scalar products. The default certificate configuration is recommended, but if you use a custom certificate configuration, you must satisfy the certificate requirements of Scalar products. For details, see [How to create private key and certificate files for Scalar products](../scalar-kubernetes/HowToCreateKeyAndCertificateFiles.mdx#certificate-requirements).
:::
```yaml
auditor:
tls:
enabled: true
certManager:
enabled: true
selfSigned:
enabled: true
dnsNames:
- auditor.scalardl.example.com
```
In this case, Scalar Helm Charts and cert-manager issue your private key and self-signed certificate files. You don't need to mount private key and certificate files manually.
#### Set a root CA certificate for ScalarDL Ledger
If you enable TLS on the ScalarDL Ledger side, you must set a root CA certificate file for Envoy in front of ScalarDL Ledger to access it from ScalarDL Auditor. To determine which approach you should take, refer to the following decision tree:
```mermaid
flowchart TD
A[Are you using cert-manager?]
A -->|Yes| B
A -->|No| D
B[Are you using a self-signed CA with cert-manager?]
B -->|No| C[Are you using the same trusted CA for ScalarDL
Ledger and ScalarDL Auditor with cert-manager?]
C -->|No| D[You must set the root
CA certificate of Envoy for ScalarDL Ledger manually.]
C ---->|Yes| E[Scalar Helm Chart automatically sets the root CA certificate. You
don't need to set `auditor.tls.upstream.caRootCertSecret` explicitly.]
```
If you need to set the root CA certificate file of Envoy manually, you can set it by using the following configurations:
```yaml
auditor:
tls:
enabled: true
caRootCertForLedgerSecret: "scalardl-auditor-tls-ca-for-ledger"
```
In this case, you have to create secret resources that include root CA certificate files as follows, replacing the contents in the angle brackets as described:
```console
kubectl create secret generic scalardl-auditor-tls-ca-for-ledger --from-file=ca.crt=//scalardl-ledger -n
```
##### Set custom authority for TLS communications
You can set the custom authority for TLS communications by using `auditor.tls.overrideAuthority`. This value doesn't change what host is actually connected. This value is intended for testing but may safely be used outside of tests as an alternative to DNS overrides. For example, you can specify the hostname presented in the certificate chain file that you set by using `auditor.tls.certChainSecret`. This chart uses this value for `startupProbe` and `livenessProbe`.
##### Set a root CA certificate for Prometheus Operator
If you set `auditor.serviceMonitor.enabled=true` and `auditor.tls.enabled=true` (in other words, if you monitor ScalarDL Auditor with TLS configuration by using Prometheus Operator), you must set the secret name to `auditor.tls.caRootCertSecretForServiceMonitor`.
```yaml
auditor:
tls:
enabled: true
caRootCertSecretForServiceMonitor: "scalardl-auditor-tls-ca-for-prometheus"
```
In this case, you have to create secret resources that include a root CA certificate for ScalarDL Auditor in the same namespace as Prometheus as follows:
```console
kubectl create secret generic scalardl-auditor-tls-ca-for-prometheus --from-file=ca.crt=/path/to/your/ca/certificate/file -n
```
### Replica configurations (Optional based on your environment)
You can specify the number of replicas (pods) of ScalarDL Auditor using `auditor.replicaCount`.
```yaml
auditor:
replicaCount: 3
```
### Logging configurations (Optional based on your environment)
If you want to change the log level of ScalarDL Auditor, you can use `auditor.scalarAuditorConfiguration.auditorLogLevel`.
```yaml
auditor:
scalarAuditorConfiguration:
auditorLogLevel: INFO
```
### Taint and toleration configurations (Optional based on your environment)
If you want to control pod deployment by using the taints and tolerations in Kubernetes, you can use `auditor.tolerations`.
You can configure taints and tolerations by using the same syntax as the tolerations in Kubernetes. For details on configuring tolerations in Kubernetes, see the official Kubernetes documentation [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/).
```yaml
auditor:
tolerations:
- effect: NoSchedule
key: scalar-labs.com/dedicated-node
operator: Equal
value: scalardl-auditor
```
================================================
FILE: docs/helm-charts/configure-custom-values-scalardl-ledger.mdx
================================================
---
tags:
- Enterprise
displayed_sidebar: docsEnglish
---
# Configure a custom values file for ScalarDL Ledger
import CertificateManagement from '/src/components/en-us/_certificate-management.mdx';
This document explains how to create your custom values file for the ScalarDL Ledger chart. If you want to know the details of the parameters, please refer to the [README](https://github.com/scalar-labs/helm-charts/blob/main/charts/scalardl/README.md) of the ScalarDL Ledger chart.
## Required configurations
### Scalar Envoy configurations
You must set the Scalar Envoy configurations in the custom values file for ScalarDL Ledger. This is because client requests are sent to ScalarDL Ledger via Scalar Envoy as the load balancer of gRPC requests if you deploy ScalarDL Ledger on a Kubernetes environment.
Please refer to the document [Configure a custom values file for Scalar Envoy](configure-custom-values-envoy.mdx) for more details on the Scalar Envoy configurations.
```yaml
envoy:
configurationsForScalarEnvoy:
...
ledger:
configurationsForScalarDLLedger:
...
```
### Image configurations
You must set `ledger.image.repository`. Be sure to specify the ScalarDL Ledger container image so that you can pull the image from the container repository.
```yaml
ledger:
image:
repository:
```
For more details on the container repository for Scalar products, see [How to get the container images of Scalar products](../scalar-kubernetes/HowToGetContainerImages.mdx).
### Ledger/Database configurations
You must set `ledger.ledgerProperties`. Please set your `ledger.properties` to this parameter. Please refer to the [ledger.properties](https://github.com/scalar-labs/scalar/blob/master/ledger/conf/ledger.properties) for more details on the configuration of ScalarDL Ledger.
```yaml
ledger:
ledgerProperties: |
scalar.db.contact_points=localhost
scalar.db.username=cassandra
scalar.db.password=cassandra
scalar.db.storage=cassandra
scalar.dl.ledger.proof.enabled=true
scalar.dl.ledger.auditor.enabled=true
scalar.dl.ledger.proof.private_key_path=/keys/ledger-key-file
```
### Key/Certificate configurations
If you set `scalar.dl.ledger.proof.enabled` to `true` (this configuration is required if you use ScalarDL Auditor), you must set a private key file to `scalar.dl.ledger.proof.private_key_path`.
In this case, you must mount the private key file on the ScalarDL Ledger pod.
For more details on how to mount the private key file, refer to [Mount key and certificate files on a pod in ScalarDL Helm Charts](mount-files-or-volumes-on-scalar-pods.mdx#mount-key-and-certificate-files-on-a-pod-in-scalardl-helm-charts).
## Optional configurations
### Resource configurations (Recommended in the production environment)
If you want to control pod resources using the requests and limits of Kubernetes, you can use `ledger.resources`.
Note that it is recommended to set at least 2vCPU / 4GB memory if you use the bring-your-own-license (BYOL) containers. Also, if you use the pay-as-you-go (PAYG) containers that the AWS Marketplace provides, you will not be able to run any containers that exceed the 2vCPU / 4GB memory configuration in `resources.limits`. If you exceed this resource limitation, the pods will automatically stop.
You can configure them using the same syntax as the requests and limits of Kubernetes. So, please refer to the official document [Resource Management for Pods and Containers](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for more details on the requests and limits of Kubernetes.
```yaml
ledger:
resources:
requests:
cpu: 2000m
memory: 4Gi
limits:
cpu: 2000m
memory: 4Gi
```
### Secret configurations (Recommended in the production environment)
If you want to use environment variables to set some properties (e.g., credentials) in the `ledger.ledgerProperties`, you can use `ledger.secretName` to specify the Secret resource that includes some credentials.
For example, you can set credentials for a backend database (`scalar.db.username` and `scalar.db.password`) using environment variables, which makes your pods more secure.
Please refer to the document [How to use Secret resources to pass the credentials as the environment variables into the properties file](use-secret-for-credentials.mdx) for more details on how to use a Secret resource.
```yaml
ledger:
secretName: "ledger-credentials-secret"
```
### Affinity configurations (Recommended in the production environment)
If you want to control pod deployment using the affinity and anti-affinity of Kubernetes, you can use `ledger.affinity`.
You can configure them using the same syntax as the affinity of Kubernetes. So, please refer to the official document [Assigning Pods to Nodes](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) for more details on the affinity configuration of Kubernetes.
```yaml
ledger:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- scalardl
- key: app.kubernetes.io/app
operator: In
values:
- ledger
topologyKey: kubernetes.io/hostname
weight: 50
```
### Prometheus/Grafana configurations (Recommended in the production environment)
If you want to monitor ScalarDL Ledger pods using [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack), you can deploy a ConfigMap, a ServiceMonitor, and a PrometheusRule resource for kube-prometheus-stack using `ledger.grafanaDashboard.enabled`, `ledger.serviceMonitor.enabled`, and `ledger.prometheusRule.enabled`.
```yaml
ledger:
grafanaDashboard:
enabled: true
namespace: monitoring
serviceMonitor:
enabled: true
namespace: monitoring
interval: 15s
prometheusRule:
enabled: true
namespace: monitoring
```
### SecurityContext configurations (Default value is recommended)
If you want to set SecurityContext and PodSecurityContext for ScalarDL Ledger pods, you can use `ledger.securityContext` and `ledger.podSecurityContext`.
You can configure them using the same syntax as SecurityContext and PodSecurityContext of Kubernetes. So, please refer to the official document [Configure a Security Context for a Pod or Container](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for more details on the SecurityContext and PodSecurityContext configurations of Kubernetes.
```yaml
ledger:
podSecurityContext:
seccompProfile:
type: RuntimeDefault
securityContext:
capabilities:
drop:
- ALL
runAsNonRoot: true
allowPrivilegeEscalation: false
```
### TLS configurations (optional based on your environment)
You can enable TLS in:
- The communications between the ScalarDL Ledger and clients.
- The communications between the ScalarDL Ledger and ScalarDL Auditor.
#### Enable TLS
You can enable TLS in all ScalarDL Ledger connections by using the following configurations:
```yaml
ledger:
ledgerProperties: |
...(omit)...
scalar.dl.ledger.server.tls.enabled=true
scalar.dl.ledger.server.tls.cert_chain_path=/tls/scalardl-ledger/certs/tls.crt
scalar.dl.ledger.server.tls.private_key_path=/tls/scalardl-ledger/certs/tls.key
tls:
enabled: true
```
##### Use your private key and certificate files
You can set your private key and certificate files by using the following configurations:
```yaml
ledger:
tls:
enabled: true
caRootCertSecret: "scalardl-ledger-tls-ca"
certChainSecret: "scalardl-ledger-tls-cert"
privateKeySecret: "scalardl-ledger-tls-key"
```
In this case, you have to create secret resources that include private key and certificate files for ScalarDL Ledger as follows, replacing the contents in the angle brackets as described:
```console
kubectl create secret generic scalardl-ledger-tls-ca --from-file=ca.crt=/ -n
kubectl create secret generic scalardl-ledger-tls-cert --from-file=tls.crt=/ -n
kubectl create secret generic scalardl-ledger-tls-key --from-file=tls.key=/ -n
```
For more details on how to prepare private key and certificate files, see [How to create private key and certificate files for Scalar products](../scalar-kubernetes/HowToCreateKeyAndCertificateFiles.mdx).
##### Use a trusted CA with cert-manager to manage your private key and certificate files
You can manage private key and certificate with cert-manager by using the following configurations:
:::note
* If you want to use cert-manager, you must deploy cert-manager and prepare the `Issuers` resource. For more details on cert-manager, see the [Installation](https://cert-manager.io/docs/installation/) and [Issuer Configuration](https://cert-manager.io/docs/configuration/) in the cert-manager official document.
* By default, Scalar Helm Chart creates a `Certificate` resource that satisfies the certificate requirements of Scalar products. We recommend the default certificate configuration, but if you custom certificate configuration, you must satisfy the certificate requirements of Scalar products. See [How to create private key and certificate files for Scalar products](../scalar-kubernetes/HowToCreateKeyAndCertificateFiles.mdx#certificate-requirements).
:::
```yaml
ledger:
tls:
enabled: true
certManager:
enabled: true
issuerRef:
name: your-trusted-ca
dnsNames:
- ledger.scalardl.example.com
```
In this case, cert-manager issues private key and certificate by using your trusted issuer. You don't need to mount private key and certificate files manually.
##### Use a self-signed CA with cert-manager to manage your private key and certificate files
You can manage private key and self-signed certificate with cert-manager by using the following configurations:
:::note
* If you want to use cert-manager, you must deploy cert-manager. For more details on how to deploy cert-manager, see the [Installation](https://cert-manager.io/docs/installation/) in the cert-manager official document.
* By default, Scalar Helm Chart creates a `Certificate` resource that satisfies the certificate requirements of Scalar products. We recommend the default certificate configuration, but if you custom certificate configuration, you must satisfy the certificate requirements of Scalar products. See [How to create private key and certificate files for Scalar products](../scalar-kubernetes/HowToCreateKeyAndCertificateFiles.mdx#certificate-requirements).
:::
```yaml
ledger:
tls:
enabled: true
certManager:
enabled: true
selfSigned:
enabled: true
dnsNames:
- ledger.scalardl.example.com
```
In this case, Scalar Helm Charts and cert-manager issue private key and self-signed certificate. You don't need to mount private key and certificate files manually.
##### Set custom authority for TLS communications
You can set the custom authority for TLS communications by using `ledger.tls.overrideAuthority`. This value doesn't change what host is actually connected. This value is intended for testing but may safely be used outside of tests as an alternative to DNS overrides. For example, you can specify the hostname presented in the certificate chain file that you set by using `ledger.tls.certChainSecret`. This chart uses this value for `startupProbe` and `livenessProbe`.
```yaml
ledger:
tls:
enabled: true
overrideAuthority: "ledger.scalardl.example.com"
```
##### Set a root CA certificate for Prometheus Operator
If you set `ledger.serviceMonitor.enabled=true` and `ledger.tls.enabled=true` (in other words, if you monitor ScalarDL Ledger with TLS configuration by using Prometheus Operator), you must set the secret name to `ledger.tls.caRootCertSecretForServiceMonitor`.
```yaml
ledger:
tls:
enabled: true
caRootCertSecretForServiceMonitor: "scalardl-ledger-tls-ca-for-prometheus"
```
In this case, you have to create secret resources that include a root CA certificate for ScalarDL Ledger in the same namespace as Prometheus as follows:
```console
kubectl create secret generic scalardl-ledger-tls-ca-for-prometheus --from-file=ca.crt=/path/to/your/ca/certificate/file -n
```
### Replica configurations (optional based on your environment)
You can specify the number of replicas (pods) of ScalarDL Ledger using `ledger.replicaCount`.
```yaml
ledger:
replicaCount: 3
```
### Logging configurations (Optional based on your environment)
If you want to change the log level of ScalarDL Ledger, you can use `ledger.scalarLedgerConfiguration.ledgerLogLevel`.
```yaml
ledger:
scalarLedgerConfiguration:
ledgerLogLevel: INFO
```
### Taint and toleration configurations (Optional based on your environment)
If you want to control pod deployment by using the taints and tolerations in Kubernetes, you can use `ledger.tolerations`.
You can configure taints and tolerations by using the same syntax as the tolerations in Kubernetes. For details on configuring tolerations in Kubernetes, see the official Kubernetes documentation [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/).
```yaml
ledger:
tolerations:
- effect: NoSchedule
key: scalar-labs.com/dedicated-node
operator: Equal
value: scalardl-ledger
```
================================================
FILE: docs/helm-charts/configure-custom-values-scalardl-schema-loader.mdx
================================================
---
tags:
- Enterprise
displayed_sidebar: docsEnglish
---
# Configure a custom values file for ScalarDL Schema Loader
This document explains how to create your custom values file for the ScalarDL Schema Loader chart. If you want to know the details of the parameters, please refer to the [README](https://github.com/scalar-labs/helm-charts/blob/main/charts/schema-loading/README.md) of the ScalarDL Schema Loader chart.
## Required configurations
### Database configurations
You must set `schemaLoading.databaseProperties`. Please set your `database.properties` to access the backend database to this parameter. Please refer to the [Getting Started with ScalarDB](https://scalardb.scalar-labs.com/docs/latest/getting-started-with-scalardb) for more details on the database configuration of ScalarDB.
```yaml
schemaLoading:
databaseProperties: |
scalar.db.contact_points=cassandra
scalar.db.contact_port=9042
scalar.db.username=cassandra
scalar.db.password=cassandra
scalar.db.storage=cassandra
```
### Schema type configurations
You must set `schemaLoading.schemaType`.
If you create the schema of ScalarDL Ledger, please set `ledger`.
```yaml
schemaLoading:
schemaType: ledger
```
If you create the schema of ScalarDL Auditor, please set `auditor`.
```yaml
schemaLoading:
schemaType: auditor
```
## Optional configurations
### Secret configurations (Recommended in the production environment)
If you want to use environment variables to set some properties (e.g., credentials) in the `schemaLoading.databaseProperties`, you can use `schemaLoading.secretName` to specify the Secret resource that includes some credentials.
For example, you can set credentials for a backend database (`scalar.db.username` and `scalar.db.password`) using environment variables, which makes your pods more secure.
Please refer to the document [How to use Secret resources to pass the credentials as the environment variables into the properties file](use-secret-for-credentials.mdx) for more details on how to use a Secret resource.
```yaml
schemaLoading:
secretName: "schema-loader-credentials-secret"
```
### Image configurations (Default value is recommended)
If you want to change the image repository, you can use `schemaLoading.image.repository` to specify which repository you want to use to pull the ScalarDL Schema Loader container image from.
```yaml
schemaLoading:
image:
repository:
```
### Flags configurations (Optional based on your environment)
You can specify several flags as an array. Please refer to the document [ScalarDB Schema Loader](https://scalardb.scalar-labs.com/docs/latest/schema-loader) for more details on the flags.
```yaml
schemaLoading:
commandArgs:
- "--alter"
- "--compaction-strategy"
- ""
- "--delete-all"
- "--no-backup"
- "--no-scaling"
- "--repair-all"
- "--replication-factor"
- ""
- "--replication-strategy"
- ""
- "--ru"
- ""
```
================================================
FILE: docs/helm-charts/getting-started-logging.mdx
================================================
---
tags:
- Community
displayed_sidebar: docsEnglish
---
# Getting Started with Helm Charts (Logging using Loki Stack)
This document explains how to get started with log aggregation for Scalar products on Kubernetes using Grafana Loki (with Promtail).
We assume that you have already read the [getting-started with monitoring](getting-started-monitoring.mdx) for Scalar products and installed kube-prometheus-stack.
## What we create
We will deploy the following components on a Kubernetes cluster as follows.
```
+--------------------------------------------------------------------------------------------------+
| +------------------------------------+ |
| | loki-stack | |
| | | +-----------------+ |
| | +--------------+ +--------------+ | <-----------------(Log)-------------- | Scalar Products | |
| | | Loki | | Promtail | | | | |
| | +--------------+ +--------------+ | | +-----------+ | |
| +------------------------------------+ | | ScalarDB | | |
| | +-----------+ | |
| +------------------------------------------------------+ | | |
| | kube-prometheus-stack | | +-----------+ | |
| | | | | ScalarDL | | |
| | +--------------+ +--------------+ +--------------+ | -----(Monitor)----> | +-----------+ | |
| | | Prometheus | | Alertmanager | | Grafana | | +-----------------+ |
| | +-------+------+ +------+-------+ +------+-------+ | |
| | | | | | |
| | +----------------+-----------------+ | |
| | | | |
| +--------------------------+---------------------------+ |
| | |
| | Kubernetes |
+----------------------------+---------------------------------------------------------------------+
| <- expose to localhost (127.0.0.1) or use load balancer etc to access
|
(Access Dashboard through HTTP)
|
+----+----+
| Browser |
+---------+
```
## Step 1. Prepare a custom values file
1. Get the sample file [scalar-loki-stack-custom-values.yaml](conf/scalar-loki-stack-custom-values.yaml) for the `loki-stack` helm chart.
## Step 2. Deploy `loki-stack`
1. Add the `grafana` helm repository.
```console
helm repo add grafana https://grafana.github.io/helm-charts
```
1. Deploy the `loki-stack` helm chart.
```console
helm install scalar-logging-loki grafana/loki-stack -n monitoring -f scalar-loki-stack-custom-values.yaml
```
## Step 3. Add a Loki data source in the Grafana configuration
1. Add a configuration of the Loki data source in the `scalar-prometheus-custom-values.yaml` file.
```yaml
grafana:
additionalDataSources:
- name: Loki
type: loki
uid: loki
url: http://scalar-logging-loki:3100/
access: proxy
editable: false
isDefault: false
```
1. Apply the configuration (upgrade the deployment of `kube-prometheus-stack`).
```console
helm upgrade scalar-monitoring prometheus-community/kube-prometheus-stack -n monitoring -f scalar-prometheus-custom-values.yaml
```
## Step 4. Access the Grafana dashboard
1. Add Loki as a data source
- Go to Grafana http://localhost:3000 (If you use minikube)
- Go to `Explore` to find the added Loki
- You can see the collected logs in the `Explore` page
## Step 5. Delete the `loki-stack` helm chart
1. Uninstall `loki-stack`.
```console
helm uninstall scalar-logging-loki -n monitoring
```
================================================
FILE: docs/helm-charts/getting-started-monitoring.mdx
================================================
---
tags:
- Community
displayed_sidebar: docsEnglish
---
# Getting Started with Helm Charts (Monitoring using Prometheus Operator)
This document explains how to get started with Scalar products monitoring on Kubernetes using Prometheus Operator (kube-prometheus-stack). Here, we assume that you already have a Mac or Linux environment for testing. We use **Minikube** in this document, but the steps we will show should work in any Kubernetes cluster.
## What we create
We will deploy the following components on a Kubernetes cluster as follows.
```
+--------------------------------------------------------------------------------------------------+
| +------------------------------------------------------+ +-----------------+ |
| | kube-prometheus-stack | | Scalar Products | |
| | | | | |
| | +--------------+ +--------------+ +--------------+ | -----(Monitor)----> | +-----------+ | |
| | | Prometheus | | Alertmanager | | Grafana | | | | ScalarDB | | |
| | +-------+------+ +------+-------+ +------+-------+ | | +-----------+ | |
| | | | | | | +-----------+ | |
| | +----------------+-----------------+ | | | ScalarDL | | |
| | | | | +-----------+ | |
| +--------------------------+---------------------------+ +-----------------+ |
| | |
| | Kubernetes |
+----------------------------+---------------------------------------------------------------------+
| <- expose to localhost (127.0.0.1) or use load balancer etc to access
|
(Access Dashboard through HTTP)
|
+----+----+
| Browser |
+---------+
```
## Step 1. Start a Kubernetes cluster
First, you need to prepare a Kubernetes cluster. If you use a **minikube** environment, please refer to the [Getting Started with Scalar Helm Charts](getting-started-scalar-helm-charts.mdx). If you have already started a Kubernetes cluster, you can skip this step.
## Step 2. Prepare a custom values file
1. Save the sample file [scalar-prometheus-custom-values.yaml](conf/scalar-prometheus-custom-values.yaml) for `kube-prometheus-stack`.
1. Add custom values in the `scalar-prometheus-custom-values.yaml` as follows.
* settings
* `prometheus.service.type` to `LoadBalancer`
* `alertmanager.service.type` to `LoadBalancer`
* `grafana.service.type` to `LoadBalancer`
* `grafana.service.port` to `3000`
* Example
```yaml
alertmanager:
service:
type: LoadBalancer
...
grafana:
service:
type: LoadBalancer
port: 3000
...
prometheus:
service:
type: LoadBalancer
...
```
* Note:
* If you want to customize the Prometheus Operator deployment by using Helm Charts, you'll need to set the following configurations to monitor Scalar products:
* Set `serviceMonitorSelectorNilUsesHelmValues` and `ruleSelectorNilUsesHelmValues` to `false` (`true` by default) so that Prometheus Operator can detect `ServiceMonitor` and `PrometheusRule` for Scalar products.
* If you want to use Scalar Manager, you'll need to set the following configurations to enable Scalar Manager to collect CPU and memory resources:
* Set `kubeStateMetrics.enabled`, `nodeExporter.enabled`, and `kubelet.enabled` to `true`.
* If you want to use Scalar Manager, you'll need to set the following configurations to enable Scalar Manager to embed Grafana:
* Set `grafana.ini.security.allow_embedding` and `grafana.ini.auth.anonymous.enabled` to `true`.
* Set `grafana.ini.auth.anonymous.org_name` to the organization you are using. If you're using the sample custom values, the value is `Main Org.`.
* Set `grafana.ini.auth.anonymous.org_role` to `Editor`.
## Step 3. Deploy `kube-prometheus-stack`
1. Add the `prometheus-community` helm repository.
```console
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
```
1. Create a namespace `monitoring` on the Kubernetes.
```console
kubectl create namespace monitoring
```
1. Deploy the `kube-prometheus-stack`.
```console
helm install scalar-monitoring prometheus-community/kube-prometheus-stack -n monitoring -f scalar-prometheus-custom-values.yaml
```
## Step 4. Deploy (or Upgrade) Scalar products using Helm Charts
* Note:
* The following explains the minimum steps. If you want to know more details about the deployment of ScalarDB and ScalarDL, please refer to the following documents.
* [Getting Started with Helm Charts (ScalarDB Server)](getting-started-scalardb.mdx)
* [Getting Started with Helm Charts (ScalarDL Ledger / Ledger only)](getting-started-scalardl-ledger.mdx)
* [Getting Started with Helm Charts (ScalarDL Ledger and Auditor / Auditor mode)](getting-started-scalardl-auditor.mdx)
1. To enable Prometheus monitoring of Scalar products, set `true` to the following configurations in the custom values file.
* Configurations
* `*.prometheusRule.enabled`
* `*.grafanaDashboard.enabled`
* `*.serviceMonitor.enabled`
* Sample configuration files
* ScalarDB (scalardb-custom-values.yaml)
```yaml
envoy:
prometheusRule:
enabled: true
grafanaDashboard:
enabled: true
serviceMonitor:
enabled: true
scalardb:
prometheusRule:
enabled: true
grafanaDashboard:
enabled: true
serviceMonitor:
enabled: true
```
* ScalarDL Ledger (scalardl-ledger-custom-values.yaml)
```yaml
envoy:
prometheusRule:
enabled: true
grafanaDashboard:
enabled: true
serviceMonitor:
enabled: true
ledger:
prometheusRule:
enabled: true
grafanaDashboard:
enabled: true
serviceMonitor:
enabled: true
```
* ScalarDL Auditor (scalardl-auditor-custom-values.yaml)
```yaml
envoy:
prometheusRule:
enabled: true
grafanaDashboard:
enabled: true
serviceMonitor:
enabled: true
auditor:
prometheusRule:
enabled: true
grafanaDashboard:
enabled: true
serviceMonitor:
enabled: true
```
1. Deploy (or Upgrade) Scalar products using Helm Charts with the above custom values file.
* Examples
* ScalarDB
```console
helm install scalardb scalar-labs/scalardb -f ./scalardb-custom-values.yaml
```
```console
helm upgrade scalardb scalar-labs/scalardb -f ./scalardb-custom-values.yaml
```
* ScalarDL Ledger
```console
helm install scalardl-ledger scalar-labs/scalardl -f ./scalardl-ledger-custom-values.yaml
```
```console
helm upgrade scalardl-ledger scalar-labs/scalardl -f ./scalardl-ledger-custom-values.yaml
```
* ScalarDL Auditor
```console
helm install scalardl-auditor scalar-labs/scalardl-audit -f ./scalardl-auditor-custom-values.yaml
```
```console
helm upgrade scalardl-auditor scalar-labs/scalardl-audit -f ./scalardl-auditor-custom-values.yaml
```
## Step 5. Access Dashboards
### If you use minikube
1. To expose each service resource as your `localhost (127.0.0.1)`, open another terminal, and run the `minikube tunnel` command.
```console
minikube tunnel
```
After running the `minikube tunnel` command, you can see the EXTERNAL-IP of each service resource as `127.0.0.1`.
```console
kubectl get svc -n monitoring scalar-monitoring-kube-pro-prometheus scalar-monitoring-kube-pro-alertmanager scalar-monitoring-grafana
```
[Command execution result]
```console
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
scalar-monitoring-kube-pro-prometheus LoadBalancer 10.98.11.12 127.0.0.1 9090:30550/TCP 26m
scalar-monitoring-kube-pro-alertmanager LoadBalancer 10.98.151.66 127.0.0.1 9093:31684/TCP 26m
scalar-monitoring-grafana LoadBalancer 10.103.19.4 127.0.0.1 3000:31948/TCP 26m
```
1. Access each Dashboard.
* Prometheus
```console
http://localhost:9090/
```
* Alertmanager
```console
http://localhost:9093/
```
* Grafana
```console
http://localhost:3000/
```
* Note:
* You can see the user and password of Grafana as follows.
* user
```console
kubectl get secrets scalar-monitoring-grafana -n monitoring -o jsonpath='{.data.admin-user}' | base64 -d
```
* password
```console
kubectl get secrets scalar-monitoring-grafana -n monitoring -o jsonpath='{.data.admin-password}' | base64 -d
```
### If you use other Kubernetes than minikube
If you use a Kubernetes cluster other than minikube, you need to access the LoadBalancer service according to the manner of each Kubernetes cluster. For example, using a Load Balancer provided by cloud service or the `kubectl port-forward` command.
## Step 6. Delete all resources
After completing the Monitoring tests on the Kubernetes cluster, remove all resources.
1. Terminate the `minikube tunnel` command. (If you use minikube)
```console
Ctrl + C
```
1. Uninstall `kube-prometheus-stack`.
```console
helm uninstall scalar-monitoring -n monitoring
```
1. Delete minikube. (Optional / If you use minikube)
```console
minikube delete --all
```
* Note:
* If you deploy the ScalarDB or ScalarDL, you need to remove them before deleting minikube.
================================================
FILE: docs/helm-charts/getting-started-scalar-helm-charts.mdx
================================================
---
tags:
- Enterprise Standard
- Enterprise Premium
displayed_sidebar: docsEnglish
---
# Getting Started with Scalar Helm Charts
This document explains how to get started with Scalar Helm Chart on a Kubernetes cluster as a test environment. Here, we assume that you already have a Mac or Linux environment for testing. We use **Minikube** in this document, but the steps we will show should work in any Kubernetes cluster.
## Tools
We will use the following tools for testing.
1. minikube (If you use other Kubernetes distributions, minikube is not necessary.)
1. kubectl
1. Helm
1. cfssl / cfssljson
## Step 1. Install tools
First, you need to install the following tools used in this guide.
1. Install the `minikube` command according to the [minikube documentation](https://minikube.sigs.k8s.io/docs/start/)
1. Install the `kubectl` command according to the [Kubernetes documentation](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/)
1. Install the `helm` command according to the [Helm documentation](https://helm.sh/docs/intro/install/)
1. Install the `cfssl` and `cfssljson` according to the [CFSSL documentation](https://github.com/cloudflare/cfssl)
:::note
You need to install the `cfssl` and `cfssljson` command when following these getting started guides:
* [ScalarDB Cluster with TLS](getting-started-scalardb-cluster-tls.mdx)
* [ScalarDL Ledger and Auditor with TLS (Auditor mode)](getting-started-scalardl-auditor-tls.mdx)
* [ScalarDL Ledger (Ledger only)](getting-started-scalardl-ledger.mdx)
* [ScalarDL Ledger and Auditor (Auditor mode)](getting-started-scalardl-auditor.mdx)
:::
## Step 2. Start minikube with docker driver (Optional / If you use minikube)
1. Start minikube.
```console
minikube start
```
1. Check the status of the minikube and pods.
```console
kubectl get pod -A
```
[Command execution result]
```console
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-64897985d-lbsfr 1/1 Running 1 (20h ago) 21h
kube-system etcd-minikube 1/1 Running 1 (20h ago) 21h
kube-system kube-apiserver-minikube 1/1 Running 1 (20h ago) 21h
kube-system kube-controller-manager-minikube 1/1 Running 1 (20h ago) 21h
kube-system kube-proxy-gsl6j 1/1 Running 1 (20h ago) 21h
kube-system kube-scheduler-minikube 1/1 Running 1 (20h ago) 21h
kube-system storage-provisioner 1/1 Running 2 (19s ago) 21h
```
If the minikube starts properly, you can see some pods are **Running** in the kube-system namespace.
## Step 3.
After the Kubernetes cluster starts, you can try each Scalar Helm Charts on it. Please refer to the following documents for more details.
* [ScalarDB Cluster with TLS](getting-started-scalardb-cluster-tls.mdx)
* [ScalarDB Cluster with TLS by Using cert-manager](getting-started-scalardb-cluster-tls-cert-manager.mdx)
* [ScalarDL Ledger and Auditor with TLS (Auditor mode)](getting-started-scalardl-auditor-tls.mdx)
* [ScalarDL Ledger and Auditor with TLS by Using cert-manager (Auditor mode)](getting-started-scalardl-auditor-tls-cert-manager.mdx)
* [ScalarDL Ledger (Ledger only)](getting-started-scalardl-ledger.mdx)
* [ScalarDL Ledger and Auditor (Auditor mode)](getting-started-scalardl-auditor.mdx)
* [Monitoring using Prometheus Operator](getting-started-monitoring.mdx)
* [Logging using Loki Stack](getting-started-logging.mdx)
* [Scalar Manager](getting-started-scalar-manager.mdx)
* [[Deprecated] ScalarDB Server](getting-started-scalardb.mdx)
================================================
FILE: docs/helm-charts/getting-started-scalar-manager.mdx
================================================
---
tags:
- Enterprise Option
displayed_sidebar: docsEnglish
---
# Deploy Scalar Manager
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
[Scalar Manager](../scalar-manager/overview.mdx) is a centralized management and monitoring solution for ScalarDB and ScalarDL in Kubernetes clusters. It enables you to:
- Monitor the availability of ScalarDB and ScalarDL.
- Schedule and execute pausing jobs to create transactionally consistent periods in the databases used by ScalarDB and ScalarDL.
- Monitor ScalarDB and ScalarDL time-series metrics and logs through Grafana dashboards.
This guide explains how to deploy and access Scalar Manager on a Kubernetes cluster using Scalar Helm Charts.
## Prerequisites
Before deploying Scalar Manager, you must do the following:
- Install the tools mentioned in [Getting Started with Scalar Helm Charts](getting-started-scalar-helm-charts.mdx).
- Deploy `kube-prometheus-stack` as instructed in [Getting Started with Helm Charts (Monitoring using Prometheus Operator)](getting-started-monitoring.mdx).
- Deploy `loki-stack` as instructed in [Getting Started with Helm Charts (Logging using Loki Stack)](getting-started-logging.mdx).
- Have a running PostgreSQL database, either self-managed or from a cloud service provider. This database stores the data of Scalar Manager. For example, you can use the [Bitnami package for PostgreSQL](https://artifacthub.io/packages/helm/bitnami/postgresql) to deploy a PostgreSQL database in your Kubernetes cluster.
## Deployment architecture diagram
The following is an architecture diagram for the components deployed in a Kubernetes cluster.
```
+----------------------------------------------------------------------------------------------------------------------+
| +----------------------------+ |
| | scalar-manager | |
| | | |
| | +------------------+ | ---------------------------------(Manage)--------------------------+ |
| +---+--->| Scalar Manager | | | |
| | | +---+--------------+ | | |
| | | | | | |
| | +--------+-------------------+ | |
| | | | |
| | +----+------------------------------------------+ | |
| | | | | |
| | +--------+------------------------------------------+---------+ | |
| | | | kube-prometheus-stack | | V |
| | | V V | +-----------------+ |
| | | +--------------+ +--------------+ +--------------+ | -----(Monitor)----> | Scalar Products | |
| | | | Prometheus | <---+ | Alertmanager | | Grafana | | | | |
| | | +------+-------+ | +--------------+ +------+-------+ | | +-----------+ | |
| | | | | | | | ScalarDB | | |
| | | +----------------------------+ | | +-----------+ | |
| | | | | | | |
| | +---------------------------------------------------+---------+ | +-----------+ | |
| | | | | ScalarDL | | |
| | +------------------------------------------+ +---------- | +-----------+ | |
| | | | +-----------------+ |
| | +--------+---------------------------+ | |
| | | | loki-stack | | |
| | | V | | |
| | | +--------------+ +--------------+ | <----------------(Log)-----------+ |
| | | | Loki | | Promtail | | |
| | | +--------------+ +--------------+ | |
| | +------------------------------------+ |
| | |
| | Kubernetes |
+----+-----------------------------------------------------------------------------------------------------------------+
|
Expose the environment to localhost (127.0.0.1) or use a load balancer to access it
|
(Access the dashboard through HTTP)
|
+----+----+
| Browser |
+---------+
```
## Step 1. Start minikube
Open **Terminal**, and start minikube by running the following command:
```console
minikube start
```
## Step 2. Upgrade `kube-prometheus-stack` to enable Grafana authentication with auth proxy
To allow users to access Grafana after logging in to Scalar Manager, you must enable Grafana authentication with auth proxy.
In your custom values file for `kube-prometheus-stack` (for example, `scalar-prometheus-custom-values.yaml`), add or revise the following configurations:
```yaml
kubeStateMetrics:
enabled: true
nodeExporter:
enabled: true
kubelet:
enabled: true
grafana:
grafana.ini:
users:
allow_sign_up: false
auto_assign_org: true
auto_assign_org_role: Editor
auth.proxy:
enabled: true
header_name: X-WEBAUTH-USER
header_property: username
auto_sign_up: true
server:
root_url: "%(protocol)s://%(domain)s:%(http_port)s/grafana"
```
Then, upgrade the Helm installation by running the following command:
```console
helm upgrade scalar-monitoring prometheus-community/kube-prometheus-stack -n monitoring -f scalar-prometheus-custom-values.yaml
```
## Step 3. Set environment variables
Set the following environment variables for Scalar Manager, replacing the contents in the angle brackets as described:
```console
SCALAR_MANAGER_RELEASE_NAME=
SCALAR_MANAGER_NAMESPACE=
SCALAR_MANAGER_CUSTOM_VALUES_FILE=
SCALAR_MANAGER_CHART_VERSION=
```
## Step 4. Prepare a custom values file
Prepare a custom values file for Scalar Manager:
1. Create an empty file named `scalar-manager-custom-values.yaml`.
2. Follow the instructions in [Configure a custom values file for Scalar Manager](configure-custom-values-scalar-manager.mdx).
## Step 5. Deploy
Deploy the `scalar-manager` Helm Chart by running the following command:
```console
helm install ${SCALAR_MANAGER_RELEASE_NAME} scalar-labs/scalar-manager -n ${SCALAR_MANAGER_NAMESPACE} -f ${SCALAR_MANAGER_CUSTOM_VALUES_FILE} --version ${SCALAR_MANAGER_CHART_VERSION}
```
## Step 6. Access Scalar Manager
The method to access Scalar Manager depends on your Kubernetes cluster.
To expose Scalar Manager on localhost (127.0.0.1), open another terminal and run the `minikube tunnel` command:
```console
minikube tunnel
```
Then, access Scalar Manager at http://localhost:8000.
If you're using a Kubernetes cluster other than minikube, access the `LoadBalancer` service according to your cluster's instructions. For example, use a load balancer from your cloud service provider or use the `kubectl port-forward` command.
## Additional details
This section provides additional details related to configurations and resource discovery.
### Upgrade Scalar Manager
To upgrade Scalar Manager, run the following command:
```console
helm upgrade ${SCALAR_MANAGER_RELEASE_NAME} scalar-labs/scalar-manager -n ${SCALAR_MANAGER_NAMESPACE} -f ${SCALAR_MANAGER_CUSTOM_VALUES_FILE} --version ${SCALAR_MANAGER_CHART_VERSION}
```
### Uninstall Scalar Manager
To uninstall Scalar Manager, run the following command:
```console
helm uninstall ${SCALAR_MANAGER_RELEASE_NAME} -n ${SCALAR_MANAGER_NAMESPACE}
```
### Optional Scalar Manager configurations
For optional configurations that you can set for Scalar Manager, see [Optional configurations](./configure-custom-values-scalar-manager.mdx#optional-configurations)
### Resource discovery
Scalar Manager discovers the following Kubernetes resources in a cluster by using specific label selectors:
- Dependencies
- Prometheus service
- Targets
- ScalarDB Cluster deployments
- ScalarDL Ledger deployments
- ScalarDL Auditor deployments
The following sections explain how Scalar Manager discovers these resources.
#### Dependencies
Scalar Manager searches for the default labels and values set in the [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack) Helm Chart. For more information on the default labels and values that Scalar Manager uses to discover dependencies, see [Properties that you can set in `api.applicationProperties`](./configure-custom-values-scalar-manager.mdx#properties-that-you-can-set-in-apiapplicationProperties).
Also, if you customized any values when installing `kube-prometheus-stack`, you will need to update the label selectors in the Scalar Manager custom value `api.applicationProperties`.
#### Targets
Scalar Manager searches for ScalarDB Cluster, ScalarDL Ledger, and ScalarDL Auditor deployments by using the following labels and values:
- **ScalarDB Cluster:** `app.kubernetes.io/app=scalardb-cluster`
- **ScalarDL Ledger:** `app.kubernetes.io/app=ledger`
- **ScalarDL Auditor:** `app.kubernetes.io/app=auditor`
Scalar Helm Charts use fixed labels and values for ScalarDB Cluster, ScalarDL Ledger, and ScalarDL Auditor deployments so that if you install ScalarDB and ScalarDL by using [Scalar Helm Charts](https://github.com/scalar-labs/helm-charts), Scalar Manager will automatically discover these deployments.
================================================
FILE: docs/helm-charts/getting-started-scalardb-cluster-tls-cert-manager.mdx
================================================
---
tags:
- Enterprise Standard
- Enterprise Premium
displayed_sidebar: docsEnglish
---
# Getting Started with Helm Charts (ScalarDB Cluster with TLS by Using cert-manager)
This tutorial explains how to get started with ScalarDB Cluster with TLS configurations by using Helm Charts and cert-manager on a Kubernetes cluster in a test environment. Before starting, you should already have a Mac or Linux environment for testing. In addition, although this tutorial mentions using **minikube**, the steps described should work in any Kubernetes cluster.
## Requirements
* You need to have a license key (trial license or commercial license) for ScalarDB Cluster. If you don't have a license key, please [contact us](https://www.scalar-labs.com/contact).
* You need to use ScalarDB Cluster 3.12 or later, which supports TLS.
## What you'll create
In this tutorial, you'll deploy the following components on a Kubernetes cluster in the following way:
```
+----------------------------------------------------------------------------------------------------------------------------------------------------+
| [Kubernetes Cluster] |
| [Pod] [Pod] [Pod] |
| |
| +-------+ +------------------------+ |
| +---> | Envoy | ---+ +---> | ScalarDB Cluster node | ---+ |
| [Pod] | +-------+ | | +------------------------+ | |
| | | | | |
| +-----------+ +---------+ | +-------+ | +--------------------+ | +------------------------+ | +---------------+ |
| | Client | ---> | Service | ---+---> | Envoy | ---+---> | Service | ---+---> | ScalarDB Cluster node | ---+---> | PostgreSQL | |
| | (SQL CLI) | | (Envoy) | | +-------+ | | (ScalarDB Cluster) | | +------------------------+ | | (For Ledger) | |
| +-----------+ +---------+ | | +--------------------+ | | +---------------+ |
| | +-------+ | | +------------------------+ | |
| +---> | Envoy | ---+ +---> | ScalarDB Cluster node | ---+ |
| +-------+ +------------------------+ |
| |
| +----------------------------------------------------------------------------------+ +---------------------+ |
| | cert-manager (create private key and certificate for Envoy and ScalarDB Cluster) | | Issuer (Private CA) | |
| +----------------------------------------------------------------------------------+ +---------------------+ |
| |
+----------------------------------------------------------------------------------------------------------------------------------------------------+
```
cert-manager automatically creates the following private key and certificate files for TLS connections.
```
+----------------------+
+---> | For Scalar Envoy |
| +----------------------+
| | tls.key |
| | tls.crt |
+-------------------------+ | +----------------------+
| Issuer (Self-signed CA) | ---(Sign certificates)---+
+-------------------------+ | +----------------------+
| tls.key | +---> | For ScalarDB Cluster |
| tls.crt | +----------------------+
| ca.crt | | tls.key |
+-------------------------+ | tls.crt |
+----------------------+
```
Scalar Helm Charts automatically mount each private key and certificate file for Envoy and ScalarDB Cluster as follows to enable TLS in each connection. You'll manually mount a root CA certificate file on the client.
```
+-------------------------------------+ +------------------------------------------------+ +--------------------------------+
| Client | ---(CRUD/SQL requests)---> | Envoy for ScalarDB Cluster | ---> | ScalarDB Cluster nodes |
+-------------------------------------+ +------------------------------------------------+ +--------------------------------+
| ca.crt (to verify tls.crt of Envoy) | | tls.key | | tls.key |
+-------------------------------------+ | tls.crt | | tls.crt |
| ca.crt (to verify tls.crt of ScalarDB Cluster) | | ca.crt (to check health) |
+------------------------------------------------+ +--------------------------------+
```
The following connections exist amongst the ScalarDB Cluster–related components:
* **`Client - Envoy for ScalarDB Cluster`:** When you execute a CRUD API or SQL API function, the client accesses Envoy for ScalarDB Cluster.
* **`Envoy for ScalarDB Cluster - ScalarDB Cluster`:** Envoy works as an L7 (gRPC) load balancer in front of ScalarDB Cluster.
* **`ScalarDB Cluster node - ScalarDB Cluster node`:** A ScalarDB Cluster node accesses other ScalarDB Cluster nodes. In other words, the cluster's internal communications exist amongst all ScalarDB Cluster nodes.
## Step 1. Start a Kubernetes cluster and install tools
You need to prepare a Kubernetes cluster and install some tools (`kubectl`, `helm`, `cfssl`, and `cfssljson`). For more details on how to install them, see [Getting Started with Scalar Helm Charts](getting-started-scalar-helm-charts.mdx).
## Step 2. Start the PostgreSQL containers
ScalarDB Cluster must use some type of database system as a backend database. In this tutorial, you'll use PostgreSQL.
You can deploy PostgreSQL on the Kubernetes cluster as follows:
1. Add the Bitnami helm repository.
```console
helm repo add bitnami https://charts.bitnami.com/bitnami
```
1. Deploy PostgreSQL for ScalarDB Cluster.
```console
helm install postgresql-scalardb-cluster bitnami/postgresql \
--set auth.postgresPassword=postgres \
--set primary.persistence.enabled=false \
-n default
```
1. Check if the PostgreSQL containers are running.
```console
kubectl get pod -n default
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-scalardb-cluster-0 1/1 Running 0 34s
```
## Step 3. Create a working directory
You'll create some configuration files locally. Be sure to create a working directory for those files.
1. Create a working directory.
```console
mkdir -p ${HOME}/scalardb-cluster-test/
```
## Step 4. Deploy cert-manager and issuer resource
This tutorial uses cert-manager to issue and manage your private keys and certificates. You can deploy cert-manager on the Kubernetes cluster as follows:
1. Add the Jetstack helm repository.
```console
helm repo add jetstack https://charts.jetstack.io
```
1. Deploy cert-manager.
```console
helm install cert-manager jetstack/cert-manager \
--create-namespace \
--set installCRDs=true \
-n cert-manager
```
1. Check if the cert-manager containers are running.
```console
kubectl get pod -n cert-manager
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
cert-manager-6dc66985d4-6lvtt 1/1 Running 0 26s
cert-manager-cainjector-c7d4dbdd9-xlrpn 1/1 Running 0 26s
cert-manager-webhook-847d7676c9-ckcz2 1/1 Running 0 26s
```
1. Change the working directory to `${HOME}/scalardb-cluster-test/`.
```console
cd ${HOME}/scalardb-cluster-test/
```
1. Create a custom values file for the private CA (`private-ca-custom-values.yaml`).
```console
cat << 'EOF' > ${HOME}/scalardb-cluster-test/private-ca-custom-values.yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: self-signed-issuer
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: self-signed-ca-cert
spec:
isCA: true
commonName: self-signed-ca
secretName: self-signed-ca-cert-secret
privateKey:
algorithm: ECDSA
size: 256
issuerRef:
name: self-signed-issuer
kind: Issuer
group: cert-manager.io
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: self-signed-ca
spec:
ca:
secretName: self-signed-ca-cert-secret
EOF
```
1. Deploy a self-signed CA.
```console
kubectl apply -f ./private-ca-custom-values.yaml
```
1. Check if the issuer resources are `True`.
```console
kubectl get issuer
```
[Command execution result]
```console
NAME READY AGE
self-signed-ca True 6s
self-signed-issuer True 6s
```
## Step 5. Deploy ScalarDB Cluster on the Kubernetes cluster by using Helm Charts
1. Add the Scalar Helm Charts repository.
```console
helm repo add scalar-labs https://scalar-labs.github.io/helm-charts
```
1. Set your license key and certificate as environment variables. If you don't have a license key, please [contact us](https://www.scalar-labs.com/contact). For details about the value of ``, see [How to Configure a License Key](../scalar-licensing/index.mdx).
```console
SCALAR_DB_CLUSTER_LICENSE_KEY=''
SCALAR_DB_CLUSTER_LICENSE_CHECK_CERT_PEM=''
```
1. Create a custom values file for ScalarDB Cluster (`scalardb-cluster-custom-values.yaml`).
```console
cat << 'EOF' > ${HOME}/scalardb-cluster-test/scalardb-cluster-custom-values.yaml
envoy:
enabled: true
tls:
downstream:
enabled: true
certManager:
enabled: true
issuerRef:
name: self-signed-ca
dnsNames:
- envoy.scalar.example.com
upstream:
enabled: true
overrideAuthority: "cluster.scalardb.example.com"
scalardbCluster:
image:
repository: "ghcr.io/scalar-labs/scalardb-cluster-node-byol-premium"
scalardbClusterNodeProperties: |
### Necessary configurations for deployment on Kuberetes
scalar.db.cluster.membership.type=KUBERNETES
scalar.db.cluster.membership.kubernetes.endpoint.namespace_name=${env:SCALAR_DB_CLUSTER_MEMBERSHIP_KUBERNETES_ENDPOINT_NAMESPACE_NAME}
scalar.db.cluster.membership.kubernetes.endpoint.name=${env:SCALAR_DB_CLUSTER_MEMBERSHIP_KUBERNETES_ENDPOINT_NAME}
### Storage configurations
scalar.db.contact_points=jdbc:postgresql://postgresql-scalardb-cluster.default.svc.cluster.local:5432/postgres
scalar.db.username=${env:SCALAR_DB_CLUSTER_POSTGRES_USERNAME}
scalar.db.password=${env:SCALAR_DB_CLUSTER_POSTGRES_PASSWORD}
scalar.db.storage=jdbc
### SQL configurations
scalar.db.sql.enabled=true
### Auth configurations
scalar.db.cluster.auth.enabled=true
scalar.db.cross_partition_scan.enabled=true
### TLS configurations
scalar.db.cluster.tls.enabled=true
scalar.db.cluster.tls.ca_root_cert_path=/tls/scalardb-cluster/certs/ca.crt
scalar.db.cluster.node.tls.cert_chain_path=/tls/scalardb-cluster/certs/tls.crt
scalar.db.cluster.node.tls.private_key_path=/tls/scalardb-cluster/certs/tls.key
scalar.db.cluster.tls.override_authority=cluster.scalardb.example.com
### License key configurations
scalar.db.cluster.node.licensing.license_key=${env:SCALAR_DB_CLUSTER_LICENSE_KEY}
scalar.db.cluster.node.licensing.license_check_cert_pem=${env:SCALAR_DB_CLUSTER_LICENSE_CHECK_CERT_PEM}
tls:
enabled: true
overrideAuthority: "cluster.scalardb.example.com"
certManager:
enabled: true
issuerRef:
name: self-signed-ca
dnsNames:
- cluster.scalardb.example.com
secretName: "scalardb-credentials-secret"
EOF
```
1. Create a secret resource named `scalardb-credentials-secret` that includes credentials and license keys.
```console
kubectl create secret generic scalardb-credentials-secret \
--from-literal=SCALAR_DB_CLUSTER_POSTGRES_USERNAME=postgres \
--from-literal=SCALAR_DB_CLUSTER_POSTGRES_PASSWORD=postgres \
--from-literal=SCALAR_DB_CLUSTER_LICENSE_KEY="${SCALAR_DB_CLUSTER_LICENSE_KEY}" \
--from-file=SCALAR_DB_CLUSTER_LICENSE_CHECK_CERT_PEM=<(echo ${SCALAR_DB_CLUSTER_LICENSE_CHECK_CERT_PEM} | sed 's/\\n/\
/g') \
-n default
```
1. Set the chart version of ScalarDB Cluster.
```console
SCALAR_DB_CLUSTER_VERSION=3.12.2
SCALAR_DB_CLUSTER_CHART_VERSION=$(helm search repo scalar-labs/scalardb-cluster -l | grep -F "${SCALAR_DB_CLUSTER_VERSION}" | awk '{print $2}' | sort --version-sort -r | head -n 1)
```
1. Deploy ScalarDB Cluster.
```console
helm install scalardb-cluster scalar-labs/scalardb-cluster -f ${HOME}/scalardb-cluster-test/scalardb-cluster-custom-values.yaml --version ${SCALAR_DB_CLUSTER_CHART_VERSION} -n default
```
1. Check if the ScalarDB Cluster pods are deployed.
```console
kubectl get pod -n default
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-scalardb-cluster-0 1/1 Running 0 4m30s
scalardb-cluster-envoy-7cc948dfb-4rb8l 1/1 Running 0 18s
scalardb-cluster-envoy-7cc948dfb-hwt96 1/1 Running 0 18s
scalardb-cluster-envoy-7cc948dfb-rzbrx 1/1 Running 0 18s
scalardb-cluster-node-7c6959c79d-445kj 1/1 Running 0 18s
scalardb-cluster-node-7c6959c79d-4z54q 1/1 Running 0 18s
scalardb-cluster-node-7c6959c79d-vcv96 1/1 Running 0 18s
```
If the ScalarDB Cluster pods are deployed properly, the `STATUS` column for those pods will be displayed as `Running`.
1. Check if the ScalarDB Cluster services are deployed.
```console
kubectl get svc -n default
```
[Command execution result]
```console
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 7h34m
postgresql-scalardb-cluster ClusterIP 10.96.92.27 5432/TCP 4m52s
postgresql-scalardb-cluster-hl ClusterIP None 5432/TCP 4m52s
scalardb-cluster-envoy ClusterIP 10.96.250.175 60053/TCP 40s
scalardb-cluster-envoy-metrics ClusterIP 10.96.40.197 9001/TCP 40s
scalardb-cluster-headless ClusterIP None 60053/TCP 40s
scalardb-cluster-metrics ClusterIP 10.96.199.135 9080/TCP 40s
```
If the ScalarDB Cluster services are deployed properly, you can see private IP addresses in the `CLUSTER-IP` column.
:::note
The `CLUSTER-IP` values for `postgresql-scalardb-cluster-hl` and `scalardb-cluster-headless` are `None` since they have no IP addresses.
:::
## Step 6. Start a client container
You'll use the CA certificate file in a client container. Therefore, you'll need to create a secret resource and mount it to the client container.
1. Create a secret resource named `client-ca-cert`.
```console
kubectl create secret generic client-ca-cert --from-file=ca.crt=<(kubectl get secret self-signed-ca-cert-secret -o "jsonpath={.data['ca\.crt']}" | base64 -d) -n default
```
1. Create a manifest file for a client pod (`scalardb-cluster-client-pod.yaml`).
```console
cat << 'EOF' > ${HOME}/scalardb-cluster-test/scalardb-cluster-client-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: "scalardb-cluster-client"
spec:
containers:
- name: scalardb-cluster-client
image: eclipse-temurin:8-jre-jammy
command: ['sleep']
args: ['inf']
env:
- name: SCALAR_DB_CLUSTER_VERSION
value: SCALAR_DB_CLUSTER_CLIENT_POD_SCALAR_DB_CLUSTER_VERSION
volumeMounts:
- name: "client-ca-cert"
mountPath: "/certs/"
readOnly: true
volumes:
- name: "client-ca-cert"
secret:
secretName: "client-ca-cert"
restartPolicy: Never
EOF
```
1. Set the ScalarDB Cluster version in the manifest file.
```console
sed -i s/SCALAR_DB_CLUSTER_CLIENT_POD_SCALAR_DB_CLUSTER_VERSION/${SCALAR_DB_CLUSTER_VERSION}/ ${HOME}/scalardb-cluster-test/scalardb-cluster-client-pod.yaml
```
1. Deploy the client pod.
```console
kubectl apply -f ${HOME}/scalardb-cluster-test/scalardb-cluster-client-pod.yaml -n default
```
1. Check if the client container is running.
```console
kubectl get pod scalardb-cluster-client -n default
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
scalardb-cluster-client 1/1 Running 0 26s
```
## Step 7. Run the ScalarDB Cluster SQL CLI in the client container
1. Run bash in the client container.
```console
kubectl exec -it scalardb-cluster-client -n default -- bash
```
The commands in the following steps must be run in the client container.
1. Download the ScalarDB Cluster SQL CLI from [Releases](https://github.com/scalar-labs/scalardb/releases).
```console
curl -OL https://github.com/scalar-labs/scalardb/releases/download/v${SCALAR_DB_CLUSTER_VERSION}/scalardb-cluster-sql-cli-${SCALAR_DB_CLUSTER_VERSION}-all.jar
```
1. Create a `database.properties` file and add configurations.
```console
cat << 'EOF' > /database.properties
# ScalarDB Cluster configurations
scalar.db.sql.connection_mode=cluster
scalar.db.sql.cluster_mode.contact_points=indirect:scalardb-cluster-envoy.default.svc.cluster.local
# Auth configurations
scalar.db.cluster.auth.enabled=true
scalar.db.sql.cluster_mode.username=admin
scalar.db.sql.cluster_mode.password=admin
# TLS configurations
scalar.db.cluster.tls.enabled=true
scalar.db.cluster.tls.ca_root_cert_path=/certs/ca.crt
scalar.db.cluster.tls.override_authority=envoy.scalar.example.com
EOF
```
1. Run the ScalarDB Cluster SQL CLI.
```console
java -jar /scalardb-cluster-sql-cli-${SCALAR_DB_CLUSTER_VERSION}-all.jar --config /database.properties
```
1. Create a sample namespace named `ns`.
```sql
CREATE NAMESPACE ns;
```
1. Create a sample table named `tbl` under the namespace `ns`.
```sql
CREATE TABLE ns.tbl (a INT, b INT, c INT, PRIMARY KEY(a, b));
```
1. Insert sample records.
```sql
INSERT INTO ns.tbl VALUES (1,2,3), (4,5,6), (7,8,9);
```
1. Select the sample records that you inserted.
```sql
SELECT * FROM ns.tbl;
```
[Command execution result]
```sql
0: scalardb> SELECT * FROM ns.tbl;
+---+---+---+
| a | b | c |
+---+---+---+
| 7 | 8 | 9 |
| 1 | 2 | 3 |
| 4 | 5 | 6 |
+---+---+---+
3 rows selected (0.059 seconds)
```
1. Press `Ctrl + D` to exit from ScalarDB Cluster SQL CLI.
```console
^D
```
1. Exit from the client container.
```console
exit
```
## Step 8. Delete all resources
After completing the ScalarDB Cluster tests on the Kubernetes cluster, remove all resources.
1. Uninstall ScalarDB Cluster and PostgreSQL.
```console
helm uninstall -n default scalardb-cluster postgresql-scalardb-cluster
```
1. Remove the self-signed CA.
```
kubectl delete -f ./private-ca-custom-values.yaml
```
1. Uninstall cert-manager.
```console
helm uninstall -n cert-manager cert-manager
```
1. Remove the client container.
```
kubectl delete pod scalardb-cluster-client --grace-period 0 -n default
```
1. Remove the secret resources.
```
kubectl delete secrets scalardb-credentials-secret self-signed-ca-cert-secret scalardb-cluster-envoy-tls-cert scalardb-cluster-tls-cert client-ca-cert
```
1. Remove the namespace `cert-manager`.
```
kubectl delete ns cert-manager
```
1. Remove the working directory and the sample configuration files.
```console
cd ${HOME}
```
```console
rm -rf ${HOME}/scalardb-cluster-test/
```
## Further reading
You can see how to get started with monitoring or logging for Scalar products in the following tutorials:
* [Getting Started with Helm Charts (Monitoring using Prometheus Operator)](getting-started-monitoring.mdx)
* [Getting Started with Helm Charts (Logging using Loki Stack)](getting-started-logging.mdx)
* [Getting Started with Helm Charts (Scalar Manager)](getting-started-scalar-manager.mdx)
================================================
FILE: docs/helm-charts/getting-started-scalardb-cluster-tls.mdx
================================================
---
tags:
- Enterprise Standard
- Enterprise Premium
displayed_sidebar: docsEnglish
---
# Getting Started with Helm Charts (ScalarDB Cluster with TLS)
This tutorial explains how to get started with ScalarDB Cluster with TLS configurations by using Helm Charts on a Kubernetes cluster in a test environment. Before starting, you should already have a Mac or Linux environment for testing. In addition, although this tutorial mentions using **minikube**, the steps described should work in any Kubernetes cluster.
## Requirements
* You need to have a license key (trial license or commercial license) for ScalarDB Cluster. If you don't have a license key, please [contact us](https://www.scalar-labs.com/contact).
* You need to use ScalarDB Cluster 3.12 or later, which supports TLS.
## What you'll create
In this tutorial, you'll deploy the following components on a Kubernetes cluster in the following way:
```
+----------------------------------------------------------------------------------------------------------------------------------------------------+
| [Kubernetes Cluster] |
| [Pod] [Pod] [Pod] |
| |
| +-------+ +------------------------+ |
| +---> | Envoy | ---+ +---> | ScalarDB Cluster node | ---+ |
| [Pod] | +-------+ | | +------------------------+ | |
| | | | | |
| +-----------+ +---------+ | +-------+ | +--------------------+ | +------------------------+ | +---------------+ |
| | Client | ---> | Service | ---+---> | Envoy | ---+---> | Service | ---+---> | ScalarDB Cluster node | ---+---> | PostgreSQL | |
| | (SQL CLI) | | (Envoy) | | +-------+ | | (ScalarDB Cluster) | | +------------------------+ | | (For Ledger) | |
| +-----------+ +---------+ | | +--------------------+ | | +---------------+ |
| | +-------+ | | +------------------------+ | |
| +---> | Envoy | ---+ +---> | ScalarDB Cluster node | ---+ |
| +-------+ +------------------------+ |
| |
+----------------------------------------------------------------------------------------------------------------------------------------------------+
```
You'll also create the following private key and certificate files for TLS connections.
```
+-------------------------------+
+---> | For Scalar Envoy |
| +-------------------------------+
| | envoy-key.pem |
| | envoy.pem |
+----------------------+ | +-------------------------------+
| Self-signed CA | ---(Sign certificates)---+
+----------------------+ | +-------------------------------+
| ca-key.pem | +---> | For ScalarDB Cluster |
| ca.pem | +-------------------------------+
+----------------------+ | scalardb-cluster-key.pem |
| scalardb-cluster.pem |
+-------------------------------+
```
You'll set each private key and certificate file as follows to enable TLS in each connection.
```
+--------------------------------+ +-----------------------------------------+ +-----------------------------------------+
| Client | ---(CRUD/SQL requests)---> | Envoy for ScalarDB Cluster | ---> | ScalarDB Cluster nodes |
+--------------------------------+ +-----------------------------------------+ +-----------------------------------------+
| ca.pem (to verify envoy.pem) | | envoy-key.pem | | scalardb-cluster-key.pem |
+--------------------------------+ | envoy.pem | | scalardb-cluster.pem |
| ca.pem (to verify scalardb-cluster.pem) | | ca.pem (used for health check) |
+-----------------------------------------+ +-----------------------------------------+
```
The following connections exist amongst the ScalarDB Cluster–related components:
* **`Client - Envoy for ScalarDB Cluster`:** When you execute a CRUD API or SQL API function, the client accesses Envoy for ScalarDB Cluster.
* **`Envoy for ScalarDB Cluster - ScalarDB Cluster`:** Envoy works as an L7 (gRPC) load balancer in front of ScalarDB Cluster.
* **`ScalarDB Cluster node - ScalarDB Cluster node`:** A ScalarDB Cluster node accesses other ScalarDB Cluster nodes. In other words, the cluster's internal communications exist amongst all ScalarDB Cluster nodes.
## Step 1. Start a Kubernetes cluster and install tools
You need to prepare a Kubernetes cluster and install some tools (`kubectl`, `helm`, `cfssl`, and `cfssljson`). For more details on how to install them, see [Getting Started with Scalar Helm Charts](getting-started-scalar-helm-charts.mdx).
## Step 2. Start the PostgreSQL containers
ScalarDB Cluster must use some type of database system as a backend database. In this tutorial, you'll use PostgreSQL.
You can deploy PostgreSQL on the Kubernetes cluster as follows:
1. Add the Bitnami helm repository.
```console
helm repo add bitnami https://charts.bitnami.com/bitnami
```
1. Deploy PostgreSQL for ScalarDB Cluster.
```console
helm install postgresql-scalardb-cluster bitnami/postgresql \
--set auth.postgresPassword=postgres \
--set primary.persistence.enabled=false \
-n default
```
1. Check if the PostgreSQL containers are running.
```console
kubectl get pod -n default
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-scalardb-cluster-0 1/1 Running 0 34s
```
## Step 3. Create a working directory
You'll create some configuration files and private key and certificate files locally. Be sure to create a working directory for those files.
1. Create a working directory.
```console
mkdir -p ${HOME}/scalardb-cluster-test/certs/
```
## Step 4. Create private key and certificate files
You'll create private key and a certificate files.
1. Change the working directory to `${HOME}/scalardb-cluster-test/certs/`.
```console
cd ${HOME}/scalardb-cluster-test/certs/
```
1. Create a JSON file that includes CA information.
```console
cat << 'EOF' > ${HOME}/scalardb-cluster-test/certs/ca.json
{
"CN": "scalar-test-ca",
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "JP",
"ST": "Tokyo",
"L": "Shinjuku",
"O": "Scalar Test CA"
}
]
}
EOF
```
1. Create the CA private key and certificate files.
```console
cfssl gencert -initca ca.json | cfssljson -bare ca
```
1. Create a JSON file that includes CA configurations.
```console
cat << 'EOF' > ${HOME}/scalardb-cluster-test/certs/ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"scalar-test-ca": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth"
]
}
}
}
}
EOF
```
1. Create a JSON file that includes Envoy information.
```console
cat << 'EOF' > ${HOME}/scalardb-cluster-test/certs/envoy.json
{
"CN": "scalar-envoy",
"hosts": [
"envoy.scalar.example.com",
"localhost"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "JP",
"ST": "Tokyo",
"L": "Shinjuku",
"O": "Scalar Envoy Test"
}
]
}
EOF
```
1. Create a JSON file that includes ScalarDB Cluster information.
```console
cat << 'EOF' > ${HOME}/scalardb-cluster-test/certs/scalardb-cluster.json
{
"CN": "scalardb-cluster",
"hosts": [
"cluster.scalardb.example.com",
"localhost"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "JP",
"ST": "Tokyo",
"L": "Shinjuku",
"O": "ScalarDB Cluster Test"
}
]
}
EOF
```
1. Create private key and certificate files for Envoy.
```console
cfssl gencert -ca ca.pem -ca-key ca-key.pem -config ca-config.json -profile scalar-test-ca envoy.json | cfssljson -bare envoy
```
1. Create private key and certificate files for ScalarDB Cluster.
```console
cfssl gencert -ca ca.pem -ca-key ca-key.pem -config ca-config.json -profile scalar-test-ca scalardb-cluster.json | cfssljson -bare scalardb-cluster
```
1. Confirm that the private key and certificate files were created.
```console
ls -1
```
[Command execution result]
```console
ca-config.json
ca-key.pem
ca.csr
ca.json
ca.pem
envoy-key.pem
envoy.csr
envoy.json
envoy.pem
scalardb-cluster-key.pem
scalardb-cluster.csr
scalardb-cluster.json
scalardb-cluster.pem
```
## Step 5. Deploy ScalarDB Cluster on the Kubernetes cluster by using Helm Charts
1. Add the Scalar Helm Charts repository.
```console
helm repo add scalar-labs https://scalar-labs.github.io/helm-charts
```
1. Set your license key and certificate as environment variables. If you don't have a license key, please [contact us](https://www.scalar-labs.com/contact). For details about the value of ``, see [How to Configure a License Key](../scalar-licensing/index.mdx).
```console
SCALAR_DB_CLUSTER_LICENSE_KEY=''
SCALAR_DB_CLUSTER_LICENSE_CHECK_CERT_PEM=''
```
1. Create a custom values file for ScalarDB Cluster (`scalardb-cluster-custom-values.yaml`).
```console
cat << 'EOF' > ${HOME}/scalardb-cluster-test/scalardb-cluster-custom-values.yaml
envoy:
enabled: true
tls:
downstream:
enabled: true
certChainSecret: "envoy-tls-cert"
privateKeySecret: "envoy-tls-key"
upstream:
enabled: true
overrideAuthority: "cluster.scalardb.example.com"
caRootCertSecret: "scalardb-cluster-tls-ca"
scalardbCluster:
image:
repository: "ghcr.io/scalar-labs/scalardb-cluster-node-byol-premium"
scalardbClusterNodeProperties: |
### Necessary configurations for deployment on Kuberetes
scalar.db.cluster.membership.type=KUBERNETES
scalar.db.cluster.membership.kubernetes.endpoint.namespace_name=${env:SCALAR_DB_CLUSTER_MEMBERSHIP_KUBERNETES_ENDPOINT_NAMESPACE_NAME}
scalar.db.cluster.membership.kubernetes.endpoint.name=${env:SCALAR_DB_CLUSTER_MEMBERSHIP_KUBERNETES_ENDPOINT_NAME}
### Storage configurations
scalar.db.contact_points=jdbc:postgresql://postgresql-scalardb-cluster.default.svc.cluster.local:5432/postgres
scalar.db.username=${env:SCALAR_DB_CLUSTER_POSTGRES_USERNAME}
scalar.db.password=${env:SCALAR_DB_CLUSTER_POSTGRES_PASSWORD}
scalar.db.storage=jdbc
### SQL configurations
scalar.db.sql.enabled=true
### Auth configurations
scalar.db.cluster.auth.enabled=true
scalar.db.cross_partition_scan.enabled=true
### TLS configurations
scalar.db.cluster.tls.enabled=true
scalar.db.cluster.tls.ca_root_cert_path=/tls/scalardb-cluster/certs/ca.crt
scalar.db.cluster.node.tls.cert_chain_path=/tls/scalardb-cluster/certs/tls.crt
scalar.db.cluster.node.tls.private_key_path=/tls/scalardb-cluster/certs/tls.key
scalar.db.cluster.tls.override_authority=cluster.scalardb.example.com
### License key configurations
scalar.db.cluster.node.licensing.license_key=${env:SCALAR_DB_CLUSTER_LICENSE_KEY}
scalar.db.cluster.node.licensing.license_check_cert_pem=${env:SCALAR_DB_CLUSTER_LICENSE_CHECK_CERT_PEM}
tls:
enabled: true
overrideAuthority: "cluster.scalardb.example.com"
caRootCertSecret: "scalardb-cluster-tls-ca"
certChainSecret: "scalardb-cluster-tls-cert"
privateKeySecret: "scalardb-cluster-tls-key"
secretName: "scalardb-credentials-secret"
EOF
```
1. Create a secret resource named `scalardb-credentials-secret` that includes credentials and license keys.
```console
kubectl create secret generic scalardb-credentials-secret \
--from-literal=SCALAR_DB_CLUSTER_POSTGRES_USERNAME=postgres \
--from-literal=SCALAR_DB_CLUSTER_POSTGRES_PASSWORD=postgres \
--from-literal=SCALAR_DB_CLUSTER_LICENSE_KEY="${SCALAR_DB_CLUSTER_LICENSE_KEY}" \
--from-file=SCALAR_DB_CLUSTER_LICENSE_CHECK_CERT_PEM=<(echo ${SCALAR_DB_CLUSTER_LICENSE_CHECK_CERT_PEM} | sed 's/\\n/\
/g') \
-n default
```
1. Create secret resources that include the private key and certificate files for Envoy.
```console
kubectl create secret generic envoy-tls-cert --from-file=tls.crt=${HOME}/scalardb-cluster-test/certs/envoy.pem -n default
kubectl create secret generic envoy-tls-key --from-file=tls.key=${HOME}/scalardb-cluster-test/certs/envoy-key.pem -n default
```
1. Create secret resources that include the key, certificate, and CA certificate files for ScalarDB Cluster.
```console
kubectl create secret generic scalardb-cluster-tls-ca --from-file=ca.crt=${HOME}/scalardb-cluster-test/certs/ca.pem -n default
kubectl create secret generic scalardb-cluster-tls-cert --from-file=tls.crt=${HOME}/scalardb-cluster-test/certs/scalardb-cluster.pem -n default
kubectl create secret generic scalardb-cluster-tls-key --from-file=tls.key=${HOME}/scalardb-cluster-test/certs/scalardb-cluster-key.pem -n default
```
1. Set the chart version of ScalarDB Cluster.
```console
SCALAR_DB_CLUSTER_VERSION=3.12.2
SCALAR_DB_CLUSTER_CHART_VERSION=$(helm search repo scalar-labs/scalardb-cluster -l | grep -F "${SCALAR_DB_CLUSTER_VERSION}" | awk '{print $2}' | sort --version-sort -r | head -n 1)
```
1. Deploy ScalarDB Cluster.
```console
helm install scalardb-cluster scalar-labs/scalardb-cluster -f ${HOME}/scalardb-cluster-test/scalardb-cluster-custom-values.yaml --version ${SCALAR_DB_CLUSTER_CHART_VERSION} -n default
```
1. Check if the ScalarDB Cluster pods are deployed.
```console
kubectl get pod -n default
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-scalardb-cluster-0 1/1 Running 0 4m30s
scalardb-cluster-envoy-7cc948dfb-4rb8l 1/1 Running 0 18s
scalardb-cluster-envoy-7cc948dfb-hwt96 1/1 Running 0 18s
scalardb-cluster-envoy-7cc948dfb-rzbrx 1/1 Running 0 18s
scalardb-cluster-node-7c6959c79d-445kj 1/1 Running 0 18s
scalardb-cluster-node-7c6959c79d-4z54q 1/1 Running 0 18s
scalardb-cluster-node-7c6959c79d-vcv96 1/1 Running 0 18s
```
If the ScalarDB Cluster pods are deployed properly, the `STATUS` column for those pods will be displayed as `Running`.
1. Check if the ScalarDB Cluster services are deployed.
```console
kubectl get svc -n default
```
[Command execution result]
```console
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 7h34m
postgresql-scalardb-cluster ClusterIP 10.96.92.27 5432/TCP 4m52s
postgresql-scalardb-cluster-hl ClusterIP None 5432/TCP 4m52s
scalardb-cluster-envoy ClusterIP 10.96.250.175 60053/TCP 40s
scalardb-cluster-envoy-metrics ClusterIP 10.96.40.197 9001/TCP 40s
scalardb-cluster-headless ClusterIP None 60053/TCP 40s
scalardb-cluster-metrics ClusterIP 10.96.199.135 9080/TCP 40s
```
If the ScalarDB Cluster services are deployed properly, you can see private IP addresses in the `CLUSTER-IP` column.
:::note
The `CLUSTER-IP` values for `postgresql-scalardb-cluster-hl` and `scalardb-cluster-headless` are `None` since they have no IP addresses.
:::
## Step 6. Start a client container
You'll use the CA certificate file in a client container. Therefore, you'll need to create a secret resource and mount it to the client container.
1. Create a secret resource named `client-ca-cert`.
```console
kubectl create secret generic client-ca-cert --from-file=ca.crt=${HOME}/scalardb-cluster-test/certs/ca.pem -n default
```
1. Create a manifest file for a client pod (`scalardb-cluster-client-pod.yaml`).
```console
cat << 'EOF' > ${HOME}/scalardb-cluster-test/scalardb-cluster-client-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: "scalardb-cluster-client"
spec:
containers:
- name: scalardb-cluster-client
image: eclipse-temurin:8-jre-jammy
command: ['sleep']
args: ['inf']
env:
- name: SCALAR_DB_CLUSTER_VERSION
value: SCALAR_DB_CLUSTER_CLIENT_POD_SCALAR_DB_CLUSTER_VERSION
volumeMounts:
- name: "client-ca-cert"
mountPath: "/certs/"
readOnly: true
volumes:
- name: "client-ca-cert"
secret:
secretName: "client-ca-cert"
restartPolicy: Never
EOF
```
1. Set the ScalarDB Cluster version in the manifest file.
```console
sed -i s/SCALAR_DB_CLUSTER_CLIENT_POD_SCALAR_DB_CLUSTER_VERSION/${SCALAR_DB_CLUSTER_VERSION}/ ${HOME}/scalardb-cluster-test/scalardb-cluster-client-pod.yaml
```
1. Deploy the client pod.
```console
kubectl apply -f ${HOME}/scalardb-cluster-test/scalardb-cluster-client-pod.yaml -n default
```
1. Check if the client container is running.
```console
kubectl get pod scalardb-cluster-client -n default
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
scalardb-cluster-client 1/1 Running 0 26s
```
## Step 7. Run the ScalarDB Cluster SQL CLI in the client container
1. Run bash in the client container.
```console
kubectl exec -it scalardb-cluster-client -n default -- bash
```
The commands in the following steps must be run in the client container.
1. Download the ScalarDB Cluster SQL CLI from [Releases](https://github.com/scalar-labs/scalardb/releases).
```console
curl -OL https://github.com/scalar-labs/scalardb/releases/download/v${SCALAR_DB_CLUSTER_VERSION}/scalardb-cluster-sql-cli-${SCALAR_DB_CLUSTER_VERSION}-all.jar
```
1. Create a `database.properties` file and add configurations.
```console
cat << 'EOF' > /database.properties
# ScalarDB Cluster configurations
scalar.db.sql.connection_mode=cluster
scalar.db.sql.cluster_mode.contact_points=indirect:scalardb-cluster-envoy.default.svc.cluster.local
# Auth configurations
scalar.db.cluster.auth.enabled=true
scalar.db.sql.cluster_mode.username=admin
scalar.db.sql.cluster_mode.password=admin
# TLS configurations
scalar.db.cluster.tls.enabled=true
scalar.db.cluster.tls.ca_root_cert_path=/certs/ca.crt
scalar.db.cluster.tls.override_authority=envoy.scalar.example.com
EOF
```
1. Run the ScalarDB Cluster SQL CLI.
```console
java -jar /scalardb-cluster-sql-cli-${SCALAR_DB_CLUSTER_VERSION}-all.jar --config /database.properties
```
1. Create a sample namespace named `ns`.
```sql
CREATE NAMESPACE ns;
```
1. Create a sample table named `tbl` under the namespace `ns`.
```sql
CREATE TABLE ns.tbl (a INT, b INT, c INT, PRIMARY KEY(a, b));
```
1. Insert sample records.
```sql
INSERT INTO ns.tbl VALUES (1,2,3), (4,5,6), (7,8,9);
```
1. Select the sample records that you inserted.
```sql
SELECT * FROM ns.tbl;
```
[Command execution result]
```sql
0: scalardb> SELECT * FROM ns.tbl;
+---+---+---+
| a | b | c |
+---+---+---+
| 7 | 8 | 9 |
| 1 | 2 | 3 |
| 4 | 5 | 6 |
+---+---+---+
3 rows selected (0.059 seconds)
```
1. Press `Ctrl + D` to exit from ScalarDB Cluster SQL CLI.
```console
^D
```
1. Exit from the client container.
```console
exit
```
## Step 8. Delete all resources
After completing the ScalarDB Cluster tests on the Kubernetes cluster, remove all resources.
1. Uninstall ScalarDB Cluster and PostgreSQL.
```console
helm uninstall -n default scalardb-cluster postgresql-scalardb-cluster
```
1. Remove the client container.
```
kubectl delete pod scalardb-cluster-client --grace-period 0 -n default
```
1. Remove the secret resources.
```
kubectl delete secrets scalardb-credentials-secret scalardb-cluster-tls-key scalardb-cluster-tls-cert scalardb-cluster-tls-ca envoy-tls-key envoy-tls-cert client-ca-cert
```
1. Remove the working directory and sample files (configuration file, private key, and certificate).
```console
cd ${HOME}
```
```console
rm -rf ${HOME}/scalardb-cluster-test/
```
## Further reading
You can see how to get started with monitoring or logging for Scalar products in the following tutorials:
* [Getting Started with Helm Charts (Monitoring using Prometheus Operator)](getting-started-monitoring.mdx)
* [Getting Started with Helm Charts (Logging using Loki Stack)](getting-started-logging.mdx)
* [Getting Started with Helm Charts (Scalar Manager)](getting-started-scalar-manager.mdx)
================================================
FILE: docs/helm-charts/getting-started-scalardb.mdx
================================================
---
tags:
- Enterprise Standard
- Enterprise Premium
- Deprecated
displayed_sidebar: docsEnglish
---
# [Deprecated] Getting Started with Helm Charts (ScalarDB Server)
:::note
ScalarDB Server is now deprecated. Please use [ScalarDB Cluster](https://scalardb.scalar-labs.com/docs/latest/scalardb-cluster/setup-scalardb-cluster-on-kubernetes-by-using-helm-chart) instead.
:::
This document explains how to get started with ScalarDB Server using Helm Chart on a Kubernetes cluster as a test environment. Here, we assume that you already have a Mac or Linux environment for testing. We use **Minikube** in this document, but the steps we will show should work in any Kubernetes cluster.
## Requirement
* You need to subscribe to ScalarDB in the [AWS Marketplace](https://aws.amazon.com/marketplace/pp/prodview-rzbuhxgvqf4d2) to get container images (`scalardb-server` and `scalardb-envoy`). For more details, refer to [How to install Scalar products through AWS Marketplace](../scalar-kubernetes/AwsMarketplaceGuide.mdx).
## What we create
We will deploy the following components on a Kubernetes cluster as follows.
```
+--------------------------------------------------------------------------------------------------------------------------------------+
| [Kubernetes Cluster] |
| |
| [Pod] [Pod] [Pod] [Pod] |
| |
| +-------+ +-----------------+ |
| +---> | Envoy | ---+ +---> | ScalarDB Server | ---+ |
| | +-------+ | | +-----------------+ | |
| | | | | |
| +--------+ +---------+ | +-------+ | +-------------------+ | +-----------------+ | +------------+ |
| | Client | ---> | Service | ---+---> | Envoy | ---+---> | Service | ---+---> | ScalarDB Server | ---+---> | PostgreSQL | |
| +--------+ | (Envoy) | | +-------+ | | (ScalarDB Server) | | +-----------------+ | +------------+ |
| +---------+ | | +-------------------+ | | |
| | +-------+ | | +-----------------+ | |
| +---> | Envoy | ---+ +---> | ScalarDB Server | ---+ |
| +-------+ +-----------------+ |
| |
+--------------------------------------------------------------------------------------------------------------------------------------+
```
## Step 1. Start a Kubernetes cluster
First, you need to prepare a Kubernetes cluster. If you use a **minikube** environment, please refer to the [Getting Started with Scalar Helm Charts](getting-started-scalar-helm-charts.mdx). If you have already started a Kubernetes cluster, you can skip this step.
## Step 2. Start a PostgreSQL container
ScalarDB uses some kind of database system as a backend database. In this document, we use PostgreSQL.
You can deploy PostgreSQL on the Kubernetes cluster as follows.
1. Add the Bitnami helm repository.
```console
helm repo add bitnami https://charts.bitnami.com/bitnami
```
1. Deploy PostgreSQL.
```console
helm install postgresql-scalardb bitnami/postgresql \
--set auth.postgresPassword=postgres \
--set primary.persistence.enabled=false
```
1. Check if the PostgreSQL container is running.
```console
kubectl get pod
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-scalardb-0 1/1 Running 0 2m42s
```
## Step 3. Deploy ScalarDB Server on the Kubernetes cluster using Helm Charts
1. Add the Scalar helm repository.
```console
helm repo add scalar-labs https://scalar-labs.github.io/helm-charts
```
1. Create a secret resource to pull the ScalarDB container images from AWS.
* AWS Marketplace
```console
kubectl create secret docker-registry reg-ecr-mp-secrets \
--docker-server=709825985650.dkr.ecr.us-east-1.amazonaws.com \
--docker-username=AWS \
--docker-password=$(aws ecr get-login-password --region us-east-1)
```
For more details, refer to [How to install Scalar products through AWS Marketplace](../scalar-kubernetes/AwsMarketplaceGuide.mdx).
1. Create a custom values file for ScalarDB Server (scalardb-custom-values.yaml).
* AWS Marketplace
```console
cat << 'EOF' > scalardb-custom-values.yaml
envoy:
image:
repository: "709825985650.dkr.ecr.us-east-1.amazonaws.com/scalar/scalardb-envoy"
version: "1.3.0"
imagePullSecrets:
- name: "reg-ecr-mp-secrets"
scalardb:
image:
repository: "709825985650.dkr.ecr.us-east-1.amazonaws.com/scalar/scalardb-server"
tag: "3.7.0"
imagePullSecrets:
- name: "reg-ecr-mp-secrets"
databaseProperties: |
scalar.db.storage=jdbc
scalar.db.contact_points=jdbc:postgresql://postgresql-scalardb.default.svc.cluster.local:5432/postgres
scalar.db.username={{ default .Env.SCALAR_DB_POSTGRES_USERNAME "" }}
scalar.db.password={{ default .Env.SCALAR_DB_POSTGRES_PASSWORD "" }}
secretName: "scalardb-credentials-secret"
EOF
```
1. Create a Secret resource that includes a username and password for PostgreSQL.
```console
kubectl create secret generic scalardb-credentials-secret \
--from-literal=SCALAR_DB_POSTGRES_USERNAME=postgres \
--from-literal=SCALAR_DB_POSTGRES_PASSWORD=postgres
```
1. Deploy ScalarDB Server.
```console
helm install scalardb scalar-labs/scalardb -f ./scalardb-custom-values.yaml
```
1. Check if the ScalarDB Server pods are deployed.
```console
kubectl get pod
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-scalardb-0 1/1 Running 0 9m48s
scalardb-765598848b-75csp 1/1 Running 0 6s
scalardb-765598848b-w864f 1/1 Running 0 6s
scalardb-765598848b-x8rqj 1/1 Running 0 6s
scalardb-envoy-84c475f77b-kpz2p 1/1 Running 0 6s
scalardb-envoy-84c475f77b-n74tk 1/1 Running 0 6s
scalardb-envoy-84c475f77b-zbrwz 1/1 Running 0 6s
```
If the ScalarDB Server Pods are deployed properly, you can see the STATUS are **Running**.
1. Check if the ScalarDB Server services are deployed.
```console
kubectl get svc
```
[Command execution result]
```console
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 47d
postgresql-scalardb ClusterIP 10.109.118.122 5432/TCP 10m
postgresql-scalardb-hl ClusterIP None 5432/TCP 10m
scalardb-envoy ClusterIP 10.110.110.250 60051/TCP 41s
scalardb-envoy-metrics ClusterIP 10.107.98.227 9001/TCP 41s
scalardb-headless ClusterIP None 60051/TCP 41s
scalardb-metrics ClusterIP 10.108.188.10 8080/TCP 41s
```
If the ScalarDB Server services are deployed properly, you can see private IP addresses in the CLUSTER-IP column. (Note: `scalardb-headless` has no CLUSTER-IP.)
## Step 4. Start a Client container
1. Start a Client container on the Kubernetes cluster.
```console
kubectl run scalardb-client --image eclipse-temurin:8-jdk --command sleep inf
```
1. Check if the Client container is running.
```console
kubectl get pod scalardb-client
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
scalardb-client 1/1 Running 0 23s
```
## Step 5. Run ScalarDB sample applications in the Client container
The following explains the minimum steps. If you want to know more details about ScalarDB, please refer to the [Getting Started with ScalarDB](https://scalardb.scalar-labs.com/docs/latest/getting-started-with-scalardb).
1. Run bash in the Client container.
```console
kubectl exec -it scalardb-client -- bash
```
After this step, run each command in the Client container.
1. Install the git and curl commands in the Client container.
```console
apt update && apt install -y git curl
```
1. Clone ScalarDB git repository.
```console
git clone https://github.com/scalar-labs/scalardb.git
```
1. Change the directory to `scalardb/`.
```console
cd scalardb/
```
```console
pwd
```
[Command execution result]
```console
/scalardb
```
1. Change branch to arbitrary version.
```console
git checkout -b v3.7.0 refs/tags/v3.7.0
```
```console
git branch
```
[Command execution result]
```console
master
* v3.7.0
```
If you want to use another version, please specify the version (tag) you want to use.
1. Change the directory to `docs/getting-started/`.
```console
cd docs/getting-started/
```
```console
pwd
```
[Command execution result]
```console
/scalardb/docs/getting-started
```
1. Download Schema Loader from [ScalarDB Releases](https://github.com/scalar-labs/scalardb/releases).
```console
curl -OL https://github.com/scalar-labs/scalardb/releases/download/v3.7.0/scalardb-schema-loader-3.7.0.jar
```
You need to use the same version of ScalarDB and Schema Loader.
1. Create a configuration file (scalardb.properties) to access ScalarDB Server on the Kubernetes cluster.
```console
cat << 'EOF' > scalardb.properties
scalar.db.contact_points=scalardb-envoy.default.svc.cluster.local
scalar.db.contact_port=60051
scalar.db.storage=grpc
scalar.db.transaction_manager=grpc
EOF
```
1. Create a JSON file (emoney-transaction.json) that defines DB Schema for the sample applications.
```console
cat << 'EOF' > emoney-transaction.json
{
"emoney.account": {
"transaction": true,
"partition-key": [
"id"
],
"clustering-key": [],
"columns": {
"id": "TEXT",
"balance": "INT"
}
}
}
EOF
```
1. Run Schema Loader (Create sample TABLE).
```console
java -jar ./scalardb-schema-loader-3.7.0.jar --config ./scalardb.properties -f emoney-transaction.json --coordinator
```
1. Run the sample applications.
* Charge `1000` to `user1`:
```console
./gradlew run --args="-action charge -amount 1000 -to user1"
```
* Charge `0` to `merchant1` (Just create an account for `merchant1`):
```console
./gradlew run --args="-action charge -amount 0 -to merchant1"
```
* Pay `100` from `user1` to `merchant1`:
```console
./gradlew run --args="-action pay -amount 100 -from user1 -to merchant1"
```
* Get the balance of `user1`:
```console
./gradlew run --args="-action getBalance -id user1"
```
* Get the balance of `merchant1`:
```console
./gradlew run --args="-action getBalance -id merchant1"
```
1. (Optional) You can see the inserted and modified (INSERT/UPDATE) data through the sample applications using the following command. (This command needs to run on your localhost, not on the Client container.)
```console
kubectl exec -it postgresql-scalardb-0 -- bash -c 'export PGPASSWORD=postgres && psql -U postgres -d postgres -c "SELECT * FROM emoney.account"'
```
[Command execution result]
```sql
id | balance | tx_id | tx_state | tx_version | tx_prepared_at | tx_committed_at | before_tx_id | before_tx_state | before_tx_version | before_tx_prepared_at | before_tx_committed_at | before_balance
-----------+---------+--------------------------------------+----------+------------+----------------+-----------------+--------------------------------------+-----------------+-------------------+-----------------------+------------------------+----------------
merchant1 | 100 | 65a90225-0846-4e97-b729-151f76f6ca2f | 3 | 2 | 1667361909634 |1667361909679 | 3633df99-a8ed-4301-a8b9-db1344807d7b | 3 | 1 | 1667361902466 | 1667361902485 | 0
user1 | 900 | 65a90225-0846-4e97-b729-151f76f6ca2f | 3 | 2 | 1667361909634 |1667361909679 | 5520cba4-625a-4886-b81f-6089bf846d18 | 3 | 1 | 1667361897283 | 1667361897317 | 1000
(2 rows)
```
* Note:
* Usually, you need to access data (records) through ScalarDB. The above command is used to explain and confirm the working of the sample applications.
## Step 6. Delete all resources
After completing the ScalarDB Server tests on the Kubernetes cluster, remove all resources.
1. Uninstall ScalarDB Server and PostgreSQL.
```console
helm uninstall scalardb postgresql-scalardb
```
1. Remove the Client container.
```
kubectl delete pod scalardb-client --force --grace-period 0
```
## Further reading
You can see how to get started with monitoring or logging for Scalar products in the following documents.
* [Getting Started with Helm Charts (Monitoring using Prometheus Operator)](getting-started-monitoring.mdx)
* [Getting Started with Helm Charts (Logging using Loki Stack)](getting-started-logging.mdx)
* [Getting Started with Helm Charts (Scalar Manager)](getting-started-scalar-manager.mdx)
================================================
FILE: docs/helm-charts/getting-started-scalardl-auditor-tls-cert-manager.mdx
================================================
---
tags:
- Enterprise
displayed_sidebar: docsEnglish
---
# Getting Started with Helm Charts (ScalarDL Ledger and Auditor with TLS by Using cert-manager / Auditor Mode)
This tutorial explains how to get started with ScalarDL Ledger and ScalarDL Auditor with TLS configurations by using Helm Charts and cert-manager on a Kubernetes cluster as a test environment. Before starting, you should already have a Mac or Linux environment for testing. In addition, although this tutorial mentions using **minikube**, the steps described should work in any Kubernetes cluster.
## Requirements
* You need to have a license key (trial license or commercial license) for ScalarDL. If you don't have a license key, please [contact us](https://www.scalar-labs.com/contact).
* You need to use ScalarDL 3.9 or later, which supports TLS.
:::note
To make Byzantine-fault detection with auditing work properly, ScalarDL Ledger and ScalarDL Auditor should be deployed and managed in different administrative domains. However, in this tutorial, we will deploy ScalarDL Ledger and ScalarDL Auditor in the same Kubernetes cluster to make the test easier.
:::
## What you'll create
In this tutorial, you'll deploy the following components on a Kubernetes cluster in the following way:
```
+-----------------------------------------------------------------------------------------------------------------------------+
| [Kubernetes Cluster] |
| [Pod] [Pod] [Pod] |
| |
| +-------+ +---------+ |
| +---> | Envoy | ---+ +---> | Ledger | ---+ |
| | +-------+ | | +---------+ | |
| | | | | |
| +---------+ | +-------+ | +-----------+ | +---------+ | +---------------+ |
| +---> | Service | ---+---> | Envoy | ---+---> | Service | ---+---> | Ledger | ---+---> | PostgreSQL | |
| | | (Envoy) | | +-------+ | | (Ledger) | | +---------+ | | (For Ledger) | |
| | +---------+ | | +-----------+ | | +---------------+ |
| [Pod] | | +-------+ | | +---------+ | |
| | +---> | Envoy | ---+ +---> | Ledger | ---+ |
| +--------+ | +-------+ +---------+ |
| | Client | ---+ |
| +--------+ | +-------+ +---------+ |
| | +---> | Envoy | ---+ +---> | Auditor | ---+ |
| | | +-------+ | | +---------+ | |
| | | | | | |
| | +---------+ | +-------+ | +-----------+ | +---------+ | +---------------+ |
| +---> | Service | ---+---> | Envoy | ---+---> | Service | ---+---> | Auditor | ---+---> | PostgreSQL | |
| | (Envoy) | | +-------+ | | (Auditor) | | +---------+ | | (For Auditor) | |
| +---------+ | | +-----------+ | | +---------------+ |
| | +-------+ | | +---------+ | |
| +---> | Envoy | ---+ +---> | Auditor | ---+ |
| +-------+ +---------+ |
| |
| +--------------------------------------------------------------------------+ +---------------------+ |
| | cert-manager (create private key and certificate for Envoy and ScalarDL) | | Issuer (Private CA) | |
| +--------------------------------------------------------------------------+ +---------------------+ |
| |
+-----------------------------------------------------------------------------------------------------------------------------+
```
cert-manager automatically creates the following private key and certificate files for TLS connections.
```
+----------------------+
+---> | For Scalar Envoy |
| +----------------------+
| | tls.key |
| | tls.crt |
| +----------------------+
|
+-------------------------+ | +----------------------+
| Issuer (Self-signed CA) | ---(Sign certificates)---+---> | For ScalarDL Ledger |
+-------------------------+ | +----------------------+
| tls.key | | | tls.key |
| tls.crt | | | tls.crt |
| ca.crt | | +----------------------+
+-------------------------+ |
| +----------------------+
+---> | For ScalarDL Auditor |
+----------------------+
| tls.key |
| tls.crt |
+----------------------+
```
Scalar Helm Charts automatically mount each private key and certificate file for Envoy and ScalarDL as follows to enable TLS in each connection. You'll manually mount a root CA certificate file on the client.
```
+------------------------------------------------+ +--------------------------------------+
+-------(Normal request)-----> | Envoy for ScalarDL Ledger | ---> | ScalarDL Ledger |
| +------------------------------------------------+ +--------------------------------------+
| +---(Recovery request)---> | tls.key | ---> | tls.key |
| | | tls.crt | | tls.crt |
| | | ca.crt (to verify tls.crt of ScalarDL Ledger) | | ca.crt (to check health) |
| | +------------------------------------------------+ +--------------------------------------+
+---------------------------------------+ | |
| Client | ---+ |
+---------------------------------------+ | +------------------------------------------------------------------------------------------------------------------------------+
| ca.crt (to verify tls.crt of Envoy) | | |
+---------------------------------------+ | |
| +------------------------------------------------+ +--------------------------------------+ |
+-------(Normal request)-----> | Envoy for ScalarDL Auditor | ---> | ScalarDL Auditor | ---+
+------------------------------------------------+ +--------------------------------------+
| tls.key | | tls.key |
| tls.crt | | tls.crt |
| ca.crt (to verify tls.crt of ScalarDL Auditor) | | ca.crt (to check health) |
+------------------------------------------------+ | ca.crt (to verify tls.crt of Envoy) |
+--------------------------------------+
```
The following connections exist amongst the ScalarDL-related components:
* **`Client - Envoy for ScalarDL Ledger`:** When you execute a ScalarDL API function, the client accesses Envoy for ScalarDL Ledger.
* **`Client - Envoy for ScalarDL Auditor`:** When you execute a ScalarDL API function, the client accesses Envoy for ScalarDL Auditor.
* **`Envoy for ScalarDL Ledger - ScalarDL Ledger`:** Envoy works as an L7 (gRPC) load balancer in front of ScalarDL Ledger.
* **`Envoy for ScalarDL Auditor - ScalarDL Auditor`:** Envoy works as an L7 (gRPC) load balancer in front of ScalarDL Auditor.
* **`ScalarDL Auditor - Envoy for ScalarDL Ledger (ScalarDL Ledger)`:** When ScalarDL needs to run the recovery process to keep data consistent, ScalarDL Auditor runs the request against ScalarDL Ledger via Envoy.
## Step 1. Start a Kubernetes cluster and install tools
You need to prepare a Kubernetes cluster and install some tools (`kubectl`, `helm`, `cfssl`, and `cfssljson`). For more details on how to install them, see [Getting Started with Scalar Helm Charts](getting-started-scalar-helm-charts.mdx).
## Step 2. Start the PostgreSQL containers
ScalarDL Ledger and ScalarDL Auditor must use some type of database system as a backend database. In this tutorial, you'll use PostgreSQL.
You can deploy PostgreSQL on the Kubernetes cluster as follows:
1. Add the Bitnami helm repository.
```console
helm repo add bitnami https://charts.bitnami.com/bitnami
```
1. Deploy PostgreSQL for Ledger.
```console
helm install postgresql-ledger bitnami/postgresql \
--set auth.postgresPassword=postgres \
--set primary.persistence.enabled=false \
-n default
```
1. Deploy PostgreSQL for Auditor.
```console
helm install postgresql-auditor bitnami/postgresql \
--set auth.postgresPassword=postgres \
--set primary.persistence.enabled=false \
-n default
```
1. Check if the PostgreSQL containers are running.
```console
kubectl get pod -n default
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-auditor-0 1/1 Running 0 11s
postgresql-ledger-0 1/1 Running 0 16s
```
## Step 3. Create a working directory
You'll create some configuration files and private key and certificate files locally. Be sure to create a working directory for those files.
1. Create a working directory.
```console
mkdir -p ${HOME}/scalardl-test/
```
## Step 4. Deploy cert-manager and issuer resource
This tutorial uses cert-manager to issue and manage private keys and certificates. You can deploy cert-manager on the Kubernetes cluster as follows:
1. Add the Jetstack helm repository.
```console
helm repo add jetstack https://charts.jetstack.io
```
1. Deploy cert-manager.
```console
helm install cert-manager jetstack/cert-manager \
--create-namespace \
--set installCRDs=true \
-n cert-manager
```
1. Check if the cert-manager containers are running.
```console
kubectl get pod -n cert-manager
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
cert-manager-6dc66985d4-6lvtt 1/1 Running 0 26s
cert-manager-cainjector-c7d4dbdd9-xlrpn 1/1 Running 0 26s
cert-manager-webhook-847d7676c9-ckcz2 1/1 Running 0 26s
```
1. Change the working directory to `${HOME}/scalardl-test/`.
```console
cd ${HOME}/scalardl-test/
```
1. Create a custom values file for private CA (`private-ca-custom-values.yaml`).
```console
cat << 'EOF' > ${HOME}/scalardl-test/private-ca-custom-values.yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: self-signed-issuer
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: self-signed-ca-cert
spec:
isCA: true
commonName: self-signed-ca
secretName: self-signed-ca-cert-secret
privateKey:
algorithm: ECDSA
size: 256
issuerRef:
name: self-signed-issuer
kind: Issuer
group: cert-manager.io
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: self-signed-ca
spec:
ca:
secretName: self-signed-ca-cert-secret
EOF
```
1. Deploy self-signed CA.
```console
kubectl apply -f ./private-ca-custom-values.yaml
```
1. Check if the issuer resources are `True`.
```console
kubectl get issuer
```
[Command execution result]
```console
NAME READY AGE
self-signed-ca True 6s
self-signed-issuer True 6s
```
## Step 5. Create database schemas for ScalarDL Ledger and ScalarDL Auditor by using Helm Charts
You'll deploy two ScalarDL Schema Loader pods on the Kubernetes cluster by using Helm Charts. The ScalarDL Schema Loader will create the database schemas for ScalarDL Ledger and Auditor in PostgreSQL.
1. Add the Scalar Helm Charts repository.
```console
helm repo add scalar-labs https://scalar-labs.github.io/helm-charts
```
1. Create a custom values file for ScalarDL Schema Loader for Ledger (`schema-loader-ledger-custom-values.yaml`).
```console
cat << 'EOF' > ${HOME}/scalardl-test/schema-loader-ledger-custom-values.yaml
schemaLoading:
schemaType: "ledger"
databaseProperties: |
scalar.db.contact_points=jdbc:postgresql://postgresql-ledger.default.svc.cluster.local:5432/postgres
scalar.db.username=${env:SCALAR_DL_LEDGER_POSTGRES_USERNAME}
scalar.db.password=${env:SCALAR_DL_LEDGER_POSTGRES_PASSWORD}
scalar.db.storage=jdbc
secretName: "schema-ledger-credentials-secret"
EOF
```
1. Create a custom values file for ScalarDL Schema Loader for Auditor (`schema-loader-auditor-custom-values.yaml`).
```console
cat << 'EOF' > ${HOME}/scalardl-test/schema-loader-auditor-custom-values.yaml
schemaLoading:
schemaType: "auditor"
databaseProperties: |
scalar.db.contact_points=jdbc:postgresql://postgresql-auditor.default.svc.cluster.local:5432/postgres
scalar.db.username=${env:SCALAR_DL_AUDITOR_POSTGRES_USERNAME}
scalar.db.password=${env:SCALAR_DL_AUDITOR_POSTGRES_PASSWORD}
scalar.db.storage=jdbc
secretName: "schema-auditor-credentials-secret"
EOF
```
1. Create a secret resource named `schema-ledger-credentials-secret` that includes a username and password for PostgreSQL for ScalarDL Ledger.
```console
kubectl create secret generic schema-ledger-credentials-secret \
--from-literal=SCALAR_DL_LEDGER_POSTGRES_USERNAME=postgres \
--from-literal=SCALAR_DL_LEDGER_POSTGRES_PASSWORD=postgres \
-n default
```
1. Create a secret resource named `schema-auditor-credentials-secret` that includes a username and password for PostgreSQL for ScalarDL Auditor.
```console
kubectl create secret generic schema-auditor-credentials-secret \
--from-literal=SCALAR_DL_AUDITOR_POSTGRES_USERNAME=postgres \
--from-literal=SCALAR_DL_AUDITOR_POSTGRES_PASSWORD=postgres \
-n default
```
1. Set the chart version of ScalarDL Schema Loader.
```console
SCALAR_DL_VERSION=3.9.1
SCALAR_DL_SCHEMA_LOADER_CHART_VERSION=$(helm search repo scalar-labs/schema-loading -l | grep -F "${SCALAR_DL_VERSION}" | awk '{print $2}' | sort --version-sort -r | head -n 1)
```
1. Deploy ScalarDL Schema Loader for ScalarDL Ledger.
```console
helm install schema-loader-ledger scalar-labs/schema-loading -f ${HOME}/scalardl-test/schema-loader-ledger-custom-values.yaml --version ${SCALAR_DL_SCHEMA_LOADER_CHART_VERSION} -n default
```
1. Deploy ScalarDL Schema Loader for ScalarDL Auditor.
```console
helm install schema-loader-auditor scalar-labs/schema-loading -f ${HOME}/scalardl-test/schema-loader-auditor-custom-values.yaml --version ${SCALAR_DL_SCHEMA_LOADER_CHART_VERSION} -n default
```
1. Check if the ScalarDL Schema Loader pods are deployed with the status `Completed`.
```console
kubectl get pod -n default
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-auditor-0 1/1 Running 0 2m56s
postgresql-ledger-0 1/1 Running 0 3m1s
schema-loader-auditor-schema-loading-dvc5r 0/1 Completed 0 6s
schema-loader-ledger-schema-loading-mtllb 0/1 Completed 0 10s
```
If the status of the ScalarDL Schema Loader pods are **ContainerCreating** or **Running**, wait for the `STATUS` column for those pods to show as `Completed`.
## Step 6. Deploy ScalarDL Ledger and ScalarDL Auditor on the Kubernetes cluster by using Helm Charts
1. Set your license key and certificate as environment variables. If you don't have a license key, please [contact us](https://www.scalar-labs.com/contact). For details about the value of `` and ``, see [How to Configure a License Key](../scalar-licensing/index.mdx).
```console
SCALAR_DL_LEDGER_LICENSE_KEY=''
SCALAR_DL_LEDGER_LICENSE_CHECK_CERT_PEM=''
SCALAR_DL_AUDITOR_LICENSE_KEY=''
SCALAR_DL_AUDITOR_LICENSE_CHECK_CERT_PEM=''
```
1. Create a custom values file for ScalarDL Ledger (`scalardl-ledger-custom-values.yaml`).
```console
cat << 'EOF' > ${HOME}/scalardl-test/scalardl-ledger-custom-values.yaml
envoy:
tls:
downstream:
enabled: true
certManager:
enabled: true
issuerRef:
name: self-signed-ca
dnsNames:
- envoy.scalar.example.com
upstream:
enabled: true
overrideAuthority: "ledger.scalardl.example.com"
ledger:
image:
repository: "ghcr.io/scalar-labs/scalardl-ledger-byol"
ledgerProperties: |
### Storage configurations
scalar.db.storage=jdbc
scalar.db.contact_points=jdbc:postgresql://postgresql-ledger.default.svc.cluster.local:5432/postgres
scalar.db.username=${env:SCALAR_DL_LEDGER_POSTGRES_USERNAME}
scalar.db.password=${env:SCALAR_DL_LEDGER_POSTGRES_PASSWORD}
### Ledger configurations
scalar.dl.ledger.proof.enabled=true
scalar.dl.ledger.auditor.enabled=true
scalar.dl.ledger.authentication.method=hmac
scalar.dl.ledger.authentication.hmac.cipher_key=${env:SCALAR_DL_LEDGER_HMAC_CIPHER_KEY}
scalar.dl.ledger.servers.authentication.hmac.secret_key=${env:SCALAR_DL_LEDGER_HMAC_SECRET_KEY}
### TLS configurations
scalar.dl.ledger.server.tls.enabled=true
scalar.dl.ledger.server.tls.cert_chain_path=/tls/scalardl-ledger/certs/tls.crt
scalar.dl.ledger.server.tls.private_key_path=/tls/scalardl-ledger/certs/tls.key
### License key configurations
scalar.dl.licensing.license_key=${env:SCALAR_DL_LEDGER_LICENSE_KEY}
scalar.dl.licensing.license_check_cert_pem=${env:SCALAR_DL_LEDGER_LICENSE_CHECK_CERT_PEM}
tls:
enabled: true
overrideAuthority: "ledger.scalardl.example.com"
certManager:
enabled: true
issuerRef:
name: self-signed-ca
dnsNames:
- ledger.scalardl.example.com
secretName: "ledger-credentials-secret"
EOF
```
1. Create a custom values file for ScalarDL Auditor (`scalardl-auditor-custom-values.yaml`).
```console
cat << 'EOF' > ${HOME}/scalardl-test/scalardl-auditor-custom-values.yaml
envoy:
tls:
downstream:
enabled: true
certManager:
enabled: true
issuerRef:
name: self-signed-ca
dnsNames:
- envoy.scalar.example.com
upstream:
enabled: true
overrideAuthority: "auditor.scalardl.example.com"
auditor:
image:
repository: "ghcr.io/scalar-labs/scalardl-auditor-byol"
auditorProperties: |
### Storage configurations
scalar.db.storage=jdbc
scalar.db.contact_points=jdbc:postgresql://postgresql-auditor.default.svc.cluster.local:5432/postgres
scalar.db.username=${env:SCALAR_DL_AUDITOR_POSTGRES_USERNAME}
scalar.db.password=${env:SCALAR_DL_AUDITOR_POSTGRES_PASSWORD}
### Auditor configurations
scalar.dl.auditor.ledger.host=scalardl-ledger-envoy.default.svc.cluster.local
scalar.dl.auditor.authentication.method=hmac
scalar.dl.auditor.authentication.hmac.cipher_key=${env:SCALAR_DL_AUDITOR_HMAC_CIPHER_KEY}
scalar.dl.auditor.servers.authentication.hmac.secret_key=${env:SCALAR_DL_AUDITOR_HMAC_SECRET_KEY}
### TLS configurations
scalar.dl.auditor.server.tls.enabled=true
scalar.dl.auditor.server.tls.cert_chain_path=/tls/scalardl-auditor/certs/tls.crt
scalar.dl.auditor.server.tls.private_key_path=/tls/scalardl-auditor/certs/tls.key
scalar.dl.auditor.tls.enabled=true
scalar.dl.auditor.tls.ca_root_cert_path=/tls/scalardl-ledger/certs/ca.crt
scalar.dl.auditor.tls.override_authority=envoy.scalar.example.com
### License key configurations
scalar.dl.licensing.license_key=${env:SCALAR_DL_AUDITOR_LICENSE_KEY}
scalar.dl.licensing.license_check_cert_pem=${env:SCALAR_DL_AUDITOR_LICENSE_CHECK_CERT_PEM}
tls:
enabled: true
overrideAuthority: "auditor.scalardl.example.com"
certManager:
enabled: true
issuerRef:
name: self-signed-ca
dnsNames:
- auditor.scalardl.example.com
secretName: "auditor-credentials-secret"
EOF
```
1. Create a secret resource named `ledger-credentials-secret` that includes credentials and a license key.
```console
kubectl create secret generic ledger-credentials-secret \
--from-literal=SCALAR_DL_LEDGER_POSTGRES_USERNAME=postgres \
--from-literal=SCALAR_DL_LEDGER_POSTGRES_PASSWORD=postgres \
--from-literal=SCALAR_DL_LEDGER_HMAC_CIPHER_KEY=ledger-hmac-cipher-key \
--from-literal=SCALAR_DL_LEDGER_HMAC_SECRET_KEY=scalardl-hmac-secret-key \
--from-literal=SCALAR_DL_LEDGER_LICENSE_KEY="${SCALAR_DL_LEDGER_LICENSE_KEY}" \
--from-file=SCALAR_DL_LEDGER_LICENSE_CHECK_CERT_PEM=<(echo ${SCALAR_DL_LEDGER_LICENSE_CHECK_CERT_PEM} | sed 's/\\n/\
/g') \
-n default
```
1. Create a secret resource named `auditor-credentials-secret` that includes credentials and a license key.
```console
kubectl create secret generic auditor-credentials-secret \
--from-literal=SCALAR_DL_AUDITOR_POSTGRES_USERNAME=postgres \
--from-literal=SCALAR_DL_AUDITOR_POSTGRES_PASSWORD=postgres \
--from-literal=SCALAR_DL_AUDITOR_HMAC_CIPHER_KEY=auditor-hmac-cipher-key \
--from-literal=SCALAR_DL_AUDITOR_HMAC_SECRET_KEY=scalardl-hmac-secret-key \
--from-literal=SCALAR_DL_AUDITOR_LICENSE_KEY="${SCALAR_DL_AUDITOR_LICENSE_KEY}" \
--from-file=SCALAR_DL_AUDITOR_LICENSE_CHECK_CERT_PEM=<(echo ${SCALAR_DL_AUDITOR_LICENSE_CHECK_CERT_PEM} | sed 's/\\n/\
/g') \
-n default
```
1. Create a secret resource named `auditor-keys` to disable the `digital-signature` authentication method. In this tutorial, you'll use the `hmac` authentication method instead of `digital-signature`.
```console
kubectl create secret generic auditor-keys \
--from-literal=tls.key=dummy-data-to-disable-digital-signature-method \
--from-literal=certificate=dummy-data-to-disable-digital-signature-method \
-n default
```
Note: If you use `hmac` as an authentication method, you have to create a dummy secret `auditor-key` to disable `digital-signature` on the Helm Chart side.
1. Set the chart version of ScalarDL Ledger and ScalarDL Auditor.
```console
SCALAR_DL_LEDGER_CHART_VERSION=$(helm search repo scalar-labs/scalardl -l | grep -v -e "scalar-labs/scalardl-audit" | grep -F "${SCALAR_DL_VERSION}" | awk '{print $2}' | sort --version-sort -r | head -n 1)
SCALAR_DL_AUDITOR_CHART_VERSION=$(helm search repo scalar-labs/scalardl-audit -l | grep -F "${SCALAR_DL_VERSION}" | awk '{print $2}' | sort --version-sort -r | head -n 1)
```
1. Deploy ScalarDL Ledger.
```console
helm install scalardl-ledger scalar-labs/scalardl -f ${HOME}/scalardl-test/scalardl-ledger-custom-values.yaml --version ${SCALAR_DL_LEDGER_CHART_VERSION} -n default
```
1. Deploy ScalarDL Auditor.
```console
helm install scalardl-auditor scalar-labs/scalardl-audit -f ${HOME}/scalardl-test/scalardl-auditor-custom-values.yaml --version ${SCALAR_DL_AUDITOR_CHART_VERSION} -n default
```
1. Check if the ScalarDL Ledger and ScalarDL Auditor pods are deployed.
```console
kubectl get pod -n default
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-auditor-0 1/1 Running 0 14m
postgresql-ledger-0 1/1 Running 0 14m
scalardl-auditor-auditor-5b885ff4c8-fwkpf 1/1 Running 0 18s
scalardl-auditor-auditor-5b885ff4c8-g69cb 1/1 Running 0 18s
scalardl-auditor-auditor-5b885ff4c8-nsmnq 1/1 Running 0 18s
scalardl-auditor-envoy-689bcbdf65-5mn6v 1/1 Running 0 18s
scalardl-auditor-envoy-689bcbdf65-fpq8j 1/1 Running 0 18s
scalardl-auditor-envoy-689bcbdf65-lsz2t 1/1 Running 0 18s
scalardl-ledger-envoy-547bbf7546-n7p5x 1/1 Running 0 26s
scalardl-ledger-envoy-547bbf7546-p8nwp 1/1 Running 0 26s
scalardl-ledger-envoy-547bbf7546-pskpb 1/1 Running 0 26s
scalardl-ledger-ledger-6db5dc8774-5zsbj 1/1 Running 0 26s
scalardl-ledger-ledger-6db5dc8774-vnmrw 1/1 Running 0 26s
scalardl-ledger-ledger-6db5dc8774-wpjvs 1/1 Running 0 26s
schema-loader-auditor-schema-loading-dvc5r 0/1 Completed 0 11m
schema-loader-ledger-schema-loading-mtllb 0/1 Completed 0 11m
```
If the ScalarDL Ledger and ScalarDL Auditor pods are deployed properly, the `STATUS` column for those pods will be displayed as `Running`.
1. Check if the ScalarDL Ledger and ScalarDL Auditor services are deployed.
```console
kubectl get svc -n default
```
[Command execution result]
```console
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 47d
postgresql-auditor ClusterIP 10.107.9.78 5432/TCP 15m
postgresql-auditor-hl ClusterIP None 5432/TCP 15m
postgresql-ledger ClusterIP 10.108.241.181 5432/TCP 15m
postgresql-ledger-hl ClusterIP None 5432/TCP 15m
scalardl-auditor-envoy ClusterIP 10.100.61.202 40051/TCP,40052/TCP 55s
scalardl-auditor-envoy-metrics ClusterIP 10.99.6.227 9001/TCP 55s
scalardl-auditor-headless ClusterIP None 40051/TCP,40053/TCP,40052/TCP 55s
scalardl-auditor-metrics ClusterIP 10.108.1.147 8080/TCP 55s
scalardl-ledger-envoy ClusterIP 10.101.191.116 50051/TCP,50052/TCP 61s
scalardl-ledger-envoy-metrics ClusterIP 10.106.52.103 9001/TCP 61s
scalardl-ledger-headless ClusterIP None 50051/TCP,50053/TCP,50052/TCP 61s
scalardl-ledger-metrics ClusterIP 10.99.122.106 8080/TCP 61s
```
If the ScalarDL Ledger and ScalarDL Auditor services are deployed properly, you can see private IP addresses in the `CLUSTER-IP` column.
:::note
The `CLUSTER-IP` values for `scalardl-ledger-headless`, `scalardl-auditor-headless`, `postgresql-ledger-hl`, and `postgresql-auditor-hl` are `None` since they have no IP addresses.
:::
## Step 7. Start a client container
You'll use the CA certificate file in a client container. Therefore, you'll need to create a secret resource and mount it to the client container.
1. Create a secret resource named `client-ca-cert`.
```console
kubectl create secret generic client-ca-cert --from-file=ca.crt=<(kubectl get secret self-signed-ca-cert-secret -o "jsonpath={.data['ca\.crt']}" | base64 -d) -n default
```
1. Create a manifest file for a client pod (`scalardl-client-pod.yaml`).
```console
cat << 'EOF' > ${HOME}/scalardl-test/scalardl-client-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: "scalardl-client"
spec:
containers:
- name: scalardl-client
image: eclipse-temurin:8-jdk
command: ['sleep']
args: ['inf']
env:
- name: SCALAR_DL_VERSION
value: SCALAR_DL_CLIENT_POD_SCALAR_DL_VERSION
volumeMounts:
- name: "client-ca-cert"
mountPath: "/certs/"
readOnly: true
volumes:
- name: "client-ca-cert"
secret:
secretName: "client-ca-cert"
restartPolicy: Never
EOF
```
1. Set the ScalarDL version in the manifest file.
```console
sed -i s/SCALAR_DL_CLIENT_POD_SCALAR_DL_VERSION/${SCALAR_DL_VERSION}/ ${HOME}/scalardl-test/scalardl-client-pod.yaml
```
1. Deploy the client pod.
```console
kubectl apply -f ${HOME}/scalardl-test/scalardl-client-pod.yaml -n default
```
1. Check if the client container is running.
```console
kubectl get pod scalardl-client -n default
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
scalardl-client 1/1 Running 0 4s
```
## Step 8. Run ScalarDL sample contracts in the client container
The following explains the minimum steps needed to run sample contracts. For more details about ScalarDL Ledger and ScalarDL Auditor, see the following:
* [Getting Started with ScalarDL](https://scalardl.scalar-labs.com/docs/latest/getting-started/)
* [Getting Started with ScalarDL Auditor](https://scalardl.scalar-labs.com/docs/latest/getting-started-auditor/)
1. Run bash in the client container.
```console
kubectl exec -it scalardl-client -n default -- bash
```
The commands in the following steps must be run in the client container.
1. Install the git, curl, and unzip commands in the client container.
```console
apt update && apt install -y git curl unzip
```
1. Clone the ScalarDL Java Client SDK git repository.
```console
git clone https://github.com/scalar-labs/scalardl-java-client-sdk.git
```
1. Change the working directory to `scalardl-java-client-sdk/`.
```console
cd scalardl-java-client-sdk/
```
```console
pwd
```
[Command execution result]
```console
/scalardl-java-client-sdk
```
1. Change the branch to the version you're using.
```console
git checkout -b v${SCALAR_DL_VERSION} refs/tags/v${SCALAR_DL_VERSION}
```
1. Build the sample contracts.
```console
./gradlew assemble
```
1. Download the CLI tools for ScalarDL from [ScalarDL Java Client SDK Releases](https://github.com/scalar-labs/scalardl-java-client-sdk/releases).
```console
curl -OL https://github.com/scalar-labs/scalardl-java-client-sdk/releases/download/v${SCALAR_DL_VERSION}/scalardl-java-client-sdk-${SCALAR_DL_VERSION}.zip
```
1. Unzip the `scalardl-java-client-sdk-${SCALAR_DL_VERSION}.zip` file.
```console
unzip ./scalardl-java-client-sdk-${SCALAR_DL_VERSION}.zip
```
1. Create a configuration file named `client.properties` to access ScalarDL Ledger and ScalarDL Auditor on the Kubernetes cluster.
```console
cat << 'EOF' > client.properties
# Ledger configuration
scalar.dl.client.server.host=scalardl-ledger-envoy.default.svc.cluster.local
scalar.dl.client.tls.enabled=true
scalar.dl.client.tls.ca_root_cert_path=/certs/ca.crt
scalar.dl.client.tls.override_authority=envoy.scalar.example.com
# Auditor configuration
scalar.dl.client.auditor.enabled=true
scalar.dl.client.auditor.host=scalardl-auditor-envoy.default.svc.cluster.local
scalar.dl.client.auditor.tls.enabled=true
scalar.dl.client.auditor.tls.ca_root_cert_path=/certs/ca.crt
scalar.dl.client.auditor.tls.override_authority=envoy.scalar.example.com
# Client configuration
scalar.dl.client.authentication_method=hmac
scalar.dl.client.entity.id=client
scalar.dl.client.entity.identity.hmac.secret_key=scalardl-hmac-client-secert-key
EOF
```
1. Register the client secret.
```console
./scalardl-java-client-sdk-${SCALAR_DL_VERSION}/bin/scalardl register-secret --config ./client.properties
```
1. Register the sample contract `StateUpdater`.
```console
./scalardl-java-client-sdk-${SCALAR_DL_VERSION}/bin/scalardl register-contract --config ./client.properties --contract-id StateUpdater --contract-binary-name com.org1.contract.StateUpdater --contract-class-file ./build/classes/java/main/com/org1/contract/StateUpdater.class
```
1. Register the sample contract `StateReader`.
```console
./scalardl-java-client-sdk-${SCALAR_DL_VERSION}/bin/scalardl register-contract --config ./client.properties --contract-id StateReader --contract-binary-name com.org1.contract.StateReader --contract-class-file ./build/classes/java/main/com/org1/contract/StateReader.class
```
1. Register the contract `ValidateLedger` to execute a validate request.
```console
./scalardl-java-client-sdk-${SCALAR_DL_VERSION}/bin/scalardl register-contract --config ./client.properties --contract-id validate-ledger --contract-binary-name com.scalar.dl.client.contract.ValidateLedger --contract-class-file ./build/classes/java/main/com/scalar/dl/client/contract/ValidateLedger.class
```
1. Execute the contract `StateUpdater`.
```console
./scalardl-java-client-sdk-${SCALAR_DL_VERSION}/bin/scalardl execute-contract --config ./client.properties --contract-id StateUpdater --contract-argument '{"asset_id": "test_asset", "state": 3}'
```
This sample contract updates the `state` (value) of the asset named `test_asset` to `3`.
1. Execute the contract `StateReader`.
```console
./scalardl-java-client-sdk-${SCALAR_DL_VERSION}/bin/scalardl execute-contract --config ./client.properties --contract-id StateReader --contract-argument '{"asset_id": "test_asset"}'
```
[Command execution result]
```console
Contract result:
{
"id" : "test_asset",
"age" : 0,
"output" : {
"state" : 3
}
}
```
### Reference
* If the asset data is not tampered with, running the `execute-contract` command to request contract execution will return `OK` as a result.
* If the asset data is tampered with (for example, if the `state` value in the database is tampered with), running the `execute-contract` command to request contract execution will return a value other than `OK` (for example, `INCONSISTENT_STATES`) as a result. See the following as an example for how ScalarDL detects data tampering.
[Command execution result (if the asset data is tampered with)]
```console
{
"status_code" : "INCONSISTENT_STATES",
"error_message" : "The results from Ledger and Auditor don't match"
}
```
1. Execute a validation request for the asset.
```console
./scalardl-java-client-sdk-${SCALAR_DL_VERSION}/bin/scalardl validate-ledger --config ./client.properties --asset-id "test_asset"
```
[Command execution result]
```console
{
"status_code" : "OK",
"Ledger" : {
"id" : "test_asset",
"age" : 0,
"nonce" : "3533427d-03cf-41d1-bf95-4d31eb0cb24d",
"hash" : "FiquvtPMKLlxKf4VGoccSAGsi9ptn4ozYVVTwdSzEQ0=",
"signature" : "MEYCIQDiiXqzw6K+Ml4uvn8rK43o5wHWESU3hoXnZPi6/OeKVwIhAM+tFBcapl6zg47Uq0Uc8nVNGWNHZLBDBGve3F0xkzTR"
},
"Auditor" : {
"id" : "test_asset",
"age" : 0,
"nonce" : "3533427d-03cf-41d1-bf95-4d31eb0cb24d",
"hash" : "FiquvtPMKLlxKf4VGoccSAGsi9ptn4ozYVVTwdSzEQ0=",
"signature" : "MEUCIQDLsfUR2PmxSvfpL3YvHJUkz00RDpjCdctkroZKXE8d5QIgH73FQH2e11jfnynD00Pp9DrIG1vYizxDsvxUsMPo9IU="
}
}
```
### Reference
* If the asset data is not tampered with, running the `validate-ledger` command to request validation will return `OK` as the result.
* If the asset data is tampered with (for example, if the `state` value in the database is tampered with), running the `validate-ledger` command to request validation will return a value other than `OK` (for example, `INVALID_OUTPUT`) as a result. See the following as an example for how ScalarDL detects data tampering.
[Command execution result (if the asset data is tampered with)]
```console
{
"status_code" : "INCONSISTENT_STATES",
"error_message" : "The results from Ledger and Auditor don't match"
}
```
1. Exit from the client container.
```console
exit
```
## Step 9. Delete all resources
After completing the ScalarDL Ledger and ScalarDL Auditor tests on the Kubernetes cluster, remove all resources.
1. Uninstall ScalarDL Ledger, ScalarDL Auditor, ScalarDL Schema Loader, and PostgreSQL.
```console
helm uninstall -n default scalardl-ledger schema-loader-ledger postgresql-ledger scalardl-auditor schema-loader-auditor postgresql-auditor
```
1. Remove the self-signed CA.
```
kubectl delete -f ./private-ca-custom-values.yaml
```
1. Uninstall cert-manager.
```console
helm uninstall -n cert-manager cert-manager
```
1. Remove the client container.
```
kubectl delete pod scalardl-client --grace-period 0 -n default
```
1. Remove the secret resources.
```
kubectl delete secrets self-signed-ca-cert-secret schema-ledger-credentials-secret schema-auditor-credentials-secret scalardl-ledger-tls-cert scalardl-ledger-envoy-tls-cert scalardl-auditor-tls-cert scalardl-auditor-envoy-tls-cert ledger-credentials-secret auditor-credentials-secret client-ca-cert auditor-keys
```
1. Remove the namespace `cert-manager`.
```
kubectl delete ns cert-manager
```
1. Remove the working directory and sample files (configuration files).
```console
cd ${HOME}
```
```console
rm -rf ${HOME}/scalardl-test/
```
## Further reading
You can see how to get started with monitoring or logging for Scalar products in the following tutorials:
* [Getting Started with Helm Charts (Monitoring using Prometheus Operator)](getting-started-monitoring.mdx)
* [Getting Started with Helm Charts (Logging using Loki Stack)](getting-started-logging.mdx)
* [Getting Started with Helm Charts (Scalar Manager)](getting-started-scalar-manager.mdx)
================================================
FILE: docs/helm-charts/getting-started-scalardl-auditor-tls.mdx
================================================
---
tags:
- Enterprise
displayed_sidebar: docsEnglish
---
# Getting Started with Helm Charts (ScalarDL Ledger and Auditor with TLS / Auditor Mode)
This tutorial explains how to get started with ScalarDL Ledger and ScalarDL Auditor with TLS configurations by using Helm Charts on a Kubernetes cluster as a test environment. Before starting, you should already have a Mac or Linux environment for testing. In addition, although this tutorial mentions using **minikube**, the steps described should work in any Kubernetes cluster.
## Requirements
* You need to have a license key (trial license or commercial license) for ScalarDL. If you don't have a license key, please [contact us](https://www.scalar-labs.com/contact).
* You need to use ScalarDL 3.9 or later, which supports TLS.
:::note
To make Byzantine fault detection with auditing work properly, ScalarDL Ledger and ScalarDL Auditor should be deployed and managed in different administrative domains. However, in this tutorial, we will deploy ScalarDL Ledger and ScalarDL Auditor in the same Kubernetes cluster to make the test easier.
:::
## What you'll create
In this tutorial, you'll deploy the following components on a Kubernetes cluster in the following way:
```
+-----------------------------------------------------------------------------------------------------------------------------+
| [Kubernetes Cluster] |
| [Pod] [Pod] [Pod] |
| |
| +-------+ +---------+ |
| +---> | Envoy | ---+ +---> | Ledger | ---+ |
| | +-------+ | | +---------+ | |
| | | | | |
| +---------+ | +-------+ | +-----------+ | +---------+ | +---------------+ |
| +---> | Service | ---+---> | Envoy | ---+---> | Service | ---+---> | Ledger | ---+---> | PostgreSQL | |
| | | (Envoy) | | +-------+ | | (Ledger) | | +---------+ | | (For Ledger) | |
| | +---------+ | | +-----------+ | | +---------------+ |
| [Pod] | | +-------+ | | +---------+ | |
| | +---> | Envoy | ---+ +---> | Ledger | ---+ |
| +--------+ | +-------+ +---------+ |
| | Client | ---+ |
| +--------+ | +-------+ +---------+ |
| | +---> | Envoy | ---+ +---> | Auditor | ---+ |
| | | +-------+ | | +---------+ | |
| | | | | | |
| | +---------+ | +-------+ | +-----------+ | +---------+ | +---------------+ |
| +---> | Service | ---+---> | Envoy | ---+---> | Service | ---+---> | Auditor | ---+---> | PostgreSQL | |
| | (Envoy) | | +-------+ | | (Auditor) | | +---------+ | | (For Auditor) | |
| +---------+ | | +-----------+ | | +---------------+ |
| | +-------+ | | +---------+ | |
| +---> | Envoy | ---+ +---> | Auditor | ---+ |
| +-------+ +---------+ |
| |
+-----------------------------------------------------------------------------------------------------------------------------+
```
You'll also create the following private key and certificate files for TLS connections.
```
+----------------------+
+---> | For Scalar Envoy |
| +----------------------+
| | envoy-key.pem |
| | envoy.pem |
| +----------------------+
|
+----------------------+ | +----------------------+
| Self-signed CA | ---(Sign certificates)---+---> | For ScalarDL Ledger |
+----------------------+ | +----------------------+
| ca-key.pem | | | ledger-key.pem |
| ca.pem | | | ledger.pem |
+----------------------+ | +----------------------+
|
| +----------------------+
+---> | For ScalarDL Auditor |
+----------------------+
| auditor-key.pem |
| auditor.pem |
+----------------------+
```
You'll set each private key and certificate file as follows to enable TLS in each connection.
```
+--------------------------------+ +--------------------------------+
+-------(Normal request)-----> | Envoy for ScalarDL Ledger | ---> | ScalarDL Ledger |
| +--------------------------------+ +--------------------------------+
| +---(Recovery request)---> | envoy-key.pem | ---> | ledger-key.pem |
| | | envoy.pem | | ledger.pem |
| | | ca.pem (to verify ledger.pem) | | ca.pem (used for health check) |
| | +--------------------------------+ +--------------------------------+
+--------------------------------+ | |
| Client | ---+ |
+--------------------------------+ | +--------------------------------------------------------------------------------------------------------+
| ca.pem (to verify envoy.pem) | | |
+--------------------------------+ | |
| +--------------------------------+ +--------------------------------+ |
+-------(Normal request)-----> | Envoy for ScalarDL Auditor | ---> | ScalarDL Auditor | ---+
+--------------------------------+ +--------------------------------+
| envoy-key.pem | | auditor-key.pem |
| envoy.pem | | auditor.pem |
| ca.pem (to verify auditor.pem) | | ca.pem (used for health check) |
+--------------------------------+ | ca.pem (to verify ledger.pem) |
+--------------------------------+
```
The following connections exist amongst the ScalarDL-related components:
* **`Client - Envoy for ScalarDL Ledger`:** When you execute a ScalarDL API function, the client accesses Envoy for ScalarDL Ledger.
* **`Client - Envoy for ScalarDL Auditor`:** When you execute a ScalarDL API function, the client accesses Envoy for ScalarDL Auditor.
* **`Envoy for ScalarDL Ledger - ScalarDL Ledger`:** Envoy works as an L7 (gRPC) load balancer in front of ScalarDL Ledger.
* **`Envoy for ScalarDL Auditor - ScalarDL Auditor`:** Envoy works as an L7 (gRPC) load balancer in front of ScalarDL Auditor.
* **`ScalarDL Auditor - Envoy for ScalarDL Ledger (ScalarDL Ledger)`:** When ScalarDL needs to run the recovery process to keep data consistent, ScalarDL Auditor runs the request against ScalarDL Ledger via Envoy.
## Step 1. Start a Kubernetes cluster and install tools
You need to prepare a Kubernetes cluster and install some tools (`kubectl`, `helm`, `cfssl`, and `cfssljson`). For more details on how to install them, see [Getting Started with Scalar Helm Charts](getting-started-scalar-helm-charts.mdx).
## Step 2. Start the PostgreSQL containers
ScalarDL Ledger and ScalarDL Auditor must use some type of database system as a backend database. In this tutorial, you'll use PostgreSQL.
You can deploy PostgreSQL on the Kubernetes cluster as follows:
1. Add the Bitnami helm repository.
```console
helm repo add bitnami https://charts.bitnami.com/bitnami
```
1. Deploy PostgreSQL for Ledger.
```console
helm install postgresql-ledger bitnami/postgresql \
--set auth.postgresPassword=postgres \
--set primary.persistence.enabled=false \
-n default
```
1. Deploy PostgreSQL for Auditor.
```console
helm install postgresql-auditor bitnami/postgresql \
--set auth.postgresPassword=postgres \
--set primary.persistence.enabled=false \
-n default
```
1. Check if the PostgreSQL containers are running.
```console
kubectl get pod -n default
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-auditor-0 1/1 Running 0 11s
postgresql-ledger-0 1/1 Running 0 16s
```
## Step 3. Create a working directory
You'll create some configuration files and private key and certificate files locally. Be sure to create a working directory for those files.
1. Create a working directory.
```console
mkdir -p ${HOME}/scalardl-test/certs/
```
## Step 4. Create private key and certificate files
You'll create private key and a certificate files.
1. Change the working directory to `${HOME}/scalardl-test/certs/`.
```console
cd ${HOME}/scalardl-test/certs/
```
1. Create a JSON file that includes CA information.
```console
cat << 'EOF' > ${HOME}/scalardl-test/certs/ca.json
{
"CN": "scalar-test-ca",
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "JP",
"ST": "Tokyo",
"L": "Shinjuku",
"O": "Scalar Test CA"
}
]
}
EOF
```
1. Create the CA private key and certificate files.
```console
cfssl gencert -initca ca.json | cfssljson -bare ca
```
1. Create a JSON file that includes CA configurations.
```console
cat << 'EOF' > ${HOME}/scalardl-test/certs/ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"scalar-test-ca": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth"
]
}
}
}
}
EOF
```
1. Create a JSON file that includes Envoy information.
```console
cat << 'EOF' > ${HOME}/scalardl-test/certs/envoy.json
{
"CN": "scalar-envoy",
"hosts": [
"envoy.scalar.example.com",
"localhost"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "JP",
"ST": "Tokyo",
"L": "Shinjuku",
"O": "Scalar Envoy Test"
}
]
}
EOF
```
1. Create a JSON file that includes ScalarDL Ledger information.
```console
cat << 'EOF' > ${HOME}/scalardl-test/certs/ledger.json
{
"CN": "scalardl-ledger",
"hosts": [
"ledger.scalardl.example.com",
"localhost"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "JP",
"ST": "Tokyo",
"L": "Shinjuku",
"O": "ScalarDL Ledger Test"
}
]
}
EOF
```
1. Create a JSON file that includes ScalarDL Auditor information.
```console
cat << 'EOF' > ${HOME}/scalardl-test/certs/auditor.json
{
"CN": "scalardl-auditor",
"hosts": [
"auditor.scalardl.example.com",
"localhost"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "JP",
"ST": "Tokyo",
"L": "Shinjuku",
"O": "ScalarDL Auditor Test"
}
]
}
EOF
```
1. Create private key and certificate files for Envoy.
```console
cfssl gencert -ca ca.pem -ca-key ca-key.pem -config ca-config.json -profile scalar-test-ca envoy.json | cfssljson -bare envoy
```
1. Create private key and certificate files for ScalarDL Ledger.
```console
cfssl gencert -ca ca.pem -ca-key ca-key.pem -config ca-config.json -profile scalar-test-ca ledger.json | cfssljson -bare ledger
```
1. Create private key and certificate files for ScalarDL Auditor.
```console
cfssl gencert -ca ca.pem -ca-key ca-key.pem -config ca-config.json -profile scalar-test-ca auditor.json | cfssljson -bare auditor
```
1. Confirm that the private key and certificate files were created.
```console
ls -1
```
[Command execution result]
```console
auditor-key.pem
auditor.csr
auditor.json
auditor.pem
ca-config.json
ca-key.pem
ca.csr
ca.json
ca.pem
envoy-key.pem
envoy.csr
envoy.json
envoy.pem
ledger-key.pem
ledger.csr
ledger.json
ledger.pem
```
## Step 5. Create database schemas for ScalarDL Ledger and ScalarDL Auditor by using Helm Charts
You'll deploy two ScalarDL Schema Loader pods on the Kubernetes cluster by using Helm Charts. The ScalarDL Schema Loader will create the database schemas for ScalarDL Ledger and Auditor in PostgreSQL.
1. Change the working directory to `${HOME}/scalardl-test/`.
```console
cd ${HOME}/scalardl-test/
```
1. Add the Scalar Helm Charts repository.
```console
helm repo add scalar-labs https://scalar-labs.github.io/helm-charts
```
1. Create a custom values file for ScalarDL Schema Loader for Ledger (`schema-loader-ledger-custom-values.yaml`).
```console
cat << 'EOF' > ${HOME}/scalardl-test/schema-loader-ledger-custom-values.yaml
schemaLoading:
schemaType: "ledger"
databaseProperties: |
scalar.db.contact_points=jdbc:postgresql://postgresql-ledger.default.svc.cluster.local:5432/postgres
scalar.db.username=${env:SCALAR_DL_LEDGER_POSTGRES_USERNAME}
scalar.db.password=${env:SCALAR_DL_LEDGER_POSTGRES_PASSWORD}
scalar.db.storage=jdbc
secretName: "schema-ledger-credentials-secret"
EOF
```
1. Create a custom values file for ScalarDL Schema Loader for Auditor (`schema-loader-auditor-custom-values.yaml`).
```console
cat << 'EOF' > ${HOME}/scalardl-test/schema-loader-auditor-custom-values.yaml
schemaLoading:
schemaType: "auditor"
databaseProperties: |
scalar.db.contact_points=jdbc:postgresql://postgresql-auditor.default.svc.cluster.local:5432/postgres
scalar.db.username=${env:SCALAR_DL_AUDITOR_POSTGRES_USERNAME}
scalar.db.password=${env:SCALAR_DL_AUDITOR_POSTGRES_PASSWORD}
scalar.db.storage=jdbc
secretName: "schema-auditor-credentials-secret"
EOF
```
1. Create a secret resource named `schema-ledger-credentials-secret` that includes a username and password for PostgreSQL for ScalarDL Ledger.
```console
kubectl create secret generic schema-ledger-credentials-secret \
--from-literal=SCALAR_DL_LEDGER_POSTGRES_USERNAME=postgres \
--from-literal=SCALAR_DL_LEDGER_POSTGRES_PASSWORD=postgres \
-n default
```
1. Create a secret resource named `schema-auditor-credentials-secret` that includes a username and password for PostgreSQL for ScalarDL Auditor.
```console
kubectl create secret generic schema-auditor-credentials-secret \
--from-literal=SCALAR_DL_AUDITOR_POSTGRES_USERNAME=postgres \
--from-literal=SCALAR_DL_AUDITOR_POSTGRES_PASSWORD=postgres \
-n default
```
1. Set the chart version of ScalarDL Schema Loader.
```console
SCALAR_DL_VERSION=3.9.1
SCALAR_DL_SCHEMA_LOADER_CHART_VERSION=$(helm search repo scalar-labs/schema-loading -l | grep -F "${SCALAR_DL_VERSION}" | awk '{print $2}' | sort --version-sort -r | head -n 1)
```
1. Deploy ScalarDL Schema Loader for ScalarDL Ledger.
```console
helm install schema-loader-ledger scalar-labs/schema-loading -f ${HOME}/scalardl-test/schema-loader-ledger-custom-values.yaml --version ${SCALAR_DL_SCHEMA_LOADER_CHART_VERSION} -n default
```
1. Deploy ScalarDL Schema Loader for ScalarDL Auditor.
```console
helm install schema-loader-auditor scalar-labs/schema-loading -f ${HOME}/scalardl-test/schema-loader-auditor-custom-values.yaml --version ${SCALAR_DL_SCHEMA_LOADER_CHART_VERSION} -n default
```
1. Check if the ScalarDL Schema Loader pods are deployed with the status `Completed`.
```console
kubectl get pod -n default
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-auditor-0 1/1 Running 0 2m56s
postgresql-ledger-0 1/1 Running 0 3m1s
schema-loader-auditor-schema-loading-dvc5r 0/1 Completed 0 6s
schema-loader-ledger-schema-loading-mtllb 0/1 Completed 0 10s
```
If the status of the ScalarDL Schema Loader pods are **ContainerCreating** or **Running**, wait for the `STATUS` column for those pods to show as `Completed`.
## Step 6. Deploy ScalarDL Ledger and ScalarDL Auditor on the Kubernetes cluster by using Helm Charts
1. Set your license key and certificate as environment variables. If you don't have a license key, please [contact us](https://www.scalar-labs.com/contact). For details about the value of `` and ``, see [How to Configure a License Key](../scalar-licensing/index.mdx).
```console
SCALAR_DL_LEDGER_LICENSE_KEY=''
SCALAR_DL_LEDGER_LICENSE_CHECK_CERT_PEM=''
SCALAR_DL_AUDITOR_LICENSE_KEY=''
SCALAR_DL_AUDITOR_LICENSE_CHECK_CERT_PEM=''
```
1. Create a custom values file for ScalarDL Ledger (`scalardl-ledger-custom-values.yaml`).
```console
cat << 'EOF' > ${HOME}/scalardl-test/scalardl-ledger-custom-values.yaml
envoy:
tls:
downstream:
enabled: true
certChainSecret: "envoy-tls-cert"
privateKeySecret: "envoy-tls-key"
upstream:
enabled: true
overrideAuthority: "ledger.scalardl.example.com"
caRootCertSecret: "scalardl-ledger-tls-ca"
ledger:
image:
repository: "ghcr.io/scalar-labs/scalardl-ledger-byol"
ledgerProperties: |
### Storage configurations
scalar.db.storage=jdbc
scalar.db.contact_points=jdbc:postgresql://postgresql-ledger.default.svc.cluster.local:5432/postgres
scalar.db.username=${env:SCALAR_DL_LEDGER_POSTGRES_USERNAME}
scalar.db.password=${env:SCALAR_DL_LEDGER_POSTGRES_PASSWORD}
### Ledger configurations
scalar.dl.ledger.proof.enabled=true
scalar.dl.ledger.auditor.enabled=true
scalar.dl.ledger.authentication.method=hmac
scalar.dl.ledger.authentication.hmac.cipher_key=${env:SCALAR_DL_LEDGER_HMAC_CIPHER_KEY}
scalar.dl.ledger.servers.authentication.hmac.secret_key=${env:SCALAR_DL_LEDGER_HMAC_SECRET_KEY}
### TLS configurations
scalar.dl.ledger.server.tls.enabled=true
scalar.dl.ledger.server.tls.cert_chain_path=/tls/scalardl-ledger/certs/tls.crt
scalar.dl.ledger.server.tls.private_key_path=/tls/scalardl-ledger/certs/tls.key
### License key configurations
scalar.dl.licensing.license_key=${env:SCALAR_DL_LEDGER_LICENSE_KEY}
scalar.dl.licensing.license_check_cert_pem=${env:SCALAR_DL_LEDGER_LICENSE_CHECK_CERT_PEM}
tls:
enabled: true
overrideAuthority: "ledger.scalardl.example.com"
caRootCertSecret: "scalardl-ledger-tls-ca"
certChainSecret: "scalardl-ledger-tls-cert"
privateKeySecret: "scalardl-ledger-tls-key"
secretName: "ledger-credentials-secret"
EOF
```
1. Create a custom values file for ScalarDL Auditor (`scalardl-auditor-custom-values.yaml`).
```console
cat << 'EOF' > ${HOME}/scalardl-test/scalardl-auditor-custom-values.yaml
envoy:
tls:
downstream:
enabled: true
certChainSecret: "envoy-tls-cert"
privateKeySecret: "envoy-tls-key"
upstream:
enabled: true
overrideAuthority: "auditor.scalardl.example.com"
caRootCertSecret: "scalardl-auditor-tls-ca"
auditor:
image:
repository: "ghcr.io/scalar-labs/scalardl-auditor-byol"
auditorProperties: |
### Storage configurations
scalar.db.storage=jdbc
scalar.db.contact_points=jdbc:postgresql://postgresql-auditor.default.svc.cluster.local:5432/postgres
scalar.db.username=${env:SCALAR_DL_AUDITOR_POSTGRES_USERNAME}
scalar.db.password=${env:SCALAR_DL_AUDITOR_POSTGRES_PASSWORD}
### Auditor configurations
scalar.dl.auditor.ledger.host=scalardl-ledger-envoy.default.svc.cluster.local
scalar.dl.auditor.authentication.method=hmac
scalar.dl.auditor.authentication.hmac.cipher_key=${env:SCALAR_DL_AUDITOR_HMAC_CIPHER_KEY}
scalar.dl.auditor.servers.authentication.hmac.secret_key=${env:SCALAR_DL_AUDITOR_HMAC_SECRET_KEY}
### TLS configurations
scalar.dl.auditor.server.tls.enabled=true
scalar.dl.auditor.server.tls.cert_chain_path=/tls/scalardl-auditor/certs/tls.crt
scalar.dl.auditor.server.tls.private_key_path=/tls/scalardl-auditor/certs/tls.key
scalar.dl.auditor.tls.enabled=true
scalar.dl.auditor.tls.ca_root_cert_path=/tls/scalardl-ledger/certs/ca.crt
scalar.dl.auditor.tls.override_authority=envoy.scalar.example.com
### License key configurations
scalar.dl.licensing.license_key=${env:SCALAR_DL_AUDITOR_LICENSE_KEY}
scalar.dl.licensing.license_check_cert_pem=${env:SCALAR_DL_AUDITOR_LICENSE_CHECK_CERT_PEM}
tls:
enabled: true
overrideAuthority: "auditor.scalardl.example.com"
caRootCertSecret: "scalardl-auditor-tls-ca"
certChainSecret: "scalardl-auditor-tls-cert"
privateKeySecret: "scalardl-auditor-tls-key"
caRootCertForLedgerSecret: "scalardl-auditor-tls-ca-for-ledger"
secretName: "auditor-credentials-secret"
EOF
```
1. Create a secret resource named `ledger-credentials-secret` that includes credentials and a license key.
```console
kubectl create secret generic ledger-credentials-secret \
--from-literal=SCALAR_DL_LEDGER_POSTGRES_USERNAME=postgres \
--from-literal=SCALAR_DL_LEDGER_POSTGRES_PASSWORD=postgres \
--from-literal=SCALAR_DL_LEDGER_HMAC_CIPHER_KEY=ledger-hmac-cipher-key \
--from-literal=SCALAR_DL_LEDGER_HMAC_SECRET_KEY=scalardl-hmac-secret-key \
--from-literal=SCALAR_DL_LEDGER_LICENSE_KEY="${SCALAR_DL_LEDGER_LICENSE_KEY}" \
--from-file=SCALAR_DL_LEDGER_LICENSE_CHECK_CERT_PEM=<(echo ${SCALAR_DL_LEDGER_LICENSE_CHECK_CERT_PEM} | sed 's/\\n/\
/g') \
-n default
```
1. Create a secret resource named `auditor-credentials-secret` that includes credentials and a license key.
```console
kubectl create secret generic auditor-credentials-secret \
--from-literal=SCALAR_DL_AUDITOR_POSTGRES_USERNAME=postgres \
--from-literal=SCALAR_DL_AUDITOR_POSTGRES_PASSWORD=postgres \
--from-literal=SCALAR_DL_AUDITOR_HMAC_CIPHER_KEY=auditor-hmac-cipher-key \
--from-literal=SCALAR_DL_AUDITOR_HMAC_SECRET_KEY=scalardl-hmac-secret-key \
--from-literal=SCALAR_DL_AUDITOR_LICENSE_KEY="${SCALAR_DL_AUDITOR_LICENSE_KEY}" \
--from-file=SCALAR_DL_AUDITOR_LICENSE_CHECK_CERT_PEM=<(echo ${SCALAR_DL_AUDITOR_LICENSE_CHECK_CERT_PEM} | sed 's/\\n/\
/g') \
-n default
```
1. Create secret resources that include the private key and certificate files for Envoy.
```console
kubectl create secret generic envoy-tls-cert --from-file=tls.crt=${HOME}/scalardl-test/certs/envoy.pem -n default
kubectl create secret generic envoy-tls-key --from-file=tls.key=${HOME}/scalardl-test/certs/envoy-key.pem -n default
```
1. Create secret resources that include the private key, certificate, and CA certificate files for ScalarDL Ledger.
```console
kubectl create secret generic scalardl-ledger-tls-ca --from-file=ca.crt=${HOME}/scalardl-test/certs/ca.pem -n default
kubectl create secret generic scalardl-ledger-tls-cert --from-file=tls.crt=${HOME}/scalardl-test/certs/ledger.pem -n default
kubectl create secret generic scalardl-ledger-tls-key --from-file=tls.key=${HOME}/scalardl-test/certs/ledger-key.pem -n default
```
1. Create secret resources that include the private key, certificate, and CA certificate files for ScalarDL Auditor.
```console
kubectl create secret generic scalardl-auditor-tls-ca --from-file=ca.crt=${HOME}/scalardl-test/certs/ca.pem -n default
kubectl create secret generic scalardl-auditor-tls-cert --from-file=tls.crt=${HOME}/scalardl-test/certs/auditor.pem -n default
kubectl create secret generic scalardl-auditor-tls-key --from-file=tls.key=${HOME}/scalardl-test/certs/auditor-key.pem -n default
kubectl create secret generic scalardl-auditor-tls-ca-for-ledger --from-file=ca.crt=${HOME}/scalardl-test/certs/ca.pem -n default
```
1. Create a secret resource named `auditor-keys` to disable the `digital-signature` authentication method. In this tutorial, you'll use the `hmac` authentication method instead of `digital-signature`.
```console
kubectl create secret generic auditor-keys \
--from-literal=tls.key=dummy-data-to-disable-digital-signature-method \
--from-literal=certificate=dummy-data-to-disable-digital-signature-method \
-n default
```
Note: If you use `hmac` as an authentication method, you have to create a dummy secret `auditor-key` to disable `digital-signature` on the helm chart side.
1. Set the chart version of ScalarDL Ledger and ScalarDL Auditor.
```console
SCALAR_DL_LEDGER_CHART_VERSION=$(helm search repo scalar-labs/scalardl -l | grep -v -e "scalar-labs/scalardl-audit" | grep -F "${SCALAR_DL_VERSION}" | awk '{print $2}' | sort --version-sort -r | head -n 1)
SCALAR_DL_AUDITOR_CHART_VERSION=$(helm search repo scalar-labs/scalardl-audit -l | grep -F "${SCALAR_DL_VERSION}" | awk '{print $2}' | sort --version-sort -r | head -n 1)
```
1. Deploy ScalarDL Ledger.
```console
helm install scalardl-ledger scalar-labs/scalardl -f ${HOME}/scalardl-test/scalardl-ledger-custom-values.yaml --version ${SCALAR_DL_LEDGER_CHART_VERSION} -n default
```
1. Deploy ScalarDL Auditor.
```console
helm install scalardl-auditor scalar-labs/scalardl-audit -f ${HOME}/scalardl-test/scalardl-auditor-custom-values.yaml --version ${SCALAR_DL_AUDITOR_CHART_VERSION} -n default
```
1. Check if the ScalarDL Ledger and ScalarDL Auditor pods are deployed.
```console
kubectl get pod -n default
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-auditor-0 1/1 Running 0 14m
postgresql-ledger-0 1/1 Running 0 14m
scalardl-auditor-auditor-5b885ff4c8-fwkpf 1/1 Running 0 18s
scalardl-auditor-auditor-5b885ff4c8-g69cb 1/1 Running 0 18s
scalardl-auditor-auditor-5b885ff4c8-nsmnq 1/1 Running 0 18s
scalardl-auditor-envoy-689bcbdf65-5mn6v 1/1 Running 0 18s
scalardl-auditor-envoy-689bcbdf65-fpq8j 1/1 Running 0 18s
scalardl-auditor-envoy-689bcbdf65-lsz2t 1/1 Running 0 18s
scalardl-ledger-envoy-547bbf7546-n7p5x 1/1 Running 0 26s
scalardl-ledger-envoy-547bbf7546-p8nwp 1/1 Running 0 26s
scalardl-ledger-envoy-547bbf7546-pskpb 1/1 Running 0 26s
scalardl-ledger-ledger-6db5dc8774-5zsbj 1/1 Running 0 26s
scalardl-ledger-ledger-6db5dc8774-vnmrw 1/1 Running 0 26s
scalardl-ledger-ledger-6db5dc8774-wpjvs 1/1 Running 0 26s
schema-loader-auditor-schema-loading-dvc5r 0/1 Completed 0 11m
schema-loader-ledger-schema-loading-mtllb 0/1 Completed 0 11m
```
If the ScalarDL Ledger and ScalarDL Auditor pods are deployed properly, the `STATUS` column for those pods will be displayed as `Running`.
1. Check if the ScalarDL Ledger and ScalarDL Auditor services are deployed.
```console
kubectl get svc -n default
```
[Command execution result]
```console
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 47d
postgresql-auditor ClusterIP 10.107.9.78 5432/TCP 15m
postgresql-auditor-hl ClusterIP None 5432/TCP 15m
postgresql-ledger ClusterIP 10.108.241.181 5432/TCP 15m
postgresql-ledger-hl ClusterIP None 5432/TCP 15m
scalardl-auditor-envoy ClusterIP 10.100.61.202 40051/TCP,40052/TCP 55s
scalardl-auditor-envoy-metrics ClusterIP 10.99.6.227 9001/TCP 55s
scalardl-auditor-headless ClusterIP None 40051/TCP,40053/TCP,40052/TCP 55s
scalardl-auditor-metrics ClusterIP 10.108.1.147 8080/TCP 55s
scalardl-ledger-envoy ClusterIP 10.101.191.116 50051/TCP,50052/TCP 61s
scalardl-ledger-envoy-metrics ClusterIP 10.106.52.103 9001/TCP 61s
scalardl-ledger-headless ClusterIP None 50051/TCP,50053/TCP,50052/TCP 61s
scalardl-ledger-metrics ClusterIP 10.99.122.106 8080/TCP 61s
```
If the ScalarDL Ledger and ScalarDL Auditor services are deployed properly, you can see private IP addresses in the `CLUSTER-IP` column.
:::note
The `CLUSTER-IP` values for `scalardl-ledger-headless`, `scalardl-auditor-headless`, `postgresql-ledger-hl`, and `postgresql-auditor-hl` are `None` since they have no IP addresses.
:::
## Step 7. Start a client container
You'll use the CA certificate file in a client container. Therefore, you'll need to create a secret resource and mount it to the client container.
1. Create a secret resource named `client-ca-cert`.
```console
kubectl create secret generic client-ca-cert --from-file=ca.crt=${HOME}/scalardl-test/certs/ca.pem -n default
```
1. Create a manifest file for a client pod (`scalardl-client-pod.yaml`).
```console
cat << 'EOF' > ${HOME}/scalardl-test/scalardl-client-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: "scalardl-client"
spec:
containers:
- name: scalardl-client
image: eclipse-temurin:8-jdk
command: ['sleep']
args: ['inf']
env:
- name: SCALAR_DL_VERSION
value: SCALAR_DL_CLIENT_POD_SCALAR_DL_VERSION
volumeMounts:
- name: "client-ca-cert"
mountPath: "/certs/"
readOnly: true
volumes:
- name: "client-ca-cert"
secret:
secretName: "client-ca-cert"
restartPolicy: Never
EOF
```
1. Set the ScalarDL version in the manifest file.
```console
sed -i s/SCALAR_DL_CLIENT_POD_SCALAR_DL_VERSION/${SCALAR_DL_VERSION}/ ${HOME}/scalardl-test/scalardl-client-pod.yaml
```
1. Deploy the client pod.
```console
kubectl apply -f ${HOME}/scalardl-test/scalardl-client-pod.yaml -n default
```
1. Check if the client container is running.
```console
kubectl get pod scalardl-client -n default
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
scalardl-client 1/1 Running 0 4s
```
## Step 8. Run ScalarDL sample contracts in the client container
The following explains the minimum steps needed to run sample contracts. For more details about ScalarDL Ledger and ScalarDL Auditor, see the following:
* [Getting Started with ScalarDL](https://scalardl.scalar-labs.com/docs/latest/getting-started/)
* [Getting Started with ScalarDL Auditor](https://scalardl.scalar-labs.com/docs/latest/getting-started-auditor/)
1. Run bash in the client container.
```console
kubectl exec -it scalardl-client -n default -- bash
```
The commands in the following steps must be run in the client container.
1. Install the git, curl, and unzip commands in the client container.
```console
apt update && apt install -y git curl unzip
```
1. Clone the ScalarDL Java Client SDK git repository.
```console
git clone https://github.com/scalar-labs/scalardl-java-client-sdk.git
```
1. Change the working directory to `scalardl-java-client-sdk/`.
```console
cd scalardl-java-client-sdk/
```
```console
pwd
```
[Command execution result]
```console
/scalardl-java-client-sdk
```
1. Change the branch to the version you're using.
```console
git checkout -b v${SCALAR_DL_VERSION} refs/tags/v${SCALAR_DL_VERSION}
```
1. Build the sample contracts.
```console
./gradlew assemble
```
1. Download the CLI tools for ScalarDL from [ScalarDL Java Client SDK Releases](https://github.com/scalar-labs/scalardl-java-client-sdk/releases).
```console
curl -OL https://github.com/scalar-labs/scalardl-java-client-sdk/releases/download/v${SCALAR_DL_VERSION}/scalardl-java-client-sdk-${SCALAR_DL_VERSION}.zip
```
You need to use the same version of CLI tools and ScalarDL Ledger.
1. Unzip the `scalardl-java-client-sdk-${SCALAR_DL_VERSION}.zip` file.
```console
unzip ./scalardl-java-client-sdk-${SCALAR_DL_VERSION}.zip
```
1. Create a configuration file named `client.properties` to access ScalarDL Ledger and ScalarDL Auditor on the Kubernetes cluster.
```console
cat << 'EOF' > client.properties
# Ledger configuration
scalar.dl.client.server.host=scalardl-ledger-envoy.default.svc.cluster.local
scalar.dl.client.tls.enabled=true
scalar.dl.client.tls.ca_root_cert_path=/certs/ca.crt
scalar.dl.client.tls.override_authority=envoy.scalar.example.com
# Auditor configuration
scalar.dl.client.auditor.enabled=true
scalar.dl.client.auditor.host=scalardl-auditor-envoy.default.svc.cluster.local
scalar.dl.client.auditor.tls.enabled=true
scalar.dl.client.auditor.tls.ca_root_cert_path=/certs/ca.crt
scalar.dl.client.auditor.tls.override_authority=envoy.scalar.example.com
# Client configuration
scalar.dl.client.authentication_method=hmac
scalar.dl.client.entity.id=client
scalar.dl.client.entity.identity.hmac.secret_key=scalardl-hmac-client-secert-key
EOF
```
1. Register the client secret.
```console
./scalardl-java-client-sdk-${SCALAR_DL_VERSION}/bin/scalardl register-secret --config ./client.properties
```
1. Register the sample contract `StateUpdater`.
```console
./scalardl-java-client-sdk-${SCALAR_DL_VERSION}/bin/scalardl register-contract --config ./client.properties --contract-id StateUpdater --contract-binary-name com.org1.contract.StateUpdater --contract-class-file ./build/classes/java/main/com/org1/contract/StateUpdater.class
```
1. Register the sample contract `StateReader`.
```console
./scalardl-java-client-sdk-${SCALAR_DL_VERSION}/bin/scalardl register-contract --config ./client.properties --contract-id StateReader --contract-binary-name com.org1.contract.StateReader --contract-class-file ./build/classes/java/main/com/org1/contract/StateReader.class
```
1. Register the contract `ValidateLedger` to execute a validate request.
```console
./scalardl-java-client-sdk-${SCALAR_DL_VERSION}/bin/scalardl register-contract --config ./client.properties --contract-id validate-ledger --contract-binary-name com.scalar.dl.client.contract.ValidateLedger --contract-class-file ./build/classes/java/main/com/scalar/dl/client/contract/ValidateLedger.class
```
1. Execute the contract `StateUpdater`.
```console
./scalardl-java-client-sdk-${SCALAR_DL_VERSION}/bin/scalardl execute-contract --config ./client.properties --contract-id StateUpdater --contract-argument '{"asset_id": "test_asset", "state": 3}'
```
This sample contract updates the `state` (value) of the asset named `test_asset` to `3`.
1. Execute the contract `StateReader`.
```console
./scalardl-java-client-sdk-${SCALAR_DL_VERSION}/bin/scalardl execute-contract --config ./client.properties --contract-id StateReader --contract-argument '{"asset_id": "test_asset"}'
```
[Command execution result]
```console
Contract result:
{
"id" : "test_asset",
"age" : 0,
"output" : {
"state" : 3
}
}
```
### Reference
* If the asset data is not tampered with, running the `execute-contract` command to request contract execution will return `OK` as a result.
* If the asset data is tampered with (for example, if the `state` value in the database is tampered with), running the `execute-contract` command to request contract execution will return a value other than `OK` (for example, `INCONSISTENT_STATES`) as a result. See the following as an example for how ScalarDL detects data tampering.
[Command execution result (if the asset data is tampered with)]
```console
{
"status_code" : "INCONSISTENT_STATES",
"error_message" : "The results from Ledger and Auditor don't match"
}
```
1. Execute a validation request for the asset.
```console
./scalardl-java-client-sdk-${SCALAR_DL_VERSION}/bin/scalardl validate-ledger --config ./client.properties --asset-id "test_asset"
```
[Command execution result]
```console
{
"status_code" : "OK",
"Ledger" : {
"id" : "test_asset",
"age" : 0,
"nonce" : "3533427d-03cf-41d1-bf95-4d31eb0cb24d",
"hash" : "FiquvtPMKLlxKf4VGoccSAGsi9ptn4ozYVVTwdSzEQ0=",
"signature" : "MEYCIQDiiXqzw6K+Ml4uvn8rK43o5wHWESU3hoXnZPi6/OeKVwIhAM+tFBcapl6zg47Uq0Uc8nVNGWNHZLBDBGve3F0xkzTR"
},
"Auditor" : {
"id" : "test_asset",
"age" : 0,
"nonce" : "3533427d-03cf-41d1-bf95-4d31eb0cb24d",
"hash" : "FiquvtPMKLlxKf4VGoccSAGsi9ptn4ozYVVTwdSzEQ0=",
"signature" : "MEUCIQDLsfUR2PmxSvfpL3YvHJUkz00RDpjCdctkroZKXE8d5QIgH73FQH2e11jfnynD00Pp9DrIG1vYizxDsvxUsMPo9IU="
}
}
```
### Reference
* If the asset data is not tampered with, running the `validate-ledger` command to request validation will return `OK` as the result.
* If the asset data is tampered with (for example, if the `state` value in the database is tampered with), running the `validate-ledger` command to request validation will return a value other than `OK` (for example, `INVALID_OUTPUT`) as a result. See the following as an example for how ScalarDL detects data tampering.
[Command execution result (if the asset data is tampered with)]
```console
{
"status_code" : "INCONSISTENT_STATES",
"error_message" : "The results from Ledger and Auditor don't match"
}
```
1. Exit from the client container.
```console
exit
```
## Step 9. Delete all resources
After completing the ScalarDL Ledger and ScalarDL Auditor tests on the Kubernetes cluster, remove all resources.
1. Uninstall ScalarDL Ledger, ScalarDL Auditor, ScalarDL Schema Loader, and PostgreSQL.
```console
helm uninstall -n default scalardl-ledger schema-loader-ledger postgresql-ledger scalardl-auditor schema-loader-auditor postgresql-auditor
```
1. Remove the client container.
```
kubectl delete pod scalardl-client --grace-period 0 -n default
```
1. Remove the secret resources.
```
kubectl delete secrets envoy-tls-key envoy-tls-cert schema-ledger-credentials-secret schema-auditor-credentials-secret ledger-credentials-secret scalardl-ledger-tls-ca scalardl-ledger-tls-cert scalardl-ledger-tls-key auditor-credentials-secret auditor-keys scalardl-auditor-tls-ca scalardl-auditor-tls-cert scalardl-auditor-tls-key scalardl-auditor-tls-ca-for-ledger client-ca-cert
```
1. Remove the working directory and sample files (configuration file, private key, and certificate).
```console
cd ${HOME}
```
```console
rm -rf ${HOME}/scalardl-test/
```
## Further reading
You can see how to get started with monitoring or logging for Scalar products in the following tutorials:
* [Getting Started with Helm Charts (Monitoring using Prometheus Operator)](getting-started-monitoring.mdx)
* [Getting Started with Helm Charts (Logging using Loki Stack)](getting-started-logging.mdx)
* [Getting Started with Helm Charts (Scalar Manager)](getting-started-scalar-manager.mdx)
================================================
FILE: docs/helm-charts/getting-started-scalardl-auditor.mdx
================================================
---
tags:
- Enterprise
displayed_sidebar: docsEnglish
---
# Getting Started with Helm Charts (ScalarDL Ledger and Auditor / Auditor mode)
This document explains how to get started with ScalarDL Ledger and Auditor using Helm Chart on a Kubernetes cluster as a test environment. Here, we assume that you already have a Mac or Linux environment for testing. We use **Minikube** in this document, but the steps we will show should work in any Kubernetes cluster.
## Requirement
You need to subscribe to ScalarDL Ledger and ScalarDL Auditor in the [AWS Marketplace](https://aws.amazon.com/marketplace/pp/prodview-rzbuhxgvqf4d2) to get the following container images.
* AWS Marketplace
* scalar-ledger
* scalar-ledger-envoy
* scalardl-schema-loader-ledger
* scalar-auditor
* scalar-auditor-envoy
* scalardl-schema-loader-auditor
For more details, refer to [How to install Scalar products through AWS Marketplace](../scalar-kubernetes/AwsMarketplaceGuide.mdx).
## Note
To make Byzantine fault detection with auditing work properly, Ledger and Auditor should be deployed and managed in different administrative domains. However, in this guide, we will deploy Ledger and Auditor in the same Kubernetes cluster to make the test easier.
## What we create
We will deploy the following components on a Kubernetes cluster as follows.
```
+-----------------------------------------------------------------------------------------------------------------------------+
| [Kubernetes Cluster] |
| [Pod] [Pod] [Pod] |
| |
| +-------+ +---------+ |
| +---> | Envoy | ---+ +---> | Ledger | ---+ |
| | +-------+ | | +---------+ | |
| | | | | |
| +---------+ | +-------+ | +-----------+ | +---------+ | +---------------+ |
| +---> | Service | ---+---> | Envoy | ---+---> | Service | ---+---> | Ledger | ---+---> | PostgreSQL | |
| | | (Envoy) | | +-------+ | | (Ledger) | | +---------+ | | (For Ledger) | |
| | +---------+ | | +-----------+ | | +---------------+ |
| | | +-------+ | | +---------+ | |
| | +---> | Envoy | ---+ +---> | Ledger | ---+ |
| +--------+ | +-------+ +---------+ |
| | Client | ---+ |
| +--------+ | +-------+ +---------+ |
| | +---> | Envoy | ---+ +---> | Auditor | ---+ |
| | | +-------+ | | +---------+ | |
| | | | | | |
| | +---------+ | +-------+ | +-----------+ | +---------+ | +---------------+ |
| +---> | Service | ---+---> | Envoy | ---+---> | Service | ---+---> | Auditor | ---+---> | PostgreSQL | |
| | (Envoy) | | +-------+ | | (Auditor) | | +---------+ | | (For Auditor) | |
| +---------+ | | +-----------+ | | +---------------+ |
| | +-------+ | | +---------+ | |
| +---> | Envoy | ---+ +---> | Auditor | ---+ |
| +-------+ +---------+ |
| |
+-----------------------------------------------------------------------------------------------------------------------------+
```
## Step 1. Start a Kubernetes cluster
First, you need to prepare a Kubernetes cluster. If you use a **minikube** environment, please refer to the [Getting Started with Scalar Helm Charts](getting-started-scalar-helm-charts.mdx). If you have already started a Kubernetes cluster, you can skip this step.
## Step 2. Start PostgreSQL containers
ScalarDL Ledger and Auditor use some kind of database system as a backend database. In this document, we use PostgreSQL.
You can deploy PostgreSQL on the Kubernetes cluster as follows.
1. Add the Bitnami helm repository.
```console
helm repo add bitnami https://charts.bitnami.com/bitnami
```
1. Deploy PostgreSQL for Ledger.
```console
helm install postgresql-ledger bitnami/postgresql \
--set auth.postgresPassword=postgres \
--set primary.persistence.enabled=false
```
1. Deploy PostgreSQL for Auditor.
```console
helm install postgresql-auditor bitnami/postgresql \
--set auth.postgresPassword=postgres \
--set primary.persistence.enabled=false
```
1. Check if the PostgreSQL containers are running.
```console
kubectl get pod
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-auditor-0 1/1 Running 0 11s
postgresql-ledger-0 1/1 Running 0 16s
```
## Step 3. Create a working directory
We will create some configuration files and key/certificate files locally. So, create a working directory for them.
1. Create a working directory.
```console
mkdir -p ~/scalardl-test/certs/
```
## Step 4. Create key/certificate files
Note: In this guide, we will use self-sign certificates for the test. However, it is strongly recommended that these certificates NOT be used in production.
1. Change the working directory to `~/scalardl-test/certs/` directory.
```console
cd ~/scalardl-test/certs/
```
1. Create a JSON file that includes Ledger information.
```console
cat << 'EOF' > ~/scalardl-test/certs/ledger.json
{
"CN": "ledger",
"hosts": ["example.com","*.example.com"],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"O": "ledger",
"OU": "test team",
"L": "Shinjuku",
"ST": "Tokyo",
"C": "JP"
}
]
}
EOF
```
1. Create a JSON file that includes Auditor information.
```console
cat << 'EOF' > ~/scalardl-test/certs/auditor.json
{
"CN": "auditor",
"hosts": ["example.com","*.example.com"],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"O": "auditor",
"OU": "test team",
"L": "Shinjuku",
"ST": "Tokyo",
"C": "JP"
}
]
}
EOF
```
1. Create a JSON file that includes Client information.
```console
cat << 'EOF' > ~/scalardl-test/certs/client.json
{
"CN": "client",
"hosts": ["example.com","*.example.com"],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"O": "client",
"OU": "test team",
"L": "Shinjuku",
"ST": "Tokyo",
"C": "JP"
}
]
}
EOF
```
1. Create key/certificate files for the Ledger.
```console
cfssl selfsign "" ./ledger.json | cfssljson -bare ledger
```
1. Create key/certificate files for the Auditor.
```console
cfssl selfsign "" ./auditor.json | cfssljson -bare auditor
```
1. Create key/certificate files for the Client.
```console
cfssl selfsign "" ./client.json | cfssljson -bare client
```
1. Confirm key/certificate files are created.
```console
ls -1
```
[Command execution result]
```console
auditor-key.pem
auditor.csr
auditor.json
auditor.pem
client-key.pem
client.csr
client.json
client.pem
ledger-key.pem
ledger.csr
ledger.json
ledger.pem
```
## Step 5. Create DB schemas for ScalarDL Ledger and ScalarDL Auditor using Helm Charts
We will deploy two ScalarDL Schema Loader pods on the Kubernetes cluster using Helm Charts.
The ScalarDL Schema Loader will create the DB schemas for ScalarDL Ledger and Auditor in PostgreSQL.
1. Change the working directory to `~/scalardl-test/`.
```console
cd ~/scalardl-test/
```
1. Add the Scalar helm repository.
```console
helm repo add scalar-labs https://scalar-labs.github.io/helm-charts
```
1. Create a secret resource to pull the ScalarDL container images from AWS.
* AWS Marketplace
```console
kubectl create secret docker-registry reg-ecr-mp-secrets \
--docker-server=709825985650.dkr.ecr.us-east-1.amazonaws.com \
--docker-username=AWS \
--docker-password=$(aws ecr get-login-password --region us-east-1)
```
For more details, refer to [How to install Scalar products through AWS Marketplace](../scalar-kubernetes/AwsMarketplaceGuide.mdx).
1. Create a custom values file for ScalarDL Schema Loader for Ledger (schema-loader-ledger-custom-values.yaml).
* AWS Marketplace
```console
cat << 'EOF' > ~/scalardl-test/schema-loader-ledger-custom-values.yaml
schemaLoading:
schemaType: "ledger"
image:
repository: "709825985650.dkr.ecr.us-east-1.amazonaws.com/scalar/scalardl-schema-loader-ledger"
version: "3.6.0"
imagePullSecrets:
- name: "reg-ecr-mp-secrets"
databaseProperties: |
scalar.db.contact_points=jdbc:postgresql://postgresql-ledger.default.svc.cluster.local:5432/postgres
scalar.db.username={{ default .Env.SCALAR_DL_LEDGER_POSTGRES_USERNAME "" }}
scalar.db.password={{ default .Env.SCALAR_DL_LEDGER_POSTGRES_PASSWORD "" }}
scalar.db.storage=jdbc
secretName: "ledger-credentials-secret"
EOF
```
1. Create a custom values file for ScalarDL Schema Loader for Auditor (schema-loader-auditor-custom-values.yaml).
* AWS Marketplace
```console
cat << 'EOF' > ~/scalardl-test/schema-loader-auditor-custom-values.yaml
schemaLoading:
schemaType: "auditor"
image:
repository: "709825985650.dkr.ecr.us-east-1.amazonaws.com/scalar/scalardl-schema-loader-auditor"
version: "3.6.0"
imagePullSecrets:
- name: "reg-ecr-mp-secrets"
databaseProperties: |
scalar.db.contact_points=jdbc:postgresql://postgresql-auditor.default.svc.cluster.local:5432/postgres
scalar.db.username={{ default .Env.SCALAR_DL_AUDITOR_POSTGRES_USERNAME "" }}
scalar.db.password={{ default .Env.SCALAR_DL_AUDITOR_POSTGRES_PASSWORD "" }}
scalar.db.storage=jdbc
secretName: "auditor-credentials-secret"
EOF
```
1. Create a secret resource that includes a username and password for PostgreSQL for Ledger.
```console
kubectl create secret generic ledger-credentials-secret \
--from-literal=SCALAR_DL_LEDGER_POSTGRES_USERNAME=postgres \
--from-literal=SCALAR_DL_LEDGER_POSTGRES_PASSWORD=postgres
```
1. Create a secret resource that includes a username and password for PostgreSQL for Auditor.
```console
kubectl create secret generic auditor-credentials-secret \
--from-literal=SCALAR_DL_AUDITOR_POSTGRES_USERNAME=postgres \
--from-literal=SCALAR_DL_AUDITOR_POSTGRES_PASSWORD=postgres
```
1. Deploy the ScalarDL Schema Loader for Ledger.
```console
helm install schema-loader-ledger scalar-labs/schema-loading -f ./schema-loader-ledger-custom-values.yaml
```
1. Deploy the ScalarDL Schema Loader for Auditor.
```console
helm install schema-loader-auditor scalar-labs/schema-loading -f ./schema-loader-auditor-custom-values.yaml
```
1. Check if the ScalarDL Schema Loader pods are deployed and completed.
```console
kubectl get pod
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-auditor-0 1/1 Running 0 2m56s
postgresql-ledger-0 1/1 Running 0 3m1s
schema-loader-auditor-schema-loading-dvc5r 0/1 Completed 0 6s
schema-loader-ledger-schema-loading-mtllb 0/1 Completed 0 10s
```
If the ScalarDL Schema Loader pods are **ContainerCreating** or **Running**, wait for the process will be completed (The STATUS will be **Completed**).
## Step 6. Deploy ScalarDL Ledger and Auditor on the Kubernetes cluster using Helm Charts
1. Create a custom values file for ScalarDL Ledger (scalardl-ledger-custom-values.yaml).
* AWS Marketplace
```console
cat << 'EOF' > ~/scalardl-test/scalardl-ledger-custom-values.yaml
envoy:
image:
repository: "709825985650.dkr.ecr.us-east-1.amazonaws.com/scalar/scalar-ledger-envoy"
version: "1.3.0"
imagePullSecrets:
- name: "reg-ecr-mp-secrets"
ledger:
image:
repository: "709825985650.dkr.ecr.us-east-1.amazonaws.com/scalar/scalar-ledger"
version: "3.6.0"
imagePullSecrets:
- name: "reg-ecr-mp-secrets"
ledgerProperties: |
scalar.db.contact_points=jdbc:postgresql://postgresql-ledger.default.svc.cluster.local:5432/postgres
scalar.db.username={{ default .Env.SCALAR_DL_LEDGER_POSTGRES_USERNAME "" }}
scalar.db.password={{ default .Env.SCALAR_DL_LEDGER_POSTGRES_PASSWORD "" }}
scalar.db.storage=jdbc
scalar.dl.ledger.proof.enabled=true
scalar.dl.ledger.auditor.enabled=true
scalar.dl.ledger.proof.private_key_path=/keys/private-key
secretName: "ledger-credentials-secret"
extraVolumes:
- name: "ledger-keys"
secret:
secretName: "ledger-keys"
extraVolumeMounts:
- name: "ledger-keys"
mountPath: "/keys"
readOnly: true
EOF
```
1. Create a custom values file for ScalarDL Auditor (scalardl-auditor-custom-values.yaml).
* AWS Marketplace
```console
cat << 'EOF' > ~/scalardl-test/scalardl-auditor-custom-values.yaml
envoy:
image:
repository: "709825985650.dkr.ecr.us-east-1.amazonaws.com/scalar/scalar-auditor-envoy"
version: "1.3.0"
imagePullSecrets:
- name: "reg-ecr-mp-secrets"
auditor:
image:
repository: "709825985650.dkr.ecr.us-east-1.amazonaws.com/scalar/scalar-auditor"
version: "3.6.0"
imagePullSecrets:
- name: "reg-ecr-mp-secrets"
auditorProperties: |
scalar.db.contact_points=jdbc:postgresql://postgresql-auditor.default.svc.cluster.local:5432/postgres
scalar.db.username={{ default .Env.SCALAR_DL_AUDITOR_POSTGRES_USERNAME "" }}
scalar.db.password={{ default .Env.SCALAR_DL_AUDITOR_POSTGRES_PASSWORD "" }}
scalar.db.storage=jdbc
scalar.dl.auditor.ledger.host=scalardl-ledger-envoy.default.svc.cluster.local
scalar.dl.auditor.private_key_path=/keys/private-key
secretName: "auditor-credentials-secret"
extraVolumes:
- name: "auditor-keys"
secret:
secretName: "auditor-keys"
extraVolumeMounts:
- name: "auditor-keys"
mountPath: "/keys"
readOnly: true
EOF
```
1. Create secret resource `ledger-keys`.
```console
kubectl create secret generic ledger-keys --from-file=certificate=./certs/ledger.pem --from-file=private-key=./certs/ledger-key.pem
```
1. Create secret resource `auditor-keys`.
```console
kubectl create secret generic auditor-keys --from-file=certificate=./certs/auditor.pem --from-file=private-key=./certs/auditor-key.pem
```
1. Deploy the ScalarDL Ledger.
```console
helm install scalardl-ledger scalar-labs/scalardl -f ./scalardl-ledger-custom-values.yaml
```
1. Deploy the ScalarDL Auditor.
```console
helm install scalardl-auditor scalar-labs/scalardl-audit -f ./scalardl-auditor-custom-values.yaml
```
1. Check if the ScalarDL Ledger and Auditor pods are deployed.
```console
kubectl get pod
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-auditor-0 1/1 Running 0 14m
postgresql-ledger-0 1/1 Running 0 14m
scalardl-auditor-auditor-5b885ff4c8-fwkpf 1/1 Running 0 18s
scalardl-auditor-auditor-5b885ff4c8-g69cb 1/1 Running 0 18s
scalardl-auditor-auditor-5b885ff4c8-nsmnq 1/1 Running 0 18s
scalardl-auditor-envoy-689bcbdf65-5mn6v 1/1 Running 0 18s
scalardl-auditor-envoy-689bcbdf65-fpq8j 1/1 Running 0 18s
scalardl-auditor-envoy-689bcbdf65-lsz2t 1/1 Running 0 18s
scalardl-ledger-envoy-547bbf7546-n7p5x 1/1 Running 0 26s
scalardl-ledger-envoy-547bbf7546-p8nwp 1/1 Running 0 26s
scalardl-ledger-envoy-547bbf7546-pskpb 1/1 Running 0 26s
scalardl-ledger-ledger-6db5dc8774-5zsbj 1/1 Running 0 26s
scalardl-ledger-ledger-6db5dc8774-vnmrw 1/1 Running 0 26s
scalardl-ledger-ledger-6db5dc8774-wpjvs 1/1 Running 0 26s
schema-loader-auditor-schema-loading-dvc5r 0/1 Completed 0 11m
schema-loader-ledger-schema-loading-mtllb 0/1 Completed 0 11m
```
If the ScalarDL Ledger and Auditor pods are deployed properly, you can see the STATUS are **Running**.
1. Check if the ScalarDL Ledger and Auditor services are deployed.
```console
kubectl get svc
```
[Command execution result]
```console
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 47d
postgresql-auditor ClusterIP 10.107.9.78 5432/TCP 15m
postgresql-auditor-hl ClusterIP None 5432/TCP 15m
postgresql-ledger ClusterIP 10.108.241.181 5432/TCP 15m
postgresql-ledger-hl ClusterIP None 5432/TCP 15m
scalardl-auditor-envoy ClusterIP 10.100.61.202 40051/TCP,40052/TCP 55s
scalardl-auditor-envoy-metrics ClusterIP 10.99.6.227 9001/TCP 55s
scalardl-auditor-headless ClusterIP None 40051/TCP,40053/TCP,40052/TCP 55s
scalardl-auditor-metrics ClusterIP 10.108.1.147 8080/TCP 55s
scalardl-ledger-envoy ClusterIP 10.101.191.116 50051/TCP,50052/TCP 61s
scalardl-ledger-envoy-metrics ClusterIP 10.106.52.103 9001/TCP 61s
scalardl-ledger-headless ClusterIP None 50051/TCP,50053/TCP,50052/TCP 61s
scalardl-ledger-metrics ClusterIP 10.99.122.106 8080/TCP 61s
```
If the ScalarDL Ledger and Auditor services are deployed properly, you can see private IP addresses in the CLUSTER-IP column. (Note: `scalardl-ledger-headless` and `scalardl-auditor-headless` have no CLUSTER-IP.)
## Step 7. Start a Client container
We will use certificate files in a Client container. So, we create a secret resource and mount it to a Client container.
1. Create secret resource `client-keys`.
```
kubectl create secret generic client-keys --from-file=certificate=./certs/client.pem --from-file=private-key=./certs/client-key.pem
```
1. Start a Client container on the Kubernetes cluster.
```console
cat << 'EOF' | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: "scalardl-client"
spec:
containers:
- name: scalardl-client
image: eclipse-temurin:8-jdk
command: ['sleep']
args: ['inf']
volumeMounts:
- name: "ledger-keys"
mountPath: "/keys/ledger"
readOnly: true
- name: "auditor-keys"
mountPath: "/keys/auditor"
readOnly: true
- name: "client-keys"
mountPath: "/keys/client"
readOnly: true
volumes:
- name: "ledger-keys"
secret:
secretName: "ledger-keys"
- name: "auditor-keys"
secret:
secretName: "auditor-keys"
- name: "client-keys"
secret:
secretName: "client-keys"
restartPolicy: Never
EOF
```
1. Check if the Client container is running.
```console
kubectl get pod scalardl-client
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
scalardl-client 1/1 Running 0 4s
```
## Step 8. Run ScalarDL sample contracts in the Client container
The following explains the minimum steps. If you want to know more details about ScalarDL Ledger and Auditor, please refer to the following documents.
* [Getting Started with ScalarDL](https://scalardl.scalar-labs.com/docs/latest/getting-started)
* [Getting Started with ScalarDL Auditor](https://scalardl.scalar-labs.com/docs/latest/getting-started-auditor)
When you use Auditor, you need to register the certificate for the Ledger and Auditor before starting the client application. Ledger needs to register its certificate to Auditor, and Auditor needs to register its certificate to Ledger.
1. Run bash in the Client container.
```console
kubectl exec -it scalardl-client -- bash
```
After this step, run each command in the Client container.
1. Install the git, curl and unzip commands in the Client container.
```console
apt update && apt install -y git curl unzip
```
1. Clone ScalarDL Java Client SDK git repository.
```console
git clone https://github.com/scalar-labs/scalardl-java-client-sdk.git
```
1. Change the directory to `scalardl-java-client-sdk/`.
```console
cd scalardl-java-client-sdk/
```
```console
pwd
```
[Command execution result]
```console
/scalardl-java-client-sdk
```
1. Change branch to arbitrary version.
```console
git checkout -b v3.6.0 refs/tags/v3.6.0
```
```console
git branch
```
[Command execution result]
```console
master
* v3.6.0
```
If you want to use another version, please specify the version (tag) you want to use. You need to use the same version of ScalarDL Ledger and ScalarDL Java Client SDK.
1. Build the sample contracts.
```console
./gradlew assemble
```
1. Download CLI tools of ScalarDL from [ScalarDL Java Client SDK Releases](https://github.com/scalar-labs/scalardl-java-client-sdk/releases).
```console
curl -OL https://github.com/scalar-labs/scalardl-java-client-sdk/releases/download/v3.6.0/scalardl-java-client-sdk-3.6.0.zip
```
You need to use the same version of CLI tools and ScalarDL Ledger.
1. Unzip the `scalardl-java-client-sdk-3.6.0.zip` file.
```console
unzip ./scalardl-java-client-sdk-3.6.0.zip
```
1. Create a configuration file (ledger.as.client.properties) to register the certificate of Ledger to Auditor.
```console
cat << 'EOF' > ledger.as.client.properties
# Ledger
scalar.dl.client.server.host=scalardl-ledger-envoy.default.svc.cluster.local
# Auditor
scalar.dl.client.auditor.enabled=true
scalar.dl.client.auditor.host=scalardl-auditor-envoy.default.svc.cluster.local
# Certificate
scalar.dl.client.cert_holder_id=ledger
scalar.dl.client.cert_path=/keys/ledger/certificate
scalar.dl.client.private_key_path=/keys/ledger/private-key
EOF
```
1. Create a configuration file (auditor.as.client.properties) to register the certificate of Auditor to Ledger.
```console
cat << 'EOF' > auditor.as.client.properties
# Ledger
scalar.dl.client.server.host=scalardl-ledger-envoy.default.svc.cluster.local
# Auditor
scalar.dl.client.auditor.enabled=true
scalar.dl.client.auditor.host=scalardl-auditor-envoy.default.svc.cluster.local
# Certificate
scalar.dl.client.cert_holder_id=auditor
scalar.dl.client.cert_path=/keys/auditor/certificate
scalar.dl.client.private_key_path=/keys/auditor/private-key
EOF
```
1. Create a configuration file (client.properties) to access ScalarDL Ledger on the Kubernetes cluster.
```console
cat << 'EOF' > client.properties
# Ledger
scalar.dl.client.server.host=scalardl-ledger-envoy.default.svc.cluster.local
# Auditor
scalar.dl.client.auditor.enabled=true
scalar.dl.client.auditor.host=scalardl-auditor-envoy.default.svc.cluster.local
# Certificate
scalar.dl.client.cert_holder_id=client
scalar.dl.client.cert_path=/keys/client/certificate
scalar.dl.client.private_key_path=/keys/client/private-key
EOF
```
1. Register the certificate file of Ledger.
```console
./scalardl-java-client-sdk-3.6.0/bin/register-cert --properties ./ledger.as.client.properties
```
1. Register the certificate file of Auditor.
```console
./scalardl-java-client-sdk-3.6.0/bin/register-cert --properties ./auditor.as.client.properties
```
1. Register the certificate file of client.
```console
./scalardl-java-client-sdk-3.6.0/bin/register-cert --properties ./client.properties
```
1. Register the sample contract `StateUpdater`.
```console
./scalardl-java-client-sdk-3.6.0/bin/register-contract --properties ./client.properties --contract-id StateUpdater --contract-binary-name com.org1.contract.StateUpdater --contract-class-file ./build/classes/java/main/com/org1/contract/StateUpdater.class
```
1. Register the sample contract `StateReader`.
```console
./scalardl-java-client-sdk-3.6.0/bin/register-contract --properties ./client.properties --contract-id StateReader --contract-binary-name com.org1.contract.StateReader --contract-class-file ./build/classes/java/main/com/org1/contract/StateReader.class
```
1. Register the contract `ValdateLedger` to execute a validate request.
```console
./scalardl-java-client-sdk-3.6.0/bin/register-contract --properties ./client.properties --contract-id validate-ledger --contract-binary-name com.scalar.dl.client.contract.ValidateLedger --contract-class-file ./build/classes/java/main/com/scalar/dl/client/contract/ValidateLedger.class
```
1. Execute the contract `StateUpdater`.
```console
./scalardl-java-client-sdk-3.6.0/bin/execute-contract --properties ./client.properties --contract-id StateUpdater --contract-argument '{"asset_id": "test_asset", "state": 3}'
```
This sample contract updates the `state` (value) of the asset named `test_asset` to `3`.
1. Execute the contract `StateReader`.
```console
./scalardl-java-client-sdk-3.6.0/bin/execute-contract --properties ./client.properties --contract-id StateReader --contract-argument '{"asset_id": "test_asset"}'
```
[Command execution result]
```console
Contract result:
{
"id" : "test_asset",
"age" : 0,
"output" : {
"state" : 3
}
}
```
* Reference information
* If the asset data is not tampered with, the contract execution request (execute-contract command) returns `OK` as a result.
* If the asset data is tampered with (e.g. the `state` value in the DB is tampered with), the contract execution request (execute-contract command) returns a value other than `OK` (e.g. `INCONSISTENT_STATES`) as a result, like the following.
[Command execution result (If the asset data is tampered with)]
```console
{
"status_code" : "INCONSISTENT_STATES",
"error_message" : "The results from Ledger and Auditor don't match"
}
```
* In this way, the ScalarDL can detect data tampering.
1. Execute a validation request for the asset.
```console
./scalardl-java-client-sdk-3.6.0/bin/validate-ledger --properties ./client.properties --asset-id "test_asset"
```
[Command execution result]
```console
{
"status_code" : "OK",
"Ledger" : {
"id" : "test_asset",
"age" : 0,
"nonce" : "3533427d-03cf-41d1-bf95-4d31eb0cb24d",
"hash" : "FiquvtPMKLlxKf4VGoccSAGsi9ptn4ozYVVTwdSzEQ0=",
"signature" : "MEYCIQDiiXqzw6K+Ml4uvn8rK43o5wHWESU3hoXnZPi6/OeKVwIhAM+tFBcapl6zg47Uq0Uc8nVNGWNHZLBDBGve3F0xkzTR"
},
"Auditor" : {
"id" : "test_asset",
"age" : 0,
"nonce" : "3533427d-03cf-41d1-bf95-4d31eb0cb24d",
"hash" : "FiquvtPMKLlxKf4VGoccSAGsi9ptn4ozYVVTwdSzEQ0=",
"signature" : "MEUCIQDLsfUR2PmxSvfpL3YvHJUkz00RDpjCdctkroZKXE8d5QIgH73FQH2e11jfnynD00Pp9DrIG1vYizxDsvxUsMPo9IU="
}
}
```
* Reference information
* If the asset data is not tampered with, the validation request (validate-ledger command) returns `OK` as a result.
* If the asset data is tampered with (e.g. the `state` value in the DB is tampered with), the validation request (validate-ledger command) returns a value other than `OK` (e.g. `INVALID_OUTPUT`) as a result, like the following.
[Command execution result (If the asset data is tampered with)]
```console
{
"status_code" : "INCONSISTENT_STATES",
"error_message" : "The results from Ledger and Auditor don't match"
}
```
* In this way, the ScalarDL Ledger can detect data tampering.
## Step 9. Delete all resources
After completing the ScalarDL Ledger tests on the Kubernetes cluster, remove all resources.
1. Uninstall ScalarDL Ledger, ScalarDL Schema Loader, and PostgreSQL.
```console
helm uninstall scalardl-ledger schema-loader-ledger postgresql-ledger scalardl-auditor schema-loader-auditor postgresql-auditor
```
1. Remove the Client container.
```
kubectl delete pod scalardl-client --force --grace-period 0
```
1. Remove the working directory and sample files (configuration file, key, and certificate).
```console
cd ~
```
```console
rm -rf ~/scalardl-test/
```
## Further reading
You can see how to get started with monitoring or logging for Scalar products in the following documents.
* [Getting Started with Helm Charts (Monitoring using Prometheus Operator)](getting-started-monitoring.mdx)
* [Getting Started with Helm Charts (Logging using Loki Stack)](getting-started-logging.mdx)
* [Getting Started with Helm Charts (Scalar Manager)](getting-started-scalar-manager.mdx)
================================================
FILE: docs/helm-charts/getting-started-scalardl-ledger.mdx
================================================
---
tags:
- Enterprise
displayed_sidebar: docsEnglish
---
# Getting Started with Helm Charts (ScalarDL Ledger / Ledger only)
This document explains how to get started with ScalarDL Ledger using Helm Chart on a Kubernetes cluster as a test environment. Here, we assume that you already have a Mac or Linux environment for testing. We use **Minikube** in this document, but the steps we will show should work in any Kubernetes cluster.
## Requirement
You need to subscribe to ScalarDL Ledger in the [AWS Marketplace](https://aws.amazon.com/marketplace/pp/prodview-rzbuhxgvqf4d2) to get the following container images.
* AWS Marketplace
* scalar-ledger
* scalar-ledger-envoy
* scalardl-schema-loader-ledger
For more details, refer to [How to install Scalar products through AWS Marketplace](../scalar-kubernetes/AwsMarketplaceGuide.mdx).
## What we create
We will deploy the following components on a Kubernetes cluster as follows.
```
+--------------------------------------------------------------------------------------------------------------------------------------+
| [Kubernetes Cluster] |
| |
| [Pod] [Pod] [Pod] [Pod] |
| |
| +-------+ +-----------------+ |
| +---> | Envoy | ---+ +---> | ScalarDL Ledger | ---+ |
| | +-------+ | | +-----------------+ | |
| | | | | |
| +--------+ +---------+ | +-------+ | +-------------------+ | +-----------------+ | +------------+ |
| | Client | ---> | Service | ---+---> | Envoy | ---+---> | Service | ---+---> | ScalarDL Ledger | ---+---> | PostgreSQL | |
| +--------+ | (Envoy) | | +-------+ | | (ScalarDL Ledger) | | +-----------------+ | +------------+ |
| +---------+ | | +-------------------+ | | |
| | +-------+ | | +-----------------+ | |
| +---> | Envoy | ---+ +---> | ScalarDL Ledger | ---+ |
| +-------+ +-----------------+ |
| |
+--------------------------------------------------------------------------------------------------------------------------------------+
```
## Step 1. Start a Kubernetes cluster
First, you need to prepare a Kubernetes cluster. If you use a **minikube** environment, please refer to the [Getting Started with Scalar Helm Charts](getting-started-scalar-helm-charts.mdx). If you have already started a Kubernetes cluster, you can skip this step.
## Step 2. Start a PostgreSQL container
ScalarDL Ledger uses some kind of database system as a backend database. In this document, we use PostgreSQL.
You can deploy PostgreSQL on the Kubernetes cluster as follows.
1. Add the Bitnami helm repository.
```console
helm repo add bitnami https://charts.bitnami.com/bitnami
```
1. Deploy PostgreSQL.
```console
helm install postgresql-ledger bitnami/postgresql \
--set auth.postgresPassword=postgres \
--set primary.persistence.enabled=false
```
1. Check if the PostgreSQL container is running.
```console
kubectl get pod
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-ledger-0 1/1 Running 0 11s
```
## Step 3. Create a working directory
We will create some configuration files and key/certificate files locally. So, create a working directory for them.
1. Create a working directory.
```console
mkdir -p ~/scalardl-test/certs/
```
## Step 4. Create key/certificate files
Note: In this guide, we will use self-sign certificates for the test. However, it is strongly recommended that these certificates NOT be used in production.
1. Change the working directory to `~/scalardl-test/certs/` directory.
```console
cd ~/scalardl-test/certs/
```
1. Create a JSON file that includes Ledger information.
```console
cat << 'EOF' > ~/scalardl-test/certs/ledger.json
{
"CN": "ledger",
"hosts": ["example.com","*.example.com"],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"O": "ledger",
"OU": "test team",
"L": "Shinjuku",
"ST": "Tokyo",
"C": "JP"
}
]
}
EOF
```
1. Create a JSON file that includes Client information.
```console
cat << 'EOF' > ~/scalardl-test/certs/client.json
{
"CN": "client",
"hosts": ["example.com","*.example.com"],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"O": "client",
"OU": "test team",
"L": "Shinjuku",
"ST": "Tokyo",
"C": "JP"
}
]
}
EOF
```
1. Create key/certificate files for the Ledger.
```console
cfssl selfsign "" ./ledger.json | cfssljson -bare ledger
```
1. Create key/certificate files for the Client.
```console
cfssl selfsign "" ./client.json | cfssljson -bare client
```
1. Confirm key/certificate files are created.
```console
ls -1
```
[Command execution result]
```console
client-key.pem
client.csr
client.json
client.pem
ledger-key.pem
ledger.csr
ledger.json
ledger.pem
```
## Step 5. Create DB schemas for ScalarDL Ledger using Helm Charts
We will deploy a ScalarDL Schema Loader on the Kubernetes cluster using Helm Charts.
The ScalarDL Schema Loader will create the DB schemas for ScalarDL Ledger in PostgreSQL.
1. Change the working directory to `~/scalardl-test/`.
```console
cd ~/scalardl-test/
```
1. Add the Scalar helm repository.
```console
helm repo add scalar-labs https://scalar-labs.github.io/helm-charts
```
1. Create a secret resource to pull the ScalarDL container images from AWS.
* AWS Marketplace
```console
kubectl create secret docker-registry reg-ecr-mp-secrets \
--docker-server=709825985650.dkr.ecr.us-east-1.amazonaws.com \
--docker-username=AWS \
--docker-password=$(aws ecr get-login-password --region us-east-1)
```
For more details, refer to [How to install Scalar products through AWS Marketplace](../scalar-kubernetes/AwsMarketplaceGuide.mdx).
1. Create a custom values file for ScalarDL Schema Loader (schema-loader-ledger-custom-values.yaml).
* AWS Marketplace
```console
cat << 'EOF' > ~/scalardl-test/schema-loader-ledger-custom-values.yaml
schemaLoading:
schemaType: "ledger"
image:
repository: "709825985650.dkr.ecr.us-east-1.amazonaws.com/scalar/scalardl-schema-loader-ledger"
version: "3.6.0"
imagePullSecrets:
- name: "reg-ecr-mp-secrets"
databaseProperties: |
scalar.db.contact_points=jdbc:postgresql://postgresql-ledger.default.svc.cluster.local:5432/postgres
scalar.db.username={{ default .Env.SCALAR_DL_LEDGER_POSTGRES_USERNAME "" }}
scalar.db.password={{ default .Env.SCALAR_DL_LEDGER_POSTGRES_PASSWORD "" }}
scalar.db.storage=jdbc
secretName: "ledger-credentials-secret"
EOF
```
1. Create a secret resource that includes a username and password for PostgreSQL.
```console
kubectl create secret generic ledger-credentials-secret \
--from-literal=SCALAR_DL_LEDGER_POSTGRES_USERNAME=postgres \
--from-literal=SCALAR_DL_LEDGER_POSTGRES_PASSWORD=postgres
```
1. Deploy the ScalarDL Schema Loader.
```console
helm install schema-loader-ledger scalar-labs/schema-loading -f ./schema-loader-ledger-custom-values.yaml
```
1. Check if the ScalarDL Schema Loader pod is deployed and completed.
```console
kubectl get pod
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-ledger-0 1/1 Running 0 11m
schema-loader-ledger-schema-loading-46rcr 0/1 Completed 0 3s
```
If the ScalarDL Schema Loader pod is **ContainerCreating** or **Running**, wait for the process will be completed (The STATUS will be **Completed**).
## Step 6. Deploy ScalarDL Ledger on the Kubernetes cluster using Helm Charts
1. Create a custom values file for ScalarDL Ledger (scalardl-ledger-custom-values.yaml).
* AWS Marketplace
```console
cat << 'EOF' > ~/scalardl-test/scalardl-ledger-custom-values.yaml
envoy:
image:
repository: "709825985650.dkr.ecr.us-east-1.amazonaws.com/scalar/scalar-ledger-envoy"
version: "1.3.0"
imagePullSecrets:
- name: "reg-ecr-mp-secrets"
ledger:
image:
repository: "709825985650.dkr.ecr.us-east-1.amazonaws.com/scalar/scalar-ledger"
version: "3.6.0"
imagePullSecrets:
- name: "reg-ecr-mp-secrets"
ledgerProperties: |
scalar.db.contact_points=jdbc:postgresql://postgresql-ledger.default.svc.cluster.local:5432/postgres
scalar.db.username={{ default .Env.SCALAR_DL_LEDGER_POSTGRES_USERNAME "" }}
scalar.db.password={{ default .Env.SCALAR_DL_LEDGER_POSTGRES_PASSWORD "" }}
scalar.db.storage=jdbc
scalar.dl.ledger.proof.enabled=true
scalar.dl.ledger.proof.private_key_path=/keys/private-key
secretName: "ledger-credentials-secret"
extraVolumes:
- name: "ledger-keys"
secret:
secretName: "ledger-keys"
extraVolumeMounts:
- name: "ledger-keys"
mountPath: "/keys"
readOnly: true
EOF
```
1. Create secret resource `ledger-keys`.
```console
kubectl create secret generic ledger-keys --from-file=private-key=./certs/ledger-key.pem
```
1. Deploy the ScalarDL Ledger.
```console
helm install scalardl-ledger scalar-labs/scalardl -f ./scalardl-ledger-custom-values.yaml
```
1. Check if the ScalarDL Ledger pods are deployed.
```console
kubectl get pod
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
postgresql-ledger-0 1/1 Running 0 14m
scalardl-ledger-envoy-547bbf7546-6cn88 1/1 Running 0 52s
scalardl-ledger-envoy-547bbf7546-rpg5p 1/1 Running 0 52s
scalardl-ledger-envoy-547bbf7546-x2vlg 1/1 Running 0 52s
scalardl-ledger-ledger-9bdf7f8bd-29bzm 1/1 Running 0 52s
scalardl-ledger-ledger-9bdf7f8bd-9fklw 1/1 Running 0 52s
scalardl-ledger-ledger-9bdf7f8bd-9tw5x 1/1 Running 0 52s
schema-loader-ledger-schema-loading-46rcr 0/1 Completed 0 3m38s
```
If the ScalarDL Ledger pods are deployed properly, you can see the STATUS are **Running**.
1. Check if the ScalarDL Ledger services are deployed.
```console
kubectl get svc
```
[Command execution result]
```console
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 47d
postgresql-ledger ClusterIP 10.109.253.150 5432/TCP 15m
postgresql-ledger-hl ClusterIP None 5432/TCP 15m
scalardl-ledger-envoy ClusterIP 10.106.141.153 50051/TCP,50052/TCP 83s
scalardl-ledger-envoy-metrics ClusterIP 10.108.36.136 9001/TCP 83s
scalardl-ledger-headless ClusterIP None 50051/TCP,50053/TCP,50052/TCP 83s
scalardl-ledger-metrics ClusterIP 10.98.4.217 8080/TCP 83s
```
If the ScalarDL Ledger services are deployed properly, you can see private IP addresses in the CLUSTER-IP column. (Note: `scalardl-ledger-headless` has no CLUSTER-IP.)
## Step 7. Start a Client container
We will use certificate files in a Client container. So, we create a secret resource and mount it to a Client container.
1. Create secret resource `client-keys`.
```
kubectl create secret generic client-keys --from-file=certificate=./certs/client.pem --from-file=private-key=./certs/client-key.pem
```
1. Start a Client container on the Kubernetes cluster.
```console
cat << 'EOF' | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: "scalardl-client"
spec:
containers:
- name: scalardl-client
image: eclipse-temurin:8-jdk
command: ['sleep']
args: ['inf']
volumeMounts:
- name: "client-keys"
mountPath: "/keys"
readOnly: true
volumes:
- name: "client-keys"
secret:
secretName: "client-keys"
restartPolicy: Never
EOF
```
1. Check if the Client container is running.
```console
kubectl get pod scalardl-client
```
[Command execution result]
```console
NAME READY STATUS RESTARTS AGE
scalardl-client 1/1 Running 0 11s
```
## Step 8. Run ScalarDL sample contracts in the Client container
The following explains the minimum steps. If you want to know more details about ScalarDL and the contract, please refer to the [Getting Started with ScalarDL](https://scalardl.scalar-labs.com/docs/latest/getting-started).
1. Run bash in the Client container.
```console
kubectl exec -it scalardl-client -- bash
```
After this step, run each command in the Client container.
1. Install the git, curl and unzip commands in the Client container.
```console
apt update && apt install -y git curl unzip
```
1. Clone ScalarDL Java Client SDK git repository.
```console
git clone https://github.com/scalar-labs/scalardl-java-client-sdk.git
```
1. Change the directory to `scalardl-java-client-sdk/`.
```console
cd scalardl-java-client-sdk/
```
```console
pwd
```
[Command execution result]
```console
/scalardl-java-client-sdk
```
1. Change branch to arbitrary version.
```console
git checkout -b v3.6.0 refs/tags/v3.6.0
```
```console
git branch
```
[Command execution result]
```console
master
* v3.6.0
```
If you want to use another version, please specify the version (tag) you want to use. You need to use the same version of ScalarDL Ledger and ScalarDL Java Client SDK.
1. Build the sample contracts.
```console
./gradlew assemble
```
1. Download CLI tools of ScalarDL from [ScalarDL Java Client SDK Releases](https://github.com/scalar-labs/scalardl-java-client-sdk/releases).
```console
curl -OL https://github.com/scalar-labs/scalardl-java-client-sdk/releases/download/v3.6.0/scalardl-java-client-sdk-3.6.0.zip
```
You need to use the same version of CLI tools and ScalarDL Ledger.
1. Unzip the `scalardl-java-client-sdk-3.6.0.zip` file.
```console
unzip ./scalardl-java-client-sdk-3.6.0.zip
```
1. Create a configuration file (client.properties) to access ScalarDL Ledger on the Kubernetes cluster.
```console
cat << 'EOF' > client.properties
scalar.dl.client.server.host=scalardl-ledger-envoy.default.svc.cluster.local
scalar.dl.client.cert_holder_id=client
scalar.dl.client.cert_path=/keys/certificate
scalar.dl.client.private_key_path=/keys/private-key
EOF
```
1. Register the certificate file of the client.
```console
./scalardl-java-client-sdk-3.6.0/bin/register-cert --properties ./client.properties
```
1. Register the sample contract `StateUpdater`.
```console
./scalardl-java-client-sdk-3.6.0/bin/register-contract --properties ./client.properties --contract-id StateUpdater --contract-binary-name com.org1.contract.StateUpdater --contract-class-file ./build/classes/java/main/com/org1/contract/StateUpdater.class
```
1. Register the sample contract `StateReader`.
```console
./scalardl-java-client-sdk-3.6.0/bin/register-contract --properties ./client.properties --contract-id StateReader --contract-binary-name com.org1.contract.StateReader --contract-class-file ./build/classes/java/main/com/org1/contract/StateReader.class
```
1. Execute the contract `StateUpdater`.
```console
./scalardl-java-client-sdk-3.6.0/bin/execute-contract --properties ./client.properties --contract-id StateUpdater --contract-argument '{"asset_id": "test_asset", "state": 3}'
```
This sample contract updates the `state` (value) of the asset named `test_asset` to `3`.
1. Execute the contract `StateReader`.
```console
./scalardl-java-client-sdk-3.6.0/bin/execute-contract --properties ./client.properties --contract-id StateReader --contract-argument '{"asset_id": "test_asset"}'
```
[Command execution result]
```console
Contract result:
{
"id" : "test_asset",
"age" : 0,
"output" : {
"state" : 3
}
}
```
1. Execute a validation request for the asset.
```console
./scalardl-java-client-sdk-3.6.0/bin/validate-ledger --properties ./client.properties --asset-id "test_asset"
```
[Command execution result]
```console
{
"status_code" : "OK",
"Ledger" : {
"id" : "test_asset",
"age" : 0,
"nonce" : "f31599c6-e6b9-4b77-adc3-61cb5f119bd3",
"hash" : "9ExfFl5Lg9IQwdXdW9b87Bi+PWccn3OSNRbhmI/dboo=",
"signature" : "MEQCIG6Xa4WOWGMIIbA3PnCje4aAapYfCMerF54xRW0gaUuzAiBCA1nCAPoFWgxArB34/u9b+KeoxQBMALI/pOzMNoLExg=="
},
"Auditor" : null
}
```
* Reference information
* If the asset data is not tampered with, the validation request (validate-ledger command) returns `OK` as a result.
* If the asset data is tampered with (e.g. the `state` value in the DB is tampered with), the validation request (validate-ledger command) returns a value other than `OK` (e.g. `INVALID_OUTPUT`) as a result, like the following.
[Command execution result (If the asset data is tampered with)]
```console
{
"status_code" : "INVALID_OUTPUT",
"Ledger" : {
"id" : "test_asset",
"age" : 0,
"nonce" : "f31599c6-e6b9-4b77-adc3-61cb5f119bd3",
"hash" : "9ExfFl5Lg9IQwdXdW9b87Bi+PWccn3OSNRbhmI/dboo=",
"signature" : "MEQCIGtJerW7N93c/bvIBy/7NXxoQwGFznHMmV6RzsgHQg0dAiBu+eBxkfmMQKJY2d9fLNvCH+4b+9rl7gZ3OXJ2NYeVsA=="
},
"Auditor" : null
}
```
* In this way, the ScalarDL Ledger can detect data tampering.
## Step 9. Delete all resources
After completing the ScalarDL Ledger tests on the Kubernetes cluster, remove all resources.
1. Uninstall ScalarDL Ledger, ScalarDL Schema Loader, and PostgreSQL.
```console
helm uninstall scalardl-ledger schema-loader-ledger postgresql-ledger
```
1. Remove the Client container.
```
kubectl delete pod scalardl-client --force --grace-period 0
```
1. Remove the working directory and sample files (configuration file, key, and certificate).
```console
cd ~
```
```console
rm -rf ~/scalardl-test/
```
## Further reading
You can see how to get started with monitoring or logging for Scalar products in the following documents.
* [Getting Started with Helm Charts (Monitoring using Prometheus Operator)](getting-started-monitoring.mdx)
* [Getting Started with Helm Charts (Logging using Loki Stack)](getting-started-logging.mdx)
* [Getting Started with Helm Charts (Scalar Manager)](getting-started-scalar-manager.mdx)
================================================
FILE: docs/helm-charts/how-to-deploy-scalar-admin-for-kubernetes.mdx
================================================
---
tags:
- Enterprise Standard
- Enterprise Premium
displayed_sidebar: docsEnglish
---
# How to deploy Scalar Admin for Kubernetes
This document explains how to deploy Scalar Admin for Kubernetes by using Scalar Helm Charts. For details on the custom values file for Scalar Admin for Kubernetes, see [Configure a custom values file for Scalar Admin for Kubernetes](configure-custom-values-scalar-admin-for-kubernetes.mdx).
## Deploy Scalar Admin for Kubernetes
To deploy Scalar Admin for Kubernetes, run the following command, replacing the contents in the angle brackets as described:
```console
helm install scalar-labs/scalar-admin-for-kubernetes -n -f / --version
```
## Upgrade a Scalar Admin for Kubernetes job
To upgrade a Scalar Admin for Kubernetes job, run the following command, replacing the contents in the angle brackets as described:
```console
helm upgrade scalar-labs/scalar-admin-for-kubernetes -n -f / --version
```
## Delete a Scalar Admin for Kubernetes job
To delete a Scalar Admin for Kubernetes job, run the following command, replacing the contents in the angle brackets as described:
```console
helm uninstall -n
```
================================================
FILE: docs/helm-charts/how-to-deploy-scalar-products.mdx
================================================
---
tags:
- Enterprise Standard
- Enterprise Premium
displayed_sidebar: docsEnglish
---
# Deploy Scalar products using Scalar Helm Charts
This document explains how to deploy Scalar products using Scalar Helm Charts. If you want to test Scalar products on your local environment using a minikube cluster, please refer to the following getting started guide.
* [Getting Started with Scalar Helm Charts](getting-started-scalar-helm-charts.mdx)
## Prerequisites
### Install the helm command
You must install the helm command to use Scalar Helm Charts. Please install the helm command according to the [Helm document](https://helm.sh/docs/intro/install/).
### Add the Scalar Helm Charts repository
```console
helm repo add scalar-labs https://scalar-labs.github.io/helm-charts
```
```console
helm repo update scalar-labs
```
### Prepare a Kubernetes cluster
You must prepare a Kubernetes cluster for the deployment of Scalar products. If you use EKS (Amazon Elastic Kubernetes Service) or AKS (Azure Kubernetes Service) in the production environment. Please refer to the following document for more details.
- [Guidelines for creating an Amazon EKS cluster for Scalar products](../scalar-kubernetes/CreateEKSClusterForScalarProducts.mdx)
- [Guidelines for creating an AKS cluster for Scalar products](../scalar-kubernetes/CreateAKSClusterForScalarProducts.mdx)
You must prepare a supported version of Kubernetes. For versions that Scalar Helm Charts supports, see [Kubernetes](https://scalardb.scalar-labs.com/docs/latest/requirements/#kubernetes).
### Prepare a database (ScalarDB, ScalarDL Ledger, ScalarDL Auditor)
You must prepare a database as a backend storage of ScalarDB/ScalarDL. You can see the supported databases by ScalarDB/ScalarDL in the following document.
* [ScalarDB Supported Databases](https://scalardb.scalar-labs.com/docs/latest/requirements#databases)
### Prepare a custom values file
You must prepare your custom values file based on your environment. Please refer to the following documents for more details on how to create a custom values file.
* [Configure a custom values file for Scalar Helm Charts](configure-custom-values-file.mdx)
### Get the container images
If you're using commercially licensed Scalar products, you must get the container images of those products. For details, see [How to get the container images of Scalar products](../scalar-kubernetes/HowToGetContainerImages.mdx).
If you're using any of the following products from the public container repository, you can get the container images from the public container repository with the default configuration of Scalar Helm Chart:
* Scalar Envoy (deploy with ScalarDB Cluster, ScalarDL Ledger, or ScalarDL Auditor)
* ScalarDL Schema Loader
* Scalar Admin for Kubernetes
## Deploy Scalar products
Please refer to the following documents for more details on how to deploy each product.
* [ScalarDB Cluster](how-to-deploy-scalardb-cluster.mdx)
* [ScalarDL Ledger](how-to-deploy-scalardl-ledger.mdx)
* [ScalarDL Auditor](how-to-deploy-scalardl-auditor.mdx)
* [Scalar Admin for Kubernetes](how-to-deploy-scalar-admin-for-kubernetes.mdx)
* [Scalar Manager](getting-started-scalar-manager.mdx)
* [[Deprecated] ScalarDB Server](how-to-deploy-scalardb.mdx)
* [[Deprecated] ScalarDB GraphQL](how-to-deploy-scalardb-graphql.mdx)
================================================
FILE: docs/helm-charts/how-to-deploy-scalardb-cluster.mdx
================================================
---
tags:
- Enterprise Standard
- Enterprise Premium
displayed_sidebar: docsEnglish
---
# How to deploy ScalarDB Cluster
This document explains how to deploy ScalarDB Cluster by using Scalar Helm Charts. For details on the custom values file for ScalarDB Cluster, see [Configure a custom values file for ScalarDB Cluster](configure-custom-values-scalardb-cluster.mdx).
## Deploy ScalarDB Cluster
```console
helm install scalar-labs/scalardb-cluster -n -f / --version