VSAM on z/OS のレプリケーション - (3) Kafka連携

# はじめに
ここまでz/OS上のVSAMファイルをLinux上のDb2にレプリケーションする例を試してみました。今回はターゲットを変更してDb2の代わりにKafkaを使用する構成を作ってみます。つまり、VSAM on z/OS => Kafka on Linuxへのレプリケーションを試してみます。

## 関連記事

[VSAM on z/OS のレプリケーション - (1) 環境構築(to Db2)](https://qiita.com/tomotagwork/items/76b531eed506658381c0)
[VSAM on z/OS のレプリケーション - (2) レプリケーション構成(to Db2)](https://qiita.com/tomotagwork/items/e6c260edc9fd30c82fab)
[VSAM on z/OS のレプリケーション - (3) Kafka連携](https://qiita.com/tomotagwork/items/c6cdf650a9eadd482019)
[VSAM on z/OS のレプリケーション - (4) VSAMファイルの追加(Kafka連携) / レプリケーションのテスト](https://qiita.com/tomotagwork/items/5be473550df81c52184d)

# 全体像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/be07bd74-3719-155f-0e97-40278b277fe7.png)

Db2の部分をKafkaに置き換えるので、Target EngineもKafka用のものに置き換えます。それ以外はこれまで構築してきたものをそのまま利用することにします。

# ターゲット環境(Kafka)構築
以下を参考に。
[CDC Replication Engine for Kafka](https://www.ibm.com/docs/en/idr/11.4.0?topic=replication-cdc-engine-kafka)

## Kafka(Confluent Platform)

ターゲットとなるKafkaの環境を準備しておきます。ここではConfluent Platformを使用します。テスト用なので、1ノード、1Broker、基本的にデフォルトの構成で使用します。

具体的な環境構築手順は以下を参照。
[Confluent Platform メモ - (1)環境構築](https://qiita.com/tomotagwork/private/7cc244c8b4605a056328)

## Target Engine (CDC Replication Engine for Kafka) インストール

### 管理用ユーザー作成

管理ユーザーとしてcdckafkaを作成し、パスワードを設定しておきます。

```
[root@test12 ~]# useradd cdckafka
[root@test12 ~]# passwd cdckafka
ユーザー cdckafka のパスワードを変更。
新しいパスワード:
新しいパスワードを再入力してください:
passwd: すべての認証トークンが正しく更新できました。
```

### インストール
インストーラーはDb2用のEngineを導入した時と同じものを使用します。
参考: [(1)環境構築 - (6) Target Engine(CDC Replication Engine for Db2 for LUW) - インストール](https://qiita.com/tomotagwork/private/76b531eed506658381c0#%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB-3)

cdckafkaユーザーでインストーラーのbin(setup-iidr-11.4.0.4-5602-linux-x86.bin)を実行します。

指示に従ってインストール。

<details><summary><font color="blue">インストール時のログ</font></summary><div>

```
[cdckafka@test12 /Inst_Image/CDC/CDCAgent]$ ./setup-iidr-11.4.0.4-5602-linux-x86.bin
Preparing to install
Extracting the JRE from the installer archive...
Unpacking the JRE...
Extracting the installation resources from the installer archive...
Configuring the installer for this system's environment...

Launching installer...

===============================================================================
ロケールの選択...
----------

    1- English
  ->2- 日本語

番号でロケールを選択してください: 2
===============================================================================
IBM InfoSphere Data Replication                           (InstallAnywhere で作成)
-------------------------------------------------------------------------------

コンソール モード インストールの準備中...




===============================================================================


概要
InstallAnywhere を使用して、IBM InfoSphere Data Replication 11.4.0.4
をインストールします。

各プロンプトに応答して、
インストールの次のステップに進みます。
前のステップに戻って変更を加えたい場合は、
「back」と入力します。

「quit」と入力すると、
いつでもインストールをキャンセルできます。
  ->1- 新規製品のインストール
    2- 既存製品のアップグレード

選択項目の番号を入力するか、<ENTER>
   を押してデフォルトを受け入れてください。: 1



===============================================================================


データ・ストア・タイプの選択
  ->1- IBM Db2 for z/OS
    2- Kafka
    3- IBM DB2
    4- IBM InfoSphere DataStage (including Apache Hadoop, WebHDFS, Cloudant)
    5- FlexRep
    6- IBM Netezza
    7- Oracle
    8- Oracle XStream
    9- Oracle Trigger
   10- Teradata
   11- PostgreSQL
   12- MySQL

選択項目の番号を入力するか、<ENTER>
   を押してデフォルトを受け入れてください。: 2



===============================================================================


オファリングの選択

資格を持つオファリングの判別でお困りの場合は、
営業担当員にお問い合わせください。

  ->1- IBM Data Replication
    2- IBM Data Replication Targets for z/OS Sources
    3- IBM InfoSphere Data Replication Non-RDBMS Targets
    4- IBM InfoSphere Data Replication
    5- IBM InfoSphere Change Data Delivery
    6- IBM InfoSphere Change Data Delivery for PureData System for Analytics
    7- IBM Data Replication Db2 for z/OS Remote Source
    8- IBM Data Replication VSAM for z/OS Remote Source

選択項目の番号を入力するか、<ENTER>
   を押してデフォルトを受け入れてください。: 4



===============================================================================
インストール・フォルダーの選択
---------------

インストール・フォルダー

  デフォルトのインストール フォルダー: /opt/ibm/InfoSphereDataReplication/ReplicationEngineforKafka

絶対パスを入力するか、ENTER
   キーを押してデフォルトを使用してください。
      :



===============================================================================




    ライセンス情報

    以下の「プログラム」は、お客様と IBM
とが事前に合意した「プログラム」の
    使用許諾条件に加えて、
次のライセンス情報の使用条件に基づいて使用許諾さ
    れます。 お客様が「プログラム」の有効な使用許諾条件
に事前に合意していな
    い場合、 プログラムのご使用条件 (Z125-3301-14)
が適用されます。

    プログラム名 (プログラム番号):
    IBM InfoSphere Data Replication V11.4.0.4 (5725-E30)
    IBM InfoSphere Data Replication for Non-Production Environments V11.
    4.0.4 (5725-E30)

    以下の標準条件が、
ライセンシーによる「プログラム」の使用に適用されま
    す。

    使用制限付き権利

    バンドル・プログラムを例外として、
ライセンシーに提供されるすべての IBM

ご使用条件の続きを読む場合は、Enter
   キーを押してください。「同意する」場合は「1」を押し、
   「同意しない」場合は「2」、印刷する場合は「3」、
   英文でご覧になる場合は「5」を押してください。
   「99」を押すと前の画面に戻ります。: 1




===============================================================================
インスタンス・フォルダーの選択
---------------

インスタンスおよび製品ログをどこに作成しますか?

絶対パスを入力するか、Enter
を押してデフォルトを受け入れます

インスタンス・フォルダー: (デフォルト:
   /opt/ibm/InfoSphereDataReplication/ReplicationEngineforKafka):




===============================================================================
プリインストール要約
----------

処理を続行する前に、以下の内容を確認してください。

製品名:
    IBM InfoSphere Data Replication

インストール フォルダー:
    /opt/ibm/InfoSphereDataReplication/ReplicationEngineforKafka

インスタンス・フォルダー:
    "/opt/ibm/InfoSphereDataReplication/ReplicationEngineforKafka"

データ・ストア・タイプ:
    Kafka

オファリング:
    IBM InfoSphere Data Replication

ディスク容量情報 (インストール先):
    必要なディスク容量:  422,637,876 バイト
    使用可能なディスク容量: 49,491,722,240 バイト

続行するには ENTER キーを押します:



===============================================================================
インストール中...
----------

 [==================|==================|==================|==================]
 [------------------|------------------|------------------|------------------]



===============================================================================
インストールが完了しました
-------------

お疲れさまでした。 IBM InfoSphere Data Replication
は次の場所に正常にインストールされました。
/opt/ibm/InfoSphereDataReplication/ReplicationEngineforKafka

/opt/ibm/InfoSphereDataReplication/ReplicationEngineforKafka/bin/dmconfigurets
を実行して
   構成ツールを起動できます。

構成ツールを起動しますか? (1=はい、2=いいえ)
   (デフォルト: 1): 2

```

</div></details>

### Target Engineインスタンス作成/起動

cdckafkaユーザーで以下のコマンドを実行して構成ツールを起動します。
(GUIのツールが起動するのでX Serverが必要です。)

```
[cdckafka@test12 ~]$ /opt/ibm/InfoSphereDataReplication/ReplicationEngineforKafka/bin/dmconfigurets
```

OK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/ee46a7d2-9218-feb9-98bf-d39bc0324aa8.png)


メモリーは4096以上を指定する必要があるようです。
Encryption profileのManageをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/efbc9082-efe7-3127-2ff5-b2de0c010f76.png)

追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/364ee27c-283b-8812-3b57-eca725dab62f.png)

NoTLSというProfile名、Encryption:Disabledを指定してOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/a25bdb71-0083-86bb-feae-a69a0e5cb932.png)


インスタンス構成画面に戻ってEncryption profileで、上で追加したNoTLSを選択。その他のパラメータも適宜選択して、「通信プロトコル」タブへ。
※tsuserというのはReplication Engineインスタンス上でのユーザーのようです。ユーザー名は固定で変更できないのでパスワードのみ指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/a49e89f5-c351-8448-b69c-0a90a84bfd2a.png)

TCP/IPのみ を選択してOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/e89c46cf-4c68-a32d-d177-1b87e3869104.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/0180f96d-0b04-4e03-facd-08307506cb21.png)

はい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/f93f03cf-86ec-72a7-207b-b670de7d0c07.png)

インスタンスが起動されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/ff8df7d3-280f-ee8b-cffb-c8762f8e7a6d.png)

`<instance_dir>/conf/`以下にProducer,Consumer用のプロパティファイルが作成されていました。

```/opt/ibm/InfoSphereDataReplication/ReplicationEngineforKafka/instance/cdc_kafka_test01/conf/kafkaproducer.properties
#Default values are provided as below: 'retries' is used for retry times and 'retry.backoff.ms' is for sleep time during each retry
#Mon Aug 16 11:37:30 JST 2021
retries=3
retry.backoff.ms=500
batch.size=65536
```

```/opt/ibm/InfoSphereDataReplication/ReplicationEngineforKafka/instance/cdc_kafka_test01/conf/kafkaconsumer.properties
#
#Mon Aug 16 11:37:30 JST 2021
```

今回はとりあえずデフォルトのままとします。

### Target Engineインスタンス起動/停止
起動コマンド: amdts64
停止コマンド: dmshutdown


2回目以降はGUIのツールを起動しなくてもコマンドでインスタンスを起動/停止することができます。
admts64コマンドでインスタンスを起動できます。(cdckafkaユーザーで実行)
参考: [Starting the CDC Replication Engine for Kafka](https://www.ibm.com/docs/en/idr/11.4.0?topic=kafka-starting-cdc-replication-engine)

```
[cdckafka@test12 ~]$ /opt/ibm/InfoSphereDataReplication/ReplicationEngineforKafka/bin/dmts64 -I cdc_kafka_test01 &
```

dmshutdownコマンドでインスタンスを起動できます。(cdckafkaユーザーで実行)
参考: [Stopping the CDC Replication Engine for Kafka](https://www.ibm.com/docs/en/idr/11.4.0?topic=kafka-stopping-cdc-replication-engine)

```
[cdckafka@test12 ~]$ /opt/ibm/InfoSphereDataReplication/ReplicationEngineforKafka/bin/dmshutdown -I cdc_kafka_test01
IBM InfoSphere Data Replication が正常にシャットダウンされました。
```

### ネットワーク構成

firewalldに対してポート11701へのアクセスを許可しておきます。

```
[root@test12 ~]# firewall-cmd --zone=public --add-port=11701/tcp --permanent
success
[root@test12 ~]# firewall-cmd --reload
success
```


# レプリケーション構成

## ソース側設定

ソース側(VSAM)の設定は、前回の記事で作成したものをそのまま使います。
参考: [(2) レプリケーション構成 - ソース側設定](https://qiita.com/tomotagwork/items/e6c260edc9fd30c82fab#1-%E3%82%BD%E3%83%BC%E3%82%B9%E5%81%B4%E8%A8%AD%E5%AE%9A)

## ターゲット側設定

ターゲット側としてはKafkaのサーバーとTarget Engineのインスタンスがあればよさそうです。

## レプリケーション設定(サブスクリプション)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/35d9ae43-2960-4e06-41c1-dd5882036db3.png)

Management ConsoleからAccess Serverに接続して各種オブジェクトの定義を行っていきます。

### ソース用データストアの作成
これも前回の記事で作成したものをそのまま使います。
参考: [(2) レプリケーション構成 - レプリケーション設定 - ソース用データストアの作成](https://qiita.com/tomotagwork/private/e6c260edc9fd30c82fab#%E3%82%BD%E3%83%BC%E3%82%B9%E7%94%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B9%E3%83%88%E3%82%A2%E3%81%AE%E4%BD%9C%E6%88%90)

### ターゲット用データストアの作成
Management Consoleを開いて、Access Serverに接続します。
ファイル - Access Server - 新規データストアを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/0cdb49ae-47ef-6ecc-103c-5637d9e287d6.png)

適当な名前を指定し、CDC Replication Engine for KafkaのインスタンスがListenするホスト名、ポートを指定します。ここで指定するホスト、ポートは、Access Serverおよび、コンテナ内のVSAM Remote Sourceから辿れるホスト名、ポートを指定する必要があります。
Pingボタンをクリックすると指定したCDC Replication Engineに接続してプロパティー部分の情報が更新されます。接続パラメーターボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/417e3b3a-5c9b-c6d2-067d-f1f72d321cbd.png)

Target Engineのインスタンス作成時に指定したtsuserとパスワードを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/39042bcf-63b9-6de9-5d51-0789709390c5.png)

OKをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/646a0adb-4d47-4dae-7d94-78fcc0a6df66.png)

Kafka用のターゲット・データストアが作成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/28f899cc-cf2e-4a24-68d4-93831ede2273.png)

#### ユーザーの割り当て

上で作成したデータストアに対してユーザーの割り当てを行います。

アクセス・マネージャータブのデータ・ストアの管理ビューで、データストア名"Kafka_test01"(ターゲット用)を右クリックしてユーザーの割り当てを選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/d4779040-801b-e677-c9c6-edd5a6861133.png)

cdcadminを選択してOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/c6189db7-61bd-ce28-af5e-5f2e8ff6bba5.png)

デフォルトのユーザーが表示されるのでそのままOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/5c70b1fe-312f-6e05-bb7e-045586954f1d.png)

右側の接続の管理ビューで、cdcadminユーザーが追加されたことが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/071f5944-c9b4-6be7-a82a-2c6d29b92e8a.png)


### サブスクリプションの作成

構成タブに切り替えて、サブスクリプションビューの"新規サブスクリプションの作成"アイコンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/01656ece-7c06-9641-1039-1630a9dc62f9.png)

適当な名前を指定し、データストアにはソースとしてVsamRemoteSource01、ターゲットとしてKafka_test01を指定し、拡張設定をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/d2298283-fa0d-8a6c-f85c-b892196d38ee.png)

確認のみ。(ソースIDとして前画面の名前の先頭8文字がとられるようなので、全画面の名前も8文字にしておくとよい)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/bb165a2c-a885-d43f-5efe-d631d30a1fdc.png)

OK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/6be06864-a2d9-56af-a9d4-237eb1beb2b8.png)

はい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/51ee8fd4-87e9-8602-82bb-f2c74246395e.png)

カスタムKafkaマッピングを選択して次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/5ac60f0f-804b-e1ab-a7ce-6466dd243f72.png)

FILEAを選択して次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/7936448a-b3b5-0003-9189-762ad9e8d597.png)

キー列としてNUMBを選択して右矢印をクリック (キー列にNUMBが表示された状態にする)
次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/d3f95996-d35e-125f-2d75-14b088c5f19f.png)

現在のビューに戻るを選択して終了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/53bdbd8a-5599-4292-fbc1-a1113339312d.png)


<details><summary><font color="blue">参考: Keyがnullのケース</font></summary><div>
以下の手順でサブスクリプションを作成すると、KafkaのTopicにデータが格納される際にKeyがnullになってしまっていました。
※Kafka上はkeyがnullのメッセージも許容されますが、RecordがDeleteされた場合のレプリケーションのメッセージとしてはkey値のみでvalueがnullのメッセージが送付されます(後述)。そのためkey値nullだとdeleteがうまくハンドリングできないということになりますのでご注意ください。

複数のKafkaマッピングを選択して次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/97a09829-a21b-2a7c-d5fd-fa2f18f22c56.png)

FILEAにチェックをして次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/8fff6742-4bc9-11c6-f3f1-663348ee2755.png)

そのまま終了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/23138257-61c4-6ba5-4be2-6806140e60a3.png)
</div></details>




#### Kafkaプロパティーの設定
参考: [Specifying connection settings for a subscription applying to Kafka](https://www.ibm.com/docs/en/idr/11.4.0?topic=subscriptions-specifying-connection-settings-subscription-applying-kafka)
上に表示された警告に従って、今作成したサブスクリプションを右クリック-Kafkaプロパティーを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/89e80ed7-fcd2-dbaa-fa07-9cc1a94585b8.png)

※以下のKafkaプロパティーウィンドウが開いた際に全ての項目がグレーアウトされている場合、一旦データストアビューからデータストア(Kafka_test01)を右クリック-切断/接続を選択して再接続してから実施すると設定できるようになった。
ZooKeeper Serverを指定して、ZooKeeperのアドレス、ポートを指定します。また、Schema Registryのアドレス、ポートも指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/7a35fb4e-535a-a53a-69f2-28dce2bac019.png)

## レプリケーションの実行

### リフレッシュ
まず最初に、現時点でのVSAMデータをKafkaに反映させておきます。
この時、CICSからはVSAMをClose状態にしておきます。

サブスクリプションを右クリック - リフレッシュの開始を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/51115fd4-9fb3-3e6a-d583-2ada001ee62e.png)

OK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/49d75297-4502-d05a-12c0-d3424efa11ac.png)

Kafka上のTopicのリストを参照してみます。

```
[root@test12 /opt/confluent-6.2.0/bin]# ./kafka-topics --list --bootstrap-server localhost:9092
__consumer_offsets
_schemas
cdc_kafka_test01-VSAMT02-commitstream
cdc_kafka_test01.vsamt02.sourcedb.vsam.test01.filea
```

cdc_kafka_test01-VSAMT02-commitstream, cdc_kafka_test01.vsamt02.sourcedb.vsam.test01.filea という2つのTopicが作成されています。

`kafka-avro-console-consumer`コマンドを使って Topic`cdc_kafka_test01.vsamt02.sourcedb.vsam.test01.filea`のメッセージを参照してみます。

```
[root@test12 /opt/confluent-6.2.0/bin]# ./kafka-avro-console-consumer --from-beginning --topic cdc_kafka_test01.vsamt02.sourcedb.vsam.test01.filea \
>    --bootstrap-server localhost:9092 \
>    --property print.key=true \
>    --property print.schema.ids=true \
>    --property schema.id.separator=: \
>    --property schema.registry.url=http://localhost:8081
{"NUMB":{"string":"000001"}}:6  {"STAT":{"string":"U"},"NUMB":{"string":"000001"},"NAME":{"string":"AAAAAA              "},"ADDRX":{"string":"AAA                 "},"PHONE":{"string":"1111    "},"DATEX":{"string":"11      "},"AMOUNT":{"string":"$0001.00"},"COMMENT":{"string":"AAAAAA   "}}:5
{"NUMB":{"string":"000002"}}:6  {"STAT":{"string":"U"},"NUMB":{"string":"000002"},"NAME":{"string":"AAA                 "},"ADDRX":{"string":"TTT                 "},"PHONE":{"string":"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"},"DATEX":{"string":"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"},"AMOUNT":{"string":"$0001.00"},"COMMENT":{"string":"COMMENT  "}}:5
{"NUMB":{"string":"000003"}}:6  {"STAT":{"string":"U"},"NUMB":{"string":"000003"},"NAME":{"string":"TTTTT               "},"ADDRX":{"string":"XXX                 "},"PHONE":{"string":"333-333 "},"DATEX":{"string":"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"},"AMOUNT":{"string":"$3333.00"},"COMMENT":{"string":"CCCCC    "}}:5
{"NUMB":{"string":"000004"}}:6  {"STAT":{"string":"A"},"NUMB":{"string":"000004"},"NAME":{"string":"DDDDD               "},"ADDRX":{"string":"DDD                 "},"PHONE":{"string":"444444  "},"DATEX":{"string":"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"},"AMOUNT":{"string":"$4444.00"},"COMMENT":{"string":"DDDD     "}}:5
{"NUMB":{"string":"000100"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"000100"},"NAME":{"string":"S. D. BORMAN        "},"ADDRX":{"string":"SURREY, ENGLAND     "},"PHONE":{"string":"32156778"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0100.11"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"000102"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"000102"},"NAME":{"string":"J. T. CZAYKOWSKI    "},"ADDRX":{"string":"WARWICK, ENGLAND    "},"PHONE":{"string":"98356183"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$1111.11"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"000104"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"000104"},"NAME":{"string":"M. B. DOMBEY        "},"ADDRX":{"string":"LONDON,ENGLAND      "},"PHONE":{"string":"12846293"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0999.99"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"000106"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"000106"},"NAME":{"string":"A. I. HICKSON       "},"ADDRX":{"string":"CROYDON, ENGLAND    "},"PHONE":{"string":"19485673"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0087.71"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"000111"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"000111"},"NAME":{"string":"ALAN TULIP          "},"ADDRX":{"string":"SARATOGA,CALIFORNIA "},"PHONE":{"string":"46120753"},"DATEX":{"string":"01 02 74"},"AMOUNT":{"string":"$0111.11"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"000762"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"000762"},"NAME":{"string":"SUSAN MALAIKA       "},"ADDRX":{"string":"SAN JOSE,CALIFORNIA "},"PHONE":{"string":"22312121"},"DATEX":{"string":"01 06 74"},"AMOUNT":{"string":"$0000.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"000983"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"000983"},"NAME":{"string":"J. S. TILLING       "},"ADDRX":{"string":"WASHINGTON, DC      "},"PHONE":{"string":"34512120"},"DATEX":{"string":"21 04 75"},"AMOUNT":{"string":"$9999.99"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"001222"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"001222"},"NAME":{"string":"D.J.VOWLES          "},"ADDRX":{"string":"BOBLINGEN, GERMANY  "},"PHONE":{"string":"70315551"},"DATEX":{"string":"10 04 73"},"AMOUNT":{"string":"$3349.99"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"001781"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"001781"},"NAME":{"string":"TINA J YOUNG        "},"ADDRX":{"string":"SINDELFINGEN,GERMANY"},"PHONE":{"string":"70319990"},"DATEX":{"string":"21 06 77"},"AMOUNT":{"string":"$0009.99"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"003210"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"003210"},"NAME":{"string":"B.A. WALKER         "},"ADDRX":{"string":"NICE, FRANCE        "},"PHONE":{"string":"12345670"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$3349.99"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"003214"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"003214"},"NAME":{"string":"PHIL CONWAY         "},"ADDRX":{"string":"SUNNYVALE, CAL.     "},"PHONE":{"string":"34112120"},"DATEX":{"string":"00 06 73"},"AMOUNT":{"string":"$0009.99"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"003890"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"003890"},"NAME":{"string":"BRIAN HARDER        "},"ADDRX":{"string":"NICE, FRANCE        "},"PHONE":{"string":"00000000"},"DATEX":{"string":"28 05 74"},"AMOUNT":{"string":"$0009.99"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"004004"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"004004"},"NAME":{"string":"JANET FOUCHE        "},"ADDRX":{"string":"DUBLIN, IRELAND     "},"PHONE":{"string":"71112121"},"DATEX":{"string":"02 11 73"},"AMOUNT":{"string":"$1259.99"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"004445"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"004445"},"NAME":{"string":"DR. P. JOHNSON      "},"ADDRX":{"string":"SOUTH BEND, S.DAK.  "},"PHONE":{"string":"61212120"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0009.99"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"004878"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"004878"},"NAME":{"string":"ADRIAN JONES        "},"ADDRX":{"string":"SUNNYVALE, CALIF.   "},"PHONE":{"string":"32212120"},"DATEX":{"string":"10 06 73"},"AMOUNT":{"string":"$5399.99"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"005005"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"005005"},"NAME":{"string":"A. E. DALTON        "},"ADDRX":{"string":"SAN FRANCISCO, CA.  "},"PHONE":{"string":"00000001"},"DATEX":{"string":"01 08 73"},"AMOUNT":{"string":"$0009.99"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"005444"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"005444"},"NAME":{"string":"ROS READER          "},"ADDRX":{"string":"SARATOGA, CALIF.    "},"PHONE":{"string":"67712120"},"DATEX":{"string":"20 10 74"},"AMOUNT":{"string":"$0809.99"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"005581"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"005581"},"NAME":{"string":"PETE ROBBINS        "},"ADDRX":{"string":"BOSTON, MASS.       "},"PHONE":{"string":"41312120"},"DATEX":{"string":"11 04 74"},"AMOUNT":{"string":"$0259.99"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"006016"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"006016"},"NAME":{"string":"SIR MICHAEL ROBERTS "},"ADDRX":{"string":"NEW DELHI, INDIA    "},"PHONE":{"string":"70331211"},"DATEX":{"string":"21 05 74"},"AMOUNT":{"string":"$0009.88"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"006670"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"006670"},"NAME":{"string":"IAN HALL            "},"ADDRX":{"string":"NEW YORK, N.Y.      "},"PHONE":{"string":"21212120"},"DATEX":{"string":"31 01 75"},"AMOUNT":{"string":"$3509.88"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"006968"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"006968"},"NAME":{"string":"J.A.L. STAINFORTH   "},"ADDRX":{"string":"WARWICK, ENGLAND    "},"PHONE":{"string":"56713821"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0009.88"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"007007"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"007007"},"NAME":{"string":"ANDREW WHARMBY      "},"ADDRX":{"string":"STUTTGART, GERMANY  "},"PHONE":{"string":"70311000"},"DATEX":{"string":"10 10 75"},"AMOUNT":{"string":"$5009.88"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"007248"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"007248"},"NAME":{"string":"M. J. AYRES         "},"ADDRX":{"string":"REDWOOD CITY, CALF. "},"PHONE":{"string":"33312121"},"DATEX":{"string":"11 10 75"},"AMOUNT":{"string":"$0009.88"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"007779"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"007779"},"NAME":{"string":"MRS. A. STEWART     "},"ADDRX":{"string":"SAN JOSE, CALIF.    "},"PHONE":{"string":"41512120"},"DATEX":{"string":"03 01 75"},"AMOUNT":{"string":"$0009.88"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"009000"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"009000"},"NAME":{"string":"P. E. HAVERCAN      "},"ADDRX":{"string":"WATERLOO, ONTARIO   "},"PHONE":{"string":"09876543"},"DATEX":{"string":"21 01 75"},"AMOUNT":{"string":"$9000.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"100000"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"100000"},"NAME":{"string":"M. ADAMS            "},"ADDRX":{"string":"TORONTO, ONTARIO    "},"PHONE":{"string":"03415121"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0010.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"111111"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"111111"},"NAME":{"string":"C. BAKER            "},"ADDRX":{"string":"OTTAWA, ONTARIO     "},"PHONE":{"string":"51212003"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0011.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"200000"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"200000"},"NAME":{"string":"S. P. RUSSELL       "},"ADDRX":{"string":"GLASGOW,  SCOTLAND  "},"PHONE":{"string":"63738290"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0020.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"222222"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"222222"},"NAME":{"string":"DR E. GRIFFITHS     "},"ADDRX":{"string":"FRANKFURT, GERMANY  "},"PHONE":{"string":"20034151"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0022.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"300000"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"300000"},"NAME":{"string":"V. J. HARRIS        "},"ADDRX":{"string":"NEW YORK, U.S.      "},"PHONE":{"string":"64739801"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0030.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"333333"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"333333"},"NAME":{"string":"J.D. HENRY          "},"ADDRX":{"string":"CARDIFF, WALES      "},"PHONE":{"string":"78493020"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0033.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"400000"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"400000"},"NAME":{"string":"C. HUNT             "},"ADDRX":{"string":"MILAN, ITALY        "},"PHONE":{"string":"25363738"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0040.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"444444"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"444444"},"NAME":{"string":"D. JACOBS           "},"ADDRX":{"string":"CALGARY, ALBERTA    "},"PHONE":{"string":"77889820"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0044.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"500000"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"500000"},"NAME":{"string":"P. KINGSLEY         "},"ADDRX":{"string":"MADRID, SPAIN       "},"PHONE":{"string":"44454640"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0000.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"555555"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"555555"},"NAME":{"string":"S.J. LAZENBY        "},"ADDRX":{"string":"KINGSTON, N.Y.      "},"PHONE":{"string":"39944420"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0005.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"600000"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"600000"},"NAME":{"string":"M.F. MASON          "},"ADDRX":{"string":"DUBLIN, IRELAND     "},"PHONE":{"string":"12398780"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0010.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"666666"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"666666"},"NAME":{"string":"R. F. WALLER        "},"ADDRX":{"string":"LA HULPE, BRUSSELS  "},"PHONE":{"string":"42983840"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0016.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"700000"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"700000"},"NAME":{"string":"M. BRANDON          "},"ADDRX":{"string":"DALLAS, TEXAS       "},"PHONE":{"string":"57984320"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0002.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"777777"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"777777"},"NAME":{"string":"L.A. FARMER         "},"ADDRX":{"string":"WILLIAMSBURG, VIRG. "},"PHONE":{"string":"91876131"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0027.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"800000"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"800000"},"NAME":{"string":"P. LUPTON           "},"ADDRX":{"string":"WESTEND, LONDON     "},"PHONE":{"string":"24233389"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0030.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"888888"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"888888"},"NAME":{"string":"P. MUNDY            "},"ADDRX":{"string":"NORTHAMPTON, ENG.   "},"PHONE":{"string":"23691639"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0038.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"900000"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"900000"},"NAME":{"string":"D.S. RENSHAW        "},"ADDRX":{"string":"TAMPA, FLA.         "},"PHONE":{"string":"35668120"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0040.00"},"COMMENT":{"string":"*********"}}:5
{"NUMB":{"string":"999999"}}:6  {"STAT":{"string":" "},"NUMB":{"string":"999999"},"NAME":{"string":"ANJI STEVENS        "},"ADDRX":{"string":"RALEIGH, N.Y.       "},"PHONE":{"string":"84591639"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0049.00"},"COMMENT":{"string":"*********"}}:5
```

<details><summary><font color="blue">スキーマ確認</font></summary><div>
Schema RegistryからSchema id: 5をGETしてみます。

```
[root@test12 ~]# curl http://localhost:8081/schemas/ids/5
{"schema":"{\"type\":\"record\",\"name\":\"FILEA\",\"namespace\":\"value.SOURCEDB.VSAM.TEST01\",\"fields\":[{\"name\":\"STAT\",\"type\":[{\"type\":\"string\",\"logicalType\":\"CHARACTER\",\"dbColumnName\":\"STAT\",\"length\":1},\"null\"],\"doc\":\"\",\"default\":\"\"},{\"name\":\"NUMB\",\"type\":[{\"type\":\"string\",\"logicalType\":\"CHARACTER\",\"dbColumnName\":\"NUMB\",\"length\":6},\"null\"],\"doc\":\"\",\"default\":\"\"},{\"name\":\"NAME\",\"type\":[{\"type\":\"string\",\"logicalType\":\"CHARACTER\",\"dbColumnName\":\"NAME\",\"length\":20},\"null\"],\"doc\":\"\",\"default\":\"\"},{\"name\":\"ADDRX\",\"type\":[{\"type\":\"string\",\"logicalType\":\"CHARACTER\",\"dbColumnName\":\"ADDRX\",\"length\":20},\"null\"],\"doc\":\"\",\"default\":\"\"},{\"name\":\"PHONE\",\"type\":[{\"type\":\"string\",\"logicalType\":\"CHARACTER\",\"dbColumnName\":\"PHONE\",\"length\":8},\"null\"],\"doc\":\"\",\"default\":\"\"},{\"name\":\"DATEX\",\"type\":[{\"type\":\"string\",\"logicalType\":\"CHARACTER\",\"dbColumnName\":\"DATEX\",\"length\":8},\"null\"],\"doc\":\"\",\"default\":\"\"},{\"name\":\"AMOUNT\",\"type\":[{\"type\":\"string\",\"logicalType\":\"CHARACTER\",\"dbColumnName\":\"AMOUNT\",\"length\":8},\"null\"],\"doc\":\"\",\"default\":\"\"},{\"name\":\"COMMENT\",\"type\":[{\"type\":\"string\",\"logicalType\":\"CHARACTER\",\"dbColumnName\":\"COMMENT\",\"length\":9},\"null\"],\"doc\":\"\",\"default\":\"\"}]}"}
```

見にくいので整形

```
[root@test12 ~]# curl -s  http://localhost:8081/schemas/ids/5 | jq .schema | sed -e 's/^"//' -e 's/"$//' -e 's/\\//g' | jq .
{
  "type": "record",
  "name": "FILEA",
  "namespace": "value.SOURCEDB.VSAM.TEST01",
  "fields": [
    {
      "name": "STAT",
      "type": [
        {
          "type": "string",
          "logicalType": "CHARACTER",
          "dbColumnName": "STAT",
          "length": 1
        },
        "null"
      ],
      "doc": "",
      "default": ""
    },
    {
      "name": "NUMB",
      "type": [
        {
          "type": "string",
          "logicalType": "CHARACTER",
          "dbColumnName": "NUMB",
          "length": 6
        },
        "null"
      ],
      "doc": "",
      "default": ""
    },
    {
      "name": "NAME",
      "type": [
        {
          "type": "string",
          "logicalType": "CHARACTER",
          "dbColumnName": "NAME",
          "length": 20
        },
        "null"
      ],
      "doc": "",
      "default": ""
    },
    {
      "name": "ADDRX",
      "type": [
        {
          "type": "string",
          "logicalType": "CHARACTER",
          "dbColumnName": "ADDRX",
          "length": 20
        },
        "null"
      ],
      "doc": "",
      "default": ""
    },
    {
      "name": "PHONE",
      "type": [
        {
          "type": "string",
          "logicalType": "CHARACTER",
          "dbColumnName": "PHONE",
          "length": 8
        },
        "null"
      ],
      "doc": "",
      "default": ""
    },
    {
      "name": "DATEX",
      "type": [
        {
          "type": "string",
          "logicalType": "CHARACTER",
          "dbColumnName": "DATEX",
          "length": 8
        },
        "null"
      ],
      "doc": "",
      "default": ""
    },
    {
      "name": "AMOUNT",
      "type": [
        {
          "type": "string",
          "logicalType": "CHARACTER",
          "dbColumnName": "AMOUNT",
          "length": 8
        },
        "null"
      ],
      "doc": "",
      "default": ""
    },
    {
      "name": "COMMENT",
      "type": [
        {
          "type": "string",
          "logicalType": "CHARACTER",
          "dbColumnName": "COMMENT",
          "length": 9
        },
        "null"
      ],
      "doc": "",
      "default": ""
    }
  ]
}
```

簡単に上のコマンド補足しておきます。
curlでSchema Registryからスキーマ情報取得すると、schemaという1要素に文字列としてスキーマ情報が返されるようです。こんな感じで=> `{"schema":"xxx"}` このxxx部分がJSON形式で表された求めるスキーマなのですが、文字列として入っているのでダブルクォーテーションがエスケープされていたりします(バックスラッシュ付き)。
そこで、curlで取ってきた情報をjqコマンド、sedコマンドで必要な部分を抽出しています。やっているのは以下の通りです。

- curlで情報取得
- jqでschema要素の値のみ抽出
- sedで先頭/末尾のダブルクォーテーション、エスケープ文字(バックスラッシュ)を削除
- 最後にjqで整形して表示


</div></details>

<details><summary><font color="blue">参考: keyがnull</font></summary><div>
サブスクリプションの作成時に"複数のKafkaマッピング"を選択していると以下のようにkeyがnullになってしまいました。

```
[root@test12 /opt/confluent-6.2.0/bin]# ./kafka-avro-console-consumer --from-beginning --topic cdc_kafka_test01.vsamt02.sourcedb.vsam.test01.filea \
>    --bootstrap-server localhost:9092 \
>    --property print.key=true \
>    --property schema.registry.url=http://localhost:8081
null    {"STAT":{"string":"U"},"NUMB":{"string":"000001"},"NAME":{"string":"AAATTT              "},"ADDRX":{"string":"BBB                 "},"PHONE":{"string":"5555    "},"DATEX":{"string":"99      "},"AMOUNT":{"string":"$0001.00"},"COMMENT":{"string":"TTTTTT   "}}
null    {"STAT":{"string":"U"},"NUMB":{"string":"000002"},"NAME":{"string":"AAA                 "},"ADDRX":{"string":"TTT                 "},"PHONE":{"string":"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"},"DATEX":{"string":"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"},"AMOUNT":{"string":"$0001.00"},"COMMENT":{"string":"COMMENT  "}}
null    {"STAT":{"string":" "},"NUMB":{"string":"000100"},"NAME":{"string":"S. D. BORMAN        "},"ADDRX":{"string":"SURREY, ENGLAND     "},"PHONE":{"string":"32156778"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0100.11"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"000102"},"NAME":{"string":"J. T. CZAYKOWSKI    "},"ADDRX":{"string":"WARWICK, ENGLAND    "},"PHONE":{"string":"98356183"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$1111.11"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"000104"},"NAME":{"string":"M. B. DOMBEY        "},"ADDRX":{"string":"LONDON,ENGLAND      "},"PHONE":{"string":"12846293"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0999.99"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"000106"},"NAME":{"string":"A. I. HICKSON       "},"ADDRX":{"string":"CROYDON, ENGLAND    "},"PHONE":{"string":"19485673"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0087.71"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"000111"},"NAME":{"string":"ALAN TULIP          "},"ADDRX":{"string":"SARATOGA,CALIFORNIA "},"PHONE":{"string":"46120753"},"DATEX":{"string":"01 02 74"},"AMOUNT":{"string":"$0111.11"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"000762"},"NAME":{"string":"SUSAN MALAIKA       "},"ADDRX":{"string":"SAN JOSE,CALIFORNIA "},"PHONE":{"string":"22312121"},"DATEX":{"string":"01 06 74"},"AMOUNT":{"string":"$0000.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"000983"},"NAME":{"string":"J. S. TILLING       "},"ADDRX":{"string":"WASHINGTON, DC      "},"PHONE":{"string":"34512120"},"DATEX":{"string":"21 04 75"},"AMOUNT":{"string":"$9999.99"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"001222"},"NAME":{"string":"D.J.VOWLES          "},"ADDRX":{"string":"BOBLINGEN, GERMANY  "},"PHONE":{"string":"70315551"},"DATEX":{"string":"10 04 73"},"AMOUNT":{"string":"$3349.99"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"001781"},"NAME":{"string":"TINA J YOUNG        "},"ADDRX":{"string":"SINDELFINGEN,GERMANY"},"PHONE":{"string":"70319990"},"DATEX":{"string":"21 06 77"},"AMOUNT":{"string":"$0009.99"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"003210"},"NAME":{"string":"B.A. WALKER         "},"ADDRX":{"string":"NICE, FRANCE        "},"PHONE":{"string":"12345670"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$3349.99"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"003214"},"NAME":{"string":"PHIL CONWAY         "},"ADDRX":{"string":"SUNNYVALE, CAL.     "},"PHONE":{"string":"34112120"},"DATEX":{"string":"00 06 73"},"AMOUNT":{"string":"$0009.99"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"003890"},"NAME":{"string":"BRIAN HARDER        "},"ADDRX":{"string":"NICE, FRANCE        "},"PHONE":{"string":"00000000"},"DATEX":{"string":"28 05 74"},"AMOUNT":{"string":"$0009.99"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"004004"},"NAME":{"string":"JANET FOUCHE        "},"ADDRX":{"string":"DUBLIN, IRELAND     "},"PHONE":{"string":"71112121"},"DATEX":{"string":"02 11 73"},"AMOUNT":{"string":"$1259.99"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"004445"},"NAME":{"string":"DR. P. JOHNSON      "},"ADDRX":{"string":"SOUTH BEND, S.DAK.  "},"PHONE":{"string":"61212120"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0009.99"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"004878"},"NAME":{"string":"ADRIAN JONES        "},"ADDRX":{"string":"SUNNYVALE, CALIF.   "},"PHONE":{"string":"32212120"},"DATEX":{"string":"10 06 73"},"AMOUNT":{"string":"$5399.99"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"005005"},"NAME":{"string":"A. E. DALTON        "},"ADDRX":{"string":"SAN FRANCISCO, CA.  "},"PHONE":{"string":"00000001"},"DATEX":{"string":"01 08 73"},"AMOUNT":{"string":"$0009.99"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"005444"},"NAME":{"string":"ROS READER          "},"ADDRX":{"string":"SARATOGA, CALIF.    "},"PHONE":{"string":"67712120"},"DATEX":{"string":"20 10 74"},"AMOUNT":{"string":"$0809.99"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"005581"},"NAME":{"string":"PETE ROBBINS        "},"ADDRX":{"string":"BOSTON, MASS.       "},"PHONE":{"string":"41312120"},"DATEX":{"string":"11 04 74"},"AMOUNT":{"string":"$0259.99"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"006016"},"NAME":{"string":"SIR MICHAEL ROBERTS "},"ADDRX":{"string":"NEW DELHI, INDIA    "},"PHONE":{"string":"70331211"},"DATEX":{"string":"21 05 74"},"AMOUNT":{"string":"$0009.88"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"006670"},"NAME":{"string":"IAN HALL            "},"ADDRX":{"string":"NEW YORK, N.Y.      "},"PHONE":{"string":"21212120"},"DATEX":{"string":"31 01 75"},"AMOUNT":{"string":"$3509.88"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"006968"},"NAME":{"string":"J.A.L. STAINFORTH   "},"ADDRX":{"string":"WARWICK, ENGLAND    "},"PHONE":{"string":"56713821"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0009.88"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"007007"},"NAME":{"string":"ANDREW WHARMBY      "},"ADDRX":{"string":"STUTTGART, GERMANY  "},"PHONE":{"string":"70311000"},"DATEX":{"string":"10 10 75"},"AMOUNT":{"string":"$5009.88"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"007248"},"NAME":{"string":"M. J. AYRES         "},"ADDRX":{"string":"REDWOOD CITY, CALF. "},"PHONE":{"string":"33312121"},"DATEX":{"string":"11 10 75"},"AMOUNT":{"string":"$0009.88"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"007779"},"NAME":{"string":"MRS. A. STEWART     "},"ADDRX":{"string":"SAN JOSE, CALIF.    "},"PHONE":{"string":"41512120"},"DATEX":{"string":"03 01 75"},"AMOUNT":{"string":"$0009.88"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"009000"},"NAME":{"string":"P. E. HAVERCAN      "},"ADDRX":{"string":"WATERLOO, ONTARIO   "},"PHONE":{"string":"09876543"},"DATEX":{"string":"21 01 75"},"AMOUNT":{"string":"$9000.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"100000"},"NAME":{"string":"M. ADAMS            "},"ADDRX":{"string":"TORONTO, ONTARIO    "},"PHONE":{"string":"03415121"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0010.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"111111"},"NAME":{"string":"C. BAKER            "},"ADDRX":{"string":"OTTAWA, ONTARIO     "},"PHONE":{"string":"51212003"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0011.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"200000"},"NAME":{"string":"S. P. RUSSELL       "},"ADDRX":{"string":"GLASGOW,  SCOTLAND  "},"PHONE":{"string":"63738290"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0020.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"222222"},"NAME":{"string":"DR E. GRIFFITHS     "},"ADDRX":{"string":"FRANKFURT, GERMANY  "},"PHONE":{"string":"20034151"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0022.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"300000"},"NAME":{"string":"V. J. HARRIS        "},"ADDRX":{"string":"NEW YORK, U.S.      "},"PHONE":{"string":"64739801"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0030.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"333333"},"NAME":{"string":"J.D. HENRY          "},"ADDRX":{"string":"CARDIFF, WALES      "},"PHONE":{"string":"78493020"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0033.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"400000"},"NAME":{"string":"C. HUNT             "},"ADDRX":{"string":"MILAN, ITALY        "},"PHONE":{"string":"25363738"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0040.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"444444"},"NAME":{"string":"D. JACOBS           "},"ADDRX":{"string":"CALGARY, ALBERTA    "},"PHONE":{"string":"77889820"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0044.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"500000"},"NAME":{"string":"P. KINGSLEY         "},"ADDRX":{"string":"MADRID, SPAIN       "},"PHONE":{"string":"44454640"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0000.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"555555"},"NAME":{"string":"S.J. LAZENBY        "},"ADDRX":{"string":"KINGSTON, N.Y.      "},"PHONE":{"string":"39944420"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0005.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"600000"},"NAME":{"string":"M.F. MASON          "},"ADDRX":{"string":"DUBLIN, IRELAND     "},"PHONE":{"string":"12398780"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0010.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"666666"},"NAME":{"string":"R. F. WALLER        "},"ADDRX":{"string":"LA HULPE, BRUSSELS  "},"PHONE":{"string":"42983840"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0016.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"700000"},"NAME":{"string":"M. BRANDON          "},"ADDRX":{"string":"DALLAS, TEXAS       "},"PHONE":{"string":"57984320"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0002.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"777777"},"NAME":{"string":"L.A. FARMER         "},"ADDRX":{"string":"WILLIAMSBURG, VIRG. "},"PHONE":{"string":"91876131"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0027.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"800000"},"NAME":{"string":"P. LUPTON           "},"ADDRX":{"string":"WESTEND, LONDON     "},"PHONE":{"string":"24233389"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0030.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"888888"},"NAME":{"string":"P. MUNDY            "},"ADDRX":{"string":"NORTHAMPTON, ENG.   "},"PHONE":{"string":"23691639"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0038.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"900000"},"NAME":{"string":"D.S. RENSHAW        "},"ADDRX":{"string":"TAMPA, FLA.         "},"PHONE":{"string":"35668120"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0040.00"},"COMMENT":{"string":"*********"}}
null    {"STAT":{"string":" "},"NUMB":{"string":"999999"},"NAME":{"string":"ANJI STEVENS        "},"ADDRX":{"string":"RALEIGH, N.Y.       "},"PHONE":{"string":"84591639"},"DATEX":{"string":"26 11 81"},"AMOUNT":{"string":"$0049.00"},"COMMENT":{"string":"*********"}}
^CProcessed a total of 45 messages
```

Kafka的にはkeyがnullのメッセージでもよいと思いますが、Kafkaの先のTargetがRDBだと恐らくkeyがnullのケースはよろしくないと思われます。後述していますがRecordをDeleteするケースだと、特定のkey値に対してValueがnullのメッセージが飛ばされることになります。この時keyがnullだとDelete処理が反映できないということになってしまいます。

</div></details>


### ミラーリングの開始

サブスクリプションを右クリック - ミラーリングの開始を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/fd1559f4-52bb-9408-f625-a4e5674a3d17.png)

継続を選択してOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/1e047bd2-8a8a-3811-deab-d9c07ad0abe6.png)

モニタータブを開いて、指定したサブスクリプションの状態が"継続ミラーリング"になっていることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/f4fbbb6f-b266-e05e-7d1c-7f9970ee7ec5.png)

#### Insertの確認

CICS側で、当該ファイルをOpenにして当該FILEを更新する処理を実施してみます。
AMNUというCICS提供サンプルトランザクションで、以下のレコードを追加(Insert)してみます。

```
               FILE ADD               
                                      
 NUMBER:  000005                      
 NAME:    EEEEE                       
 ADDRESS: EEE                         
 PHONE:   55555                       
 DATE:    55                          
 AMOUNT:  $0055.00                    
 COMMENT: DDDDD                       
                                      
                                      
 ENTER DATA AND PRESS ENTER KEY         
```

`kafka-avro-console-consumer`コマンドを使って Topic`cdc_kafka_test01.vsamt02.sourcedb.vsam.test01.filea`のメッセージを参照してみると、以下のメッセージが追加されました。

```
{"NUMB":{"string":"000005"}}:6  {"STAT":{"string":"A"},"NUMB":{"string":"000005"},"NAME":{"string":"EEEEE               "},"ADDRX":{"string":"EEE                 "},"PHONE":{"string":"55555   "},"DATEX":{"string":"55      "},"AMOUNT":{"string":"$0055.00"},"COMMENT":{"string":"DDDDD    "}}:5
```

#### Updateの確認

CICSトランザクションからNUMBER:000001のレコードを更新(Update)してみます。

```
               FILE UPDATE      
                                
 NUMBER:  000001                
 NAME:    TTTTTT                
 ADDRESS: TTT                   
 PHONE:   9999                  
 DATE:    11                    
 AMOUNT:  $0099.00              
 COMMENT: TTTTTT                
                                
                                
 CHANGE FIELDS AND PRESS ENTER  
```

Consumerで見ると、以下のメッセージが追加されているのが確認できました。

```
{"NUMB":{"string":"000001"}}:6  {"STAT":{"string":"U"},"NUMB":{"string":"000001"},"NAME":{"string":"TTTTTT              "},"ADDRX":{"string":"TTT                 "},"PHONE":{"string":"9999    "},"DATEX":{"string":"11      "},"AMOUNT":{"string":"$0099.00"},"COMMENT":{"string":"TTTTTT   "}}:5
```

※最初の000001のメッセージは残ったまま、同じキーで新たにメッセージが追加されました。

#### Deleteの確認

CICSトランザクションからNUMBER:000005のレコードを削除(Delete)してみます。

Consumerで見ると、以下のメッセージが追加されているのが確認できました。

```
{"NUMB":{"string":"000005"}}    null
```

※この時、`kafka-avro-console-consumer`コマンドの`--property print.schema.ids=true`、`--property schema.id.separator=:` オプションははずしておくこと！そうしないとSchema IDが無いせいかヌルポでConsumerが落ちる！