ScalarDL の入門
このページは英語版のページが機械翻訳されたものです。英語版との間に矛盾または不一致がある場合は、英語版を正としてください。
このドキュメントでは、Client SDK を使用して最初の簡単なコントラクトを実行して、ScalarDL を開始する方法について説明します。 ここでは、ScalarDL がすでにインストールされており、ScalarDL Ledger が実行されており、ローカルホスト上の 50051 および 50052 ポートをリッスンしていることを前提としています。そのような環境がない場合は、ドキュメントに従ってください。また、コントラクトを実行するために必要な証明書と秘密鍵をすでに持っていることも前提としています。
ScalarDL とは何ですか?
ScalarDL は、正確性、スケーラビリティ、およびデータベース非依存性を実現する、トランザクショナルデータベースシステム用のスケーラブルで実用的なビザンチン故障検出ミドルウェアです。
ScalarDL は、次の図に示すように、Ledger、Auditor、および Client SDK で構成されます。ScalarDL Ledger は、ハッシュチェーンと電子署名を使用した独自の方法でアプリケーションデータを管理します。ScalarDL Auditor はオプションのコンポーネントであり、Ledger に依存せずに Ledger データのコピーを管理して、Ledger データと Auditor データの不一致を特定します。 Client SDK は、Ledger および Auditor と対話するためのユーザー向けプログラムのセットです。詳細については、設計ドキュメントおよび 実装の詳細を参照してください。
ScalarDL (Ledger and Auditor) はデータを一連のアセットとして抽象化します。各アセットは、asset_id
と呼ばれるキーと age
と呼ばれる履歴バージョン番号によって識別されるレコードの履歴で構成されます。
このドキュメントでは、ScalarDL Client SDK を使用してアセットのステータスを管理する非常に単純なアプリケーションを作成します。
JDK をインストールする
ScalarDL は Java で記述されているため、Java の使用は ScalarDL アプリケーションを構築する最も簡単な方法の1つです。 このような場合は、次の Java Development Kit (JDK) のいずれかを環境にインストールする必要があります。
- Oracle JDK LTSバージョン (8、11、または17)
- OpenJDK LTSバージョン (8、11、または17)
ScalarDL は JDK 8 で構築されているため、コントラクトは JDK 8 と互換性のあるバイナリである必要があります。JDK 8 以外のバージョンを使用する場合は、JDK 8 と互換性のあるバイナリをビルドするようにビルドツールを構成する必要があります。バイナリ互換性を指定するには、javac の --release 8
オプションを使用する方法や、次のように JDK 8 ツールチェーンを使用するように Gradle (または Maven) 構成を設定する方法など、いくつかの方法があります。
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(8))
}
}
Gradle および Maven 構成の詳細については、Toolchains for JVM projects for Gradle および Guide to Using Toolchains for Maven を参照してください。
上記の LTS バージョンを使用することをお勧めしますが、他の非 LTS バージョンも動作する可能性があります。
さらに、他の JDK も ScalarDL で動作するはずですが、それらはテストされていません。
Client SDK をダウンロードする
Client SDK ライブラリは、Maven Central で入手できます。Gradle などのビルドツールを使用してアプリケーションにインストールできます。 たとえば、Gradle では、次の依存関係を build.gradle に追加できます。
dependencies {
compile group: 'com.scalar-labs', name: 'scalardl-java-client-sdk', version: '<version>'
}
ここからは、サンプル build.gradle
、サンプルコントラクト、 迅速なテストのためのツールも含まれます。
まず、使用するバージョン (例: 3.6.0) を指定します。利用可能なバージョンについては、タグを参照してください。
VERSION=X.Y.Z
次に、リポジトリのクローンを作成し、ツールをダウンロードします。
git clone https://github.com/scalar-labs/scalardl-java-client-sdk.git
cd scalardl-java-client-sdk
git checkout v$VERSION
curl -OL https://github.com/scalar-labs/scalardl-java-client-sdk/releases/download/v$VERSION/scalardl-java-client-sdk-$VERSION.zip
unzip scalardl-java-client-sdk-$VERSION.zip
mv scalardl-java-client-sdk-$VERSION client
プロパティを構成する
最初に行う必要があるのは、Client SDK を構成することです。 次のサンプルプロパティは、Client SDK が ScalarDL Ledger と対話するために最低限必要なプロパティです。
[client.properties]
# A host name of ScalarDL Ledger
scalar.dl.client.server.host=localhost
# An ID of a certificate holder. It must be configured for each private key and unique in the system.
scalar.dl.client.cert_holder_id=foo
# A certificate file path to use.
scalar.dl.client.cert_path=/path/to/foo.pem
# A private key file path to use.
scalar.dl.client.private_key_path=/path/to/foo-key.pem
サンプルの client.properties
ファイルは conf
ディレクトリにあるので、それを現在のディレクトリにコピーしましょう。
cp conf/client.properties .
コピーした client.properties
ファイルの値を環境に応じて更新してください。
証明書を登録します
次に、ScalarDL Ledger に証明書を登録しましょう。証明書の準備方法については、caclient-getting-startedをご確認ください。
今回は以 下のように簡単なツールを使って証明書を登録してみましょう。
client/bin/register-cert --properties client.properties
登録された証明書を使用すると、コントラクトの登録と実行が可能になるほか、データベース内のビザンチン故障の検出にも使用されます。
セキュリティ上の理由から、追加できるのは新しい証明書のみであり、既存の証明書を更新することはできないことに注意してください。新しい証明書を追加する場合は、登録ツールを実行する前に scalar.dl.client.cert_version
をインクリメントします。
コントラクトを作成する
ScalarDL のコントラクトは、事前定義された基本コントラクトクラス (JacksonBasedContract
クラスなど) を拡張し、invoke
メソッドをオーバーライドする単純な Java クラスです。アセットを作成し、それにいくつかの状態を関連付ける StateUpdater.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<JsonNode> 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<JsonNode>> asset = ledger.get(assetId);
if (!asset.isPresent() || asset.get().data().get("state").asInt() != state) {
ledger.put(assetId, getObjectMapper().createObjectNode().put("state", state));
}
return null;
}
}
このコントラクトは、引数からクライアント定義のアセット ID (asset_id
) と状態 (state
) を抽出し、指定された状態がアセットの現在の状態と異なる場合、そのアセット ID を Ledger 内の状態に関連付けます。
次に、以下のようにコントラクトを作成します。 次に、以下のようにコントラクトを作成します。
./gradlew assemble
これにより、build/classes/java/main/com/org1/contract/StateUpdater.class
が生成されます。