2021年6月15日
クリックテック・ジャパン株式会社
Qlikエンジンの
サーバーサイド拡張(SSE)
の基礎から実装まで
1. サーバーサイド拡張の概要 と gRPCの基礎
2. 単純なgRPCサーバー&クライアント実装(+セキュアな通信)
3. 双方向ストリーミングなgRPCサーバー&クライアント実装
4. サーバーサイド拡張(SSE)のサンプル実装とサンプルアプリ(.qvf)
5. Qlik Sense Enterprise for Windowsでの利用
6. その他の情報
アジェンダ このセッションでは、Qlikエンジンに独自の関数を追加可能にする
サーバーサイド拡張(SSE)について、その基礎となるgRPCから
関数の実装例まで、数あるコンピュータ言語の中から
Node.js(JavaScript)を使用して解説・デモをいたします。
3
サーバーサイド拡張の概要と
gRPCの基礎
4
Webブラウザで値を選択
(ロードスクリプトも可)
Qlikエンジンがデータの処理
(SSEの数式処理も行う)
軸・数式などのデータを
Qlikエンジンから受信し計算
1 2 3
Webブラウザに結果を表示
SSEの結果を受信
(結果のキャッシュも可能)
計算実行後の結果を返信
6 5 4
サーバーサイド拡張(Server Side Extension,SSE)
gRPC over
HTTP/2(TLS)
C++
Java
C#
Python
Node.js
Ruby
Go など
Qlikエンジン
(gRPCクライアント)
SSEサービス
(gRPCサーバー)
5
gRPCサーバーとしてのSSEサービスプロセス
 Qlik Sense Desktop
• Settings.iniで設定
 Qlik Sense Enterprise for Windows
• Qlik Management Console(QMC)で設定
 プログラミング言語でSSEサービス(gRPCサーバー)を開発
 SSEサービス(gRPCサーバー)を起動
 計算要求を受信し、結果をQlikエンジンに返す
SSEサービス(gRPCサーバー)の
• サーバーアドレス
• ポート番号
• HTTPS証明書
を設定(複数種のSSEサービスを設定可能)
C++
Java
C#
Python
Node.js
Ruby
Go など
gRPC over HTTP/2(TLS)
Qlikエンジン(gRPCクライアント) SSEサービス(gRPCサーバー)
例えば、Node.js製のSSEサービス(gRPCサーバー)を
• サーバーアドレス: sse.example.com
• ポート番号: 50053
• HTTPS証明書: sse_server_cert.pem など
として稼働
SSE.SumOfColumn(Col1) を呼び出し
SSE.SumOfColumn(Col1)の結果を返信
その他の
システム
6
gRPCとは
https://www.grpc.io/docs/
gRPCでは、クライアントアプリケーションは、ローカルオブジェクトである
かのように、別のマシン上のサーバーアプリケーションのメソッドを直接
呼び出すことができるため、分散アプリケーションやサービスを簡単に
作成できます。多くのRPCシステムと同様に、gRPCはサービスを定
義するという考えに基づいており、パラメーターと戻り値の型を使用し
てリモートで呼び出すことができるメソッドを指定します。サーバー側で
は、サーバーがこのインターフェースを実装し、gRPCサーバーを実行し
てクライアント呼び出しを処理します。クライアント側では、クライアント
にはサーバーと同じメソッドを提供するスタブ(一部の言語では単に
クライアントと呼ばれる)があります。
(出典 : gRPC公式サイト 日本語訳)
 Googleが開発したリモートプロシージャコール(RPC, 遠隔手続き呼び出し)の一種
• HTTP/2を利用し、プロセス間通信に利用される
 Protocol Buffersを利用したデータの送受信
• IDL(インターフェース定義言語, .protoファイル)によるデータ構造およびサービスの定義
 プラットフォーム非依存
• C++, Java(Kotlin), C#, Go, Python, Node.js, Ruby, PHP, Swift(Objective-C) など
• Windows, Linux, macOS など
7
gRPCサーバーとgRPCクライアントの開発手順の例
gRPCサービス定義ファイル: helloworld.proto
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
C++向けproto処理用ツールを使用して
C++向けスタブ・スケルトンコード(.h,.cc)を生成
Ruby向けproto処理用ツールを使用して
Ruby向けスタブ・スケルトンコード(.rb)を生成
C++向けgRPCライブラリ
Ruby向けgRPCパッケージ
C++でgRPCサービスを
実装したサーバーコード(.cpp)
RubyでgRPCサービス呼び出しを
実装したクライアントコード(.rb)
https://www.grpc.io/docs/
8
単純なgRPCサーバー&
クライアント実装
(+セキュアな通信)
開発環境の準備 – Node.js(JavaScript)
 Windows/Linux/macOSのいずれかを用意
• Windows 10 64bit
 OSに、Node.jsをインストール(v8.13.0~)
• Windows版: https://nodejs.org/dist/v14.17.0/node-v14.17.0-x64.msi
 protoファイル用にライブラリ(Protocol Buffersコンパイラ)をインストール
• npm install -g grpc-tools
• npm list –g
 セキュア(TLS)通信用の証明書生成のためにOpenSSLをインストール
• Windows版: https://slproweb.com/products/Win32OpenSSL.html
 証明書を生成(Common Nameはlocalhost, server.crt, server.key, PEM形式)
• openssl req -newkey rsa:2048 -nodes -keyout server.key -x509 -days 3650
-out server.crt
 gRPCのWebサイトのドキュメント類を参照
• https://grpc.io/docs/languages/node/
• https://github.com/grpc/grpc
gRPCサービスの定義
 helloworld.proto gRPCクライアント gRPCサーバー
call SayHello(HelloRequest)
return HelloReply
 Node.js用のスタブ・スケルトンを生成(helloworld_pb.js, helloworld_grpc_pb.js)
• grpc_tools_node_protoc --js_out=import_style=commonjs,binary:./ --grpc_out=grpc_js:./ ./helloworld.proto
gRPCサーバー実装 - greeter_ssl_server.js
 Node.js向けgRPCライブラリ(パッケージ)をインストール
• npm install @grpc/proto-loader google-protobuf @grpc/grpc-js
必要なモジュール群のロード
証明書(PEM形式)読み込み
gRPCサーバーを生成し、サービス提供用メソッドを
登録し、50051番ポートでTLSで起動
戻り値を生成し、 call内にある引数を取得し、
callbackで戻り値を返信(null=エラー無し)
gRPCクライアント実装 - greeter_ssl_client.js
 Node.js向けgRPCライブラリ(パッケージ)をインストール
• npm install @grpc/proto-loader google-protobuf @grpc/grpc-js
必要なモジュール群のロード
証明書(PEM形式)読み込み
gRPCサーバーへの接続設定を
行うが、証明書の検証をスキップ
(Common Name)
引数を生成し、sayHello関数を
呼び出し
戻り値をコールバックで受信し、出
力してプロセスを終了
gRPCサーバーとクライアントの実行
 node greeter_ssl_client.js
 node greeter_ssl_server.js
14
双方向ストリーミングな
gRPCサーバー&クライアント実装
gRPCのストリーミングの特徴
 gRPCで送受信するデータの最大サイズはデフォルトで4MB
 サービス(関数)の呼び出し時に、4MBを越える巨大な引数や戻り値を処理できない(エラーが発生)
 引数や戻り値を小分けに分割して、配列のように(配列ではない)少しづつ送受信できる
 Qlikエンジンのサーバーサイド拡張(SSE)では、ストリーミング形式でデータを送受信する
• ServerSideExtension.proto
gRPCサービスの定義
 hellostreamingworld.proto gRPCクライアント gRPCサーバー
call SayHello(HelloRequest)
return HelloReply
 Node.js用のスタブ・スケルトンを生成(hellostreamingworld_pb.js, hellostreamingworld_grpc_pb.js)
• grpc_tools_node_protoc --js_out=import_style=commonjs,binary:./ --grpc_out=grpc_js:./
./hellostreamingworld.proto
gRPCサーバー実装 - greeter_stream_server.js
 Node.js向けgRPCライブラリ(パッケージ)をインストール
• npm install @grpc/proto-loader google-protobuf @grpc/grpc-js
必要なモジュール群のロード
gRPCサーバーを生成し、サービス提供用
メソッドを登録し、50052番ポートで起動
call.on(‘data’, ...)のコールバックは繰り
返し呼び出され、引数全体を複数回に
渡って受信し続ける
コールバック内では、複数回戻り値を生成し
て、call.write(...)で返信し続ける
引数全体を受信し終えると、
call.on(‘end’, ...)のコールバックが呼び出さ
れ、call.end()でsayHelloの処理を終了
gRPCクライアント実装 - greeter_stream_client.js
 Node.js向けgRPCライブラリ(パッケージ)をインストール
• npm install @grpc/proto-loader google-protobuf @grpc/grpc-js
必要なモジュール群のロード
引数全体をいったん配列に保持しておく(必須
ではない)
引数全体を複数回のcall.write(...)呼び
出しで送信し、call.end()で送信を完了
戻り値をすべて受信し終えたら、
call.on(‘end’, ...)のコールバックが呼び出さ
れ、プロセスを終了
戻り値の全体を、複数回に渡って
call.on(‘data’, ...)のコールバックで受信する
gRPCサーバーへの接続設定を行う
gRPCサーバーとクライアントの実行
 node greeter_stream_client.js
 node greeter_stream_server.js
20
サーバーサイド拡張(SSE)の
サンプル実装と
サンプルアプリ(.qvf)
サーバーサイド拡張のデータ送受信の特徴
 ストリーミング形式でデータを送受信
引数や戻り値は、数値型(64bit倍精度浮動小数点数)または文字列型で、「複数列x複数行」の表形式(BundledRows x N個)
 データ以外の様々な情報を、gRPCのメタデータ(ヘッダー領域)で送受信
QlikエンジンがSSEの処理結果をキャッシュとして保持するか否か、関数名や、データの型など
 サービス定義のprotoファイルはGitHubから取得
https://github.com/qlik-oss/server-side-extension/raw/master/proto/ServerSideExtension.proto
Qlikエンジン SSEサービス
call GetCapabilities()
return Capabilities
 GetCapabilities(Qlikエンジンから一度だけ呼び出される)
SSEサービスの機能(数式の関数定義や、EvaluateScriptサポートの有無)を返す
 ExecuteFunction
SSEサービスが各関数ごとにデータを受信し、処理して結果を返す
 EvaluateScript(オプショナル)
SSEサービスが任意の文字列とデータを受信し、処理して結果を返す
●
●
●
BundledRows
BundledRows
BundledRows
BundledRows
サーバーサイド拡張の実装例 - SSE_Example.js
必要なモジュール群のロード
 Node.js向けgRPCライブラリ(パッケージ)をインストール: npm install @grpc/proto-loader google-protobuf @grpc/grpc-js
 Node.js用のスタブ・スケルトンを生成(ServerSideExtension_pb.js, ServerSideExtension_grpc_pb.js)
• grpc_tools_node_protoc --js_out=import_style=commonjs,binary:./ --grpc_out=grpc_js:./ ./ServerSideExtension.proto
ColA
1
3
5
7
9
EvaluateScriptサポートは無し
Qlikの数式: [SSEエンジン名].SumOfColumn(ColA)
gRPCサーバーを生成し、サービス提供用メソッド(2個)を登録し、
50053番ポートで起動
25
A
1
3
5
7
9
Qlikの数式: [SSEエンジン名].SumOfRows(A, B)
B
2
4
6
8
10
3
7
11
15
19
サーバーサイド拡張の実装例(続き)
gRPCの呼び出し情報のメタデータから
関数のID(今回の例では0または1)を取得
Qlikエンジンが結果をキャッシュ
しないようにメタデータを返信
集計処理後に結果(1列x1行)を返信
行ごとに計算し、結果(1列xN行)を返信
Qlik Sense Desktopで動作を確認
1. Qlik Sense Desktopをインストール
 サーバーサイド拡張(SSEサービス)の開発時は、証明書によるセキュア(TLS)なgRPCサーバーが
必須ではない「Qlik Sense Desktop」が便利
 「Qlik Sense Enterprise for Windows」は証明書(後述)が必須
2. SSEサービスを起動
 node SSE_Example.js
3. SSEサービスへの接続設定(SSEエンジン名はColumn)
 C:Users[user]DocumentsQlikSenseSettings.ini を編集
4. Qlik Sense Desktopを起動
 function getCapabilities(call, callback){...} が呼び出されるのをログ出力で確認
Qlik Sense Desktopで動作を確認
1. サンプルアプリ(SSE_Example.qvf)をオープン
2. 項目の選択状態を変更するたびにSSEサービスが呼び出される(キャッシュがOFFのため)
26
Qlik Sense Enterprise
for Windowsでの利用
SSE通信専用の証明書を準備
1. 「Qlik Sense Enterprise for Windows」はSSE通信専用の証明書(PEM形式)が必須
2. OpenSSLが利用できることを確認
3. GitHubで「Generating certificates」のページの説明を読む
• https://github.com/qlik-oss/server-side-extension/tree/master/generate_certs_guide
4. SSE通信専用の証明書生成スクリプトと設定ファイルをダウンロード
• generate_sse_certs.bat (Windows用) または generate_sse_certs.sh (Linux/macOS用)
• sse_client_config.txt
• sse_server_config.txt
5. ‘sse_server_config.txt’の[alt_names]欄を編集
• 生成される証明書の Common Name は sse_server で固定
• QlikエンジンはSSEサーバーの検証にSAN(Subject Alternative Name)を利用
6. generate_sse_certs.bat を実行して証明書を生成
証明書でセキュア(TLS)なSSEサービスに
1. 生成された証明書(PEM形式)をSSEサービスのフォルダ等にコピーする
• sse_Column_generated_certs/sse_Column_server_certs/root_cert.pem
• sse_Column_generated_certs/sse_Column_server_certs/sse_server_cert.pem
• sse_Column_generated_certs/sse_Column_server_certs/sse_server_key.pem
2. 前述した「SSE_Example.js」のコードを改変して「SSE_Example_ssl.js」として実行
3. node SSE_Example_ssl.js
Qlik Sense Enterprise for Windowsを設定
1. Qlik Sense Enterprise for Windowsのマシンに、生成された証明書(PEM形式)をコピーする
• sse_Column_generated_certssse_Column_client_certs_used_by_qlikroot_cert.pem
• sse_Column_generated_certssse_Column_client_certs_used_by_qliksse_client_cert.pem
• sse_Column_generated_certssse_Column_client_certs_used_by_qliksse_client_key.pem
2. Qlik Sense Management Console(QMC)で[Analytic connections]にColumnを追加
• Name(SSEエンジン名): Column
• Host: SSEサービスのサーバーアドレス
• Port: SSEサービスのポート番号
• Certificate file path: 証明書が置かれているパス
1. サンプルアプリ(SSE_Example.qvf)をQMCでアップロード
QlikエンジンとSSEサービスとサンプルアプリ
1. Qlik Senseは定期的にSSEサービスに接続を試みる(ただしGetCapabilitiesの呼び出しは1度のみ)
2. SSEサービスを実行、またはSSEサービスの内容を変更したらSSEサービスを再起動
• node SSE_Example_ssl.js
注: GetCapabilitiesの実装を改変した場合は、Qlik Sense Engine Serviceの再起動も必要
3. サンプルアプリ(SSE_Example.qvf)をオープン
31
その他の情報
サーバーサイド拡張(SSE)に関する資料
 GitHub >> qlik-oss / Server Side Extension
https://github.com/qlik-oss/server-side-extension
 オンラインヘルプ >> Qlik Sense Enterprise on Windows >> 分析接続の作成
https://help.qlik.com/ja-JP/sense-
admin/May2021/Subsystems/DeployAdministerQSE/Content/Sense_DeployAdminister/QSEoW/Administer_QSEoW/Managing_QSEoW/creat
e-analytic-connection.htm
 オンラインヘルプ >> Qlik Sense Desktopにおける分析接続の構成
https://help.qlik.com/ja-JP/sense/May2021/Subsystems/Hub/Content/Sense_Hub/Introduction/configure-analytic-connection-desktop.htm
 gRPCサーバー&クライアント, QlikエンジンSSEの実装例 - Node.js
https://github.com/ttcodegear/gRPC_Nodejs_QS_SSE
 gRPCサーバー&クライアント, QlikエンジンSSEの実装例 - C#(.NET Core 3.1/5.0)
https://github.com/ttcodegear/gRPC_dotNETCore_QS_SSE
 gRPCサーバー&クライアント, QlikエンジンSSEの実装例 - Java(JDK8 or later)
https://github.com/ttcodegear/gRPC_Java_QS_SSE
 gRPCサーバー&クライアント, QlikエンジンSSEの実装例 - Go
https://github.com/ttcodegear/gRPC_Go_QS_SSE
 gRPCサーバー&クライアント, QlikエンジンSSEの実装例 - Ruby
https://github.com/ttcodegear/gRPC_Ruby_QS_SSE
 gRPCサーバー&クライアント, QlikエンジンSSEの実装例 - Python
https://github.com/ttcodegear/gRPC_Python_QS_SSE
Qlik TechFest C-5  Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装まで

Qlik TechFest C-5 Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装まで

Editor's Notes