Slide 1

Slide 1 text

HCL Notes で管理する AWS リソース 中野晴幸 Haruyuki Nakano @harunakano (Twitter) harunakano.blogspot.com (blog)

Slide 2

Slide 2 text

ノーツコンソーシアム会員向け Notes/Domino のデモ環境 ノーツコンソーシアムは Notes と Domino の実行環境(「デモ 環境」と呼ぶ)を会員向けに無償提供を開始 会員は本デモ環境をアプリのテストや顧客へのデモ等の用途で利 用可能 会員は Webブラウザを利用してデモ環境の生成依頼とデモ環境 の操作が可能

Slide 3

Slide 3 text

会員が操作する生成依頼の画面 デモ環境依頼アプリ 会員に公開されている「オモテ」側を HCL Domino Leap で作成

Slide 4

Slide 4 text

会員の見えないところでデモ環境を管理する Notes アプリ • デモ環境に関する各種設定の管理 • デモ環境稼働インフラへの要求(作成/削除等) • デモ環境の状態と履歴の保存

Slide 5

Slide 5 text

デモ環境が稼働するインフラ AWS

Slide 6

Slide 6 text

デモ環境稼働インフラへの 要求のフロー デモ環境 自動生成 依頼アプリ ノーツコンソーシアム会員 オモテ ウラ デモ環境 稼働インフラ HCL Domino Leap AWS HCL Domino

Slide 7

Slide 7 text

本日の本題 ウラ デモ環境 稼働インフラ ここ AWS へ要求する部分を プログラミング AWS HCL Domino

Slide 8

Slide 8 text

AWS への要求とは • リソースの作成/削除 ec2 create-vpc ec2 run-instances cloudformation create-stack • リソースの一覧の取得 ec2 describe-instances • 特定のリソースの情報の取得 ec2 describe-instances –instance-id <インスタンスID> ec2 get-password-data –instance-id <インスタンスID>

Slide 9

Slide 9 text

AWS マネジメントコンソールを使わず Notes アプリから AWS へ要求する手段 • コマンドラインツール AWS の API をコマンドラインから操作できるようにするツール AWS CLI, PowerShell Tools等 • AWS SDK AWS のサービスをプログラムなどから操作できるようにするための開発キット C++, Java, JavaScript等 • API オペレーション 「https:/weather.acme.com/?country=jp&city=tokyo」と要求すると 「{“date”: “2022/12/08”, “forecasts”: “sunny”}」などと返すような仕組み

Slide 10

Slide 10 text

(脳内ひとりごと) • コマンドラインツールはインストール必要。ツールのバージョン管 理はしたくないし実行環境が固定されるし、コマンドファイルの扱 いは環境依存のコードになりがち… • SDK の Java で作ると Nomad で使えない ※Nomad には Java の実行環境がない • API オペレーションは NotesHTTPRequest クラスが活用できるし、 そうすれば Windows 版クライアントやサーバーだけでなく Mac 版クライアントやスマホ(Nomad Mobile)でも実行できそう

Slide 11

Slide 11 text

AWS マネジメントコンソールを使わず Notes アプリから AWS へ要求する手段 • コマンドラインツール • AWS SDK • API オペレーション LotusScript で作りました!!

Slide 12

Slide 12 text

API オペレーションのドキュメント API リファレンス 利用する AWS サービスの ドキュメントにある 「API リファレンス」 を参照

Slide 13

Slide 13 text

API オペレーションでアクション要求時に 指定するパラメータ ※日本語化されてないドキュメントもあります

Slide 14

Slide 14 text

AWS リソースを自動で構築できる便利なサービス CloudFormation デモ環境として構築するAWS環境を「テンプレート化」 AWS環境を「スタック」という単位で管理 利用料は無料(ただし使用するリソース分の料金はかかる)

Slide 15

Slide 15 text

CloudFormation の概要 テンプレートとスタック CloudFormation テンプレート パラメータ EC2 インスタンス Route53 DNSレコード スタック

Slide 16

Slide 16 text

CloudFormation のアクション CreateStack CloudFormation テンプレート スタック1 スタック2

Slide 17

Slide 17 text

テンプレートの作成 CloudFormation のアクション「CreateStack(ス タック作成)」で使用するテンプレートの作成

Slide 18

Slide 18 text

CloudFormation Designer テンプレートの作成 新規作成したテンプレートの S3 への保存や、既存テンプ レートの編集が可能

Slide 19

Slide 19 text

CloudFormation テンプレートの作成(1) 今回作成したテンプレートの構成要素 AWSTemplateFormatVersion: テンプレートのバージョン Parameters: 実行時に入力するパラメータ Resources: スタックを構成するリソース等 ※テンプレートは JSON、YAML形式で作成可能、今回は YAML で記述

Slide 20

Slide 20 text

CloudFormation テンプレートの作成(2) 「Parameters:」(一部抜粋) InstanceType: Description: EC2 Instance type Type: String Default: t2.large パラメータの「キー」や入力時にパラメータを省略した 場合のデフォルト値などを指定

Slide 21

Slide 21 text

CloudFormation テンプレートの作成(3) 「Resources:」の例 EC2Instance: Type: AWS::EC2::Instance Properties: ImageId: !Ref AMIID InstanceType: !Ref InstanceType KeyName: !Ref KeyPair NetworkInterfaces: - GroupSet: - !Ref SecurityGroupID AssociatePublicIpAddress: true DeviceIndex: 0 DeleteOnTermination: true SubnetId: !Ref SubnetID Route53RecordSet: Type: AWS::Route53::RecordSet Properties: HostedZoneName: !Join [".", [!Ref HostedZoneName, ""] ] Comment: A record for instance Name: !Join [".", [!Ref AWS::StackName, !Ref HostedZoneName, ""] ] Type: A TTL: !Sub ${TTL} ResourceRecords: - !GetAtt EC2Instance.PublicIp • Notes と Domino が入ったイメージ(AMI)が作成済みで、 それを使用して EC2 インスタンスを作成 • ユーザーが分かりやすいホスト名で EC2 インスタンスへア クセスできるよう、 DNS レコードを Route53 へ追加

Slide 22

Slide 22 text

API オペレーションで アクションを要求する アクションを要求するプログラムを作ります

Slide 23

Slide 23 text

LotusScript で NotesHTTPRequest クラスを使用した アクション要求のイメージ Dim ss as New NotesSession Dim req as NotesHTTPRequest Dim res as NotesJSONNavigator set req = ss.CreateHTTPRequest() req.PreferJSONNavigator = True req.Setheaderfield “headerItem”, “headerValue” set res = req.Get( "url" ) If 0 = InStr( req.Responsecode, "200" ) Then Print "Error" End If よくある LotusScript のパターンが そのまま使えるんでしょ? と考えてましたが…

Slide 24

Slide 24 text

LotusScript で NotesHTTPRequest クラスを使用した アクション要求のイメージ Dim ss as New NotesSession Dim req as NotesHTTPRequest Dim res as NotesJSONNavigator set req = ss.CreateHTTPRequest() req.PreferJSONNavigator = True req.Setheaderfield "headerItem", "headerValue" set res = req.Get( "url" ) If 0 = InStr( req.Responsecode, "200" ) Then Print "Error" End If AWS は甘くなかった… orz

Slide 25

Slide 25 text

アクション要求 の前処理 AWS のサービスへ API オペレーションでアク ションを要求する際に必要な「署名」とは

Slide 26

Slide 26 text

アクションを要求するために 認証情報が必要 アクションを要求したユーザーを AWS が特定するため認証情報 を渡す必要がある 【参考】認証情報を渡す際に使用される方法(AWS 以外): • HTTP ヘッダー “Authorization:” にユーザー名とパスワードをコロンでつなげ た値を base64 エンコードしてできた文字列をセットする • ユーザー名とパスワードを本文にセットし、POST メソッドで要求すると返って くる「認証トークン」を保持しておき、次回以降のアクション要求時に HTTP ヘッダー “Authorization: ” へセットする

Slide 27

Slide 27 text

AWS CLI や SDK では自動で行われている リクエストの署名 • リクエストを送るとき、API リクエストの送信者を AWS が特 定できるようリクエストに署名する • 署名する際に「AWS アクセスキー」を使用する • 一部のAPIオペレーションは署名が不要のものもある

Slide 28

Slide 28 text

【参考】 AWS アクセスキー • AWS の各サービスに対して、プログラムからのアクセスを認 証するために作成される認証キー • AWS アクセスキーは次の2つで構成されている • アクセスキーID • シークレットアクセスキー

Slide 29

Slide 29 text

【参考】 リクエストに署名する理由 • リクエスタのIDの確認 署名することで有効なアクセスキーを持っている人がリクエストを送ったことを確認できる • 送信中のデータの保護 送信中のリクエストの改ざんを防ぐため、リクエスト要素からリクエストのハッシュを計算し、得ら れたハッシュをリクエストの一部として含む。AWS は受け取ったリクエストからハッシュを計算しリ クエストにあるハッシュ値と比較する。不一致の場合、リクエストを拒否する。 • 潜在的リプレイ攻撃の防止 リクエストは、リクエストのタイムスタンプの5分以内に AWS に到達する必要がある。時間を過ぎて いた場合、リクエストを拒否する

Slide 30

Slide 30 text

API オペレーションでは計算が必須 AWS 署名バージョン 4 の署名 署名作成のタスク: 1. 正規リクエストの作成 2. 署名文字列の作成 3. 署名の計算 4. リクエストへの署名の追加 https://docs.aws.amazon.com/ja_jp/general/latest/gr/sigv4_signing.html

Slide 31

Slide 31 text

AWS 署名バージョン 4 の署名 > 署名作成のタスク 1. 正規リクエストの作成 正規リクエストは、以下を改行で区切って連結した文字列: (1) HTTP リクエストメソッド GET、PUT、POSTなど (2) 正規 URI パラメータ / ※空の場合はスラッシュを指定 (3) 正規クエリ文字列 ※後述 (4) 正規ヘッダー 署名に含める HTTP ヘッダーのリスト ヘッダー名:小文字に変換、前後にあるスペースを除去 ヘッダー値:連続するスペースを単一のスペースに変換 ヘッダー名、コロン(:)、ヘッダー値、改行文字の順に正規ヘッダーへ追加 (5) 署名に含めるヘッダー 正規ヘッダーに含めたヘッダーのリスト すべてのヘッダー名を小文字に変換、文字コードでソート、ヘッダー名をセミコロンで区切る (6) ペイロードのハッシュ値 リクエストの本文のペイロードから作成したハッシュ値 署名文字列を作成するとき、ペイロードのハッシュに使用した署名アルゴリズムを指定 ※SHA256を使用した場合、署名アルゴリズムとして “AWS4-HMAC-SHA256” を指定 ペイロードのハッシュ値は、小文字の16進文字列で表わす必要あり

Slide 32

Slide 32 text

AWS 署名バージョン 4 の署名 > 署名作成のタスク > 1. 正規リクエストの作成 (3). 正規クエリ文字列 クエリ文字列(例): ※実際のクエリ文字列は改行しません Action=CreateStack& Parameters.member.1.ParameterKey=InstanceType& Parameters.member.1.ParameterValue=t3.large& Parameters.member.2.ParameterKey=AMIID& Parameters.member.2.ParameterValue=ami-000000aaaa00aaaa0& StackName=UserShortName01a& TemplateURL=https%3A%2F%2Fs3-ap-northeast-1.amazonaws.com%2Fcf-templates-ap-northeast-1%2Fcf.domino1201FP1.xxxx& Version=2010-05-15 正規クエリへ追加するパラメータ(例): • すべてのアクションに共通して必要なパラメータは”Action”と”Version”の2つ(青太字) • アクション「CreateStack」に必要なパラメータは“StackName”のみ(赤太字) • CloudFormation テンプレートのURL(上記は AWS S3 にアップロード済み)を”TemplateURL”で示す(黒太字) • CloudFormation テンプレートへ渡すパラメータのキーを ”Parameters.member.n.ParameterKey”、 値 を ”Parameters.member.n.ParameterValue” で始まるパラメータで示す。※nは数字

Slide 33

Slide 33 text

【参考】 必須パラメータ(共通)

Slide 34

Slide 34 text

【参考】 必須パラメータ(CreateStack)

Slide 35

Slide 35 text

AWS 署名バージョン 4 の署名 > 署名作成のタスク > 1. 正規リクエストの作成 (3). 正規クエリ文字列 クエリ文字列(例): ※実際のクエリ文字列は改行しません Action=CreateStack& Parameters.member.1.ParameterKey=InstanceType& Parameters.member.1.ParameterValue=t3.large& Parameters.member.2.ParameterKey=AMIID& Parameters.member.2.ParameterValue=ami-000000aaaa00aaaa0& StackName=UserShortName01a& TemplateURL=https%3A%2F%2Fs3-ap-northeast-1.amazonaws.com%2Fcf-templates-ap-northeast-1%2Fcf.domino1201FP1.xxxx& Version=2010-05-15 正規クエリ文字列の作成ルール: a. パラメータ名(上記太字)は、文字コードの昇順にソートする b. 各パラメータ名と値を URI エンコードする c. URI エンコードしたパラメータ名、等号文字(=)、URI エンコードしたパラメータ値の順で正規クエリ文字列へ追加する d. パラメータとパラメータの間にアンパサンド文字(&)を追加する

Slide 36

Slide 36 text

AWS 署名バージョン 4 の署名 > 署名作成のタスク > 1. 正規リクエストの作成 (6). ペイロードのハッシュ値 ハッシュ値を求めるサンプルコード(Java) ※ハッシュアルゴリズムに SHA-256 を指定 public static String getHashedString( String orgString ) throws Exception { String hashedStr = ""; MessageDigest md = MessageDigest.getInstance("SHA-256"); md.update(orgString.getBytes()); byte[] cipher_byte = md.digest(); StringBuilder sb = new StringBuilder(2 * cipher_byte.length); for(byte b: cipher_byte) { sb.append(String.format("%02x", b&0xff) ); } hashedStr = sb.toString(); return hashedStr; }

Slide 37

Slide 37 text

【参考】 ハッシュ化と暗号化の違い ハッシュ化 元に戻せない(不可逆) ハッシュ関数:MD5, SHA1, SHA256など 暗号化 元に戻せる(復号化)

Slide 38

Slide 38 text

AWS 署名バージョン 4 の署名 > 署名作成のタスク 1. 正規リクエストの作成 正規リクエスト(例): GET / Action=CreateStack&Parameters.member.1.ParameterKey=InstanceType&Parameters.member.1.ParameterValue=t3.large&Parameters.me mber.2.ParameterKey=AMIID&Parameters.member.2.ParameterValue=ami -000000aaaa00aaaa0&StackName=UserShortName01a&Template URL=https%3A%2F%2Fs3-ap-northeast-1.amazonaws.com%2Fcf-templates-ap-northeast-1%2Fcf.domino1201FP1.xxxx&Version=2010-05- 15 host:cloudformation.ap-northeast-1.amazonaws.com x-amz-date:20221208T065641Z host;x-amz-date e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 ペイロードは空っぽでもハッシュ値は生成される

Slide 39

Slide 39 text

AWS 署名バージョン 4 の署名 > 署名作成のタスク 2. 署名文字列の作成 署名文字列は、以下を改行で区切って連結した文字列: 1 アルゴリズム 正規リクエストでダイジェストの計算に使用しているハッ シュアルゴリズム ※ SHA256 では AWS4-HMAC-SHA256 2 リクエスト日時 リクエストを要求する日時 ISO8601形式を使用、正規リクエストの作成で使用した値と同じ 3 認証情報スコープ 日付、対象とするリージョン、リクエストしているサービス、 小文字の終了文字列(”aws4_request”)をスラッシュ文字で 区切った文字列 4 正規リクエストのハッシュ 1つ前のタスク「1. 正規リクエストの作成」で作成した正規 リクエストのハッシュ値 ※ハッシュ値を求めるコードは「(6).ペーロードのハッシュ値」を使用

Slide 40

Slide 40 text

AWS 署名バージョン 4 の署名 > 署名作成のタスク 2. 署名文字列の作成 署名文字列(例): AWS4-HMAC-SHA256 20221208T065641Z 20221208/ap-northeast-1/cloudformation/aws4_request bc16905d349cb24baf05fd74aed5c6a49f6755eb23a45a7cda94a97c485acf2c

Slide 41

Slide 41 text

AWS 署名バージョン 4 の署名 > 署名作成のタスク 3. 署名の計算 ① 署名キーの取得: シークレットアクセスキーを使い、認証情報スコープで使用した値(日付、対象 とするリージョン、リクエストしているサービス、小文字の終了文字列)につい てハッシュを計算する ② 署名の計算: 取得した署名キーと1つ前のタスク「2. 署名文字列の作成」で作成した署名文 字列を使用してハッシュを計算し、バイナリ値を16進表現へ変換する

Slide 42

Slide 42 text

AWS 署名バージョン 4 の署名 > 署名作成のタスク > 3. 署名の計算 ①. 署名キーの取得 署名キーを得るための疑似コード: HMAC( HMAC( HMAC( HMAC( "AWS4" + “SampleSecretAccessKey”, "20221208" ), “ap-northeast-1“ ), “cloudformation“ ), "aws4_request“ ) 【HMAC】 Hash Based Message Authentication Code の略で 暗号鍵とハッシュ関数を組み合わせて不可逆 メッセージを生成する、メッセージ認証の暗号 化技術のひとつ

Slide 43

Slide 43 text

AWS 署名バージョン 4 の署名 > 署名作成のタスク > 3. 署名の計算 ②. 署名の計算 署名を得るための疑似コード: HexEncode( HMAC( 前頁<①. 署名キーの取得>で得た署名キー, タスク<2. 署名文字列の作成>で得た署名文字列 ) ) HexEncode はバイナリ値を16進表現に変換する

Slide 44

Slide 44 text

【参考】①②のコードサンプル 署名の計算(Java) static byte[] HmacSHA256(String data, byte[] key) throws Exception { String algorithm="HmacSHA256"; final SecretKeySpec keySpec = new SecretKeySpec(key, algorithm); final Mac mac = Mac.getInstance(algorithm); mac.init(keySpec); return mac.doFinal(data.getBytes("UTF-8")); } static byte[] getSignatureKey(String key, String dateStamp, String regionName, String serviceName) throws Exception { byte[] kSecret = ("AWS4" + key).getBytes("UTF-8"); byte[] kDate = HmacSHA256(dateStamp, kSecret); byte[] kRegion = HmacSHA256(regionName, kDate); byte[] kService = HmacSHA256(serviceName, kRegion); byte[] kSigning = HmacSHA256("aws4_request", kService); return kSigning; } public static String getHashedSignature(String key, String dateStamp, String regionName, String serviceName, String stringToSign) throws Exception { String signature = ""; byte[] signatureKey = getSignatureKey(key, dateStamp, regionName, serviceName); byte[] signatureByte = HmacSHA256(stringToSign, signatureKey); BigInteger bi = new BigInteger(1, signatureByte); signature = String.format("%0" + (signatureByte.length << 1) + "x", bi); return signature; }

Slide 45

Slide 45 text

AWS 署名バージョン 4 の署名 > 署名作成のタスク 3. 署名の計算 署名(例): bfe81de8b4f4b85cda4418d9eafd3bb6269808ab0f029e2dff5970de5736c8ec 前ページの Java コードを LS2J で呼び出して署名を計算させる(LotusScript) UseLSX "*javacon" Use "hashLib" Dim js As New javasession Dim jc As JavaClass Dim jo As JavaObject Set jc = js.Getclass("HashLib") Set jo = jc.Createobject signature = jo.getHashedSignature( AWS_SECRET_ACCESS_KEY, dateStamp, regionName, service, StringToSign )

Slide 46

Slide 46 text

AWS 署名バージョン 4 の署名 > 署名作成のタスク 4. リクエストへの署名の追加 署名をリクエストに追加する方法(どちらか一方) • HTTP ヘッダー(Authorization) • クエリ文字列 ※「https://○△□.com/?●=▲」の?以降の文字列

Slide 47

Slide 47 text

AWS 署名バージョン 4 の署名 > 署名作成のタスク 4. リクエストへの署名の追加 署名をリクエストに追加する方法(どちらか一方) • HTTP ヘッダー(Authorization) • クエリ文字列 ※「https://○△□.com/?●=▲」の?以降の文字列

Slide 48

Slide 48 text

AWS 署名バージョン 4 の署名 > 署名作成のタスク 4. リクエストへの署名の追加 Authorization ヘッダーの構成: Authorization: アルゴリズム Credential=アクセスキーID/認証情報スコープ, SignedHeaders=署名付きヘッダー, Signature=署名 アルゴリズムと credential の間にカンマはないが、SignedHeaders と Signature は前の値とカンマで区切る アルゴリズム AWS4-HMAC-SHA256 アクセスキーID/認証情報スコープ AKIDEXAMPLE/20221019/ap-northeast-1/cloudformation/aws4_request 署名付きヘッダー host;x-amz-date 署名 bfe81de8b4f4b85cda4418d9eafd3bb6269808ab0f029e2dff5970de5736c8ec

Slide 49

Slide 49 text

アクションの要求 AWS のサービスへ API オペレーションでアク ションを要求する

Slide 50

Slide 50 text

リクエストの送信先 AWS サービスエンドポイント サービスエンドポイントの一般的な構文: サービスコード.リージョンコード.amazonaws.com 例えば https://cloudformation.ap-northeast-1.amazonaws.com はアジアパシフィック(東京)の CloudFormation サービスのエンドポイントです サービスコード 「CloudFormation」のサービスコードは “cloudformation” リージョンコード 「アジアパシフィック(東京)」のリージョンコードは ”ap-northeast-1” ※リージョンコードを含まない(あるいはサポートされていない)サービス もある

Slide 51

Slide 51 text

リクエストの内容をサービスへ伝える クエリ文字列 HTTP リクエストのURL: プロトコル://AWS サービスエンドポイント/?クエリ文字列 URL(例): ※クエリ文字列の詳細は署名作成のタスク「1. 正規リクエストの作成 > (3).正規クエリ文字列」を参照 https://cloudformation.ap-northeast-1.amazonaws.com/ ?Action=CreateStack &Parameters.member.1.ParameterKey=InstanceType &Parameters.member.1.ParameterValue=t3.large &Parameters.member.2.ParameterKey=AMIID &Parameters.member.2.ParameterValue=ami-000000aaaa00aaaa0 &StackName=UserShortName01a &TemplateURL=https%3A%2F%2Fs3-ap-northeast-1.amazonaws.com%2Fcf-templates-ap-northeast-1%2Fcf.domino1201FP1.xxxx &Version=2010-05-15

Slide 52

Slide 52 text

HTTP リクエストのヘッダー Authorization 署名作成のタスク「4.リクエストへの署名の追加」参照 Host リクエストの送信先となる「AWS サービスエンドポイント」 X-Amz-Date 署名の作成に使用する日時

Slide 53

Slide 53 text

LotusScript で NotesHTTPRequest クラスを使用した アクション要求のコード(例) Sub httpReq( url, hAuthorization$, hHost$, hDate$ ) Dim ss as New NotesSession Dim req as NotesHTTPRequest Dim nav as NotesJSONNavigator set req = ss.CreateHTTPRequest() req.PreferJSONNavigator = True req.SetHeaderField “Authorization”, hAuthorization req.SetHeaderField “Host”, hHost req.SetHeaderField “X-Amz-Date”, hDate set nav = req.Get( url ) ‘※以降の処理は「レスポンスの処理」へつづく End Sub 3つの HTTP リクエストヘッダーをセットする (Authorization, Host, X-Amz-Date) HTTPリクエストのレスポンスがJSON形式のとき PreferJSONNavigator プロパティに True を設定する ※ PregerJSONNavigator は 10.0.1 FP2 以降のバージョンで使用可能 Get メソッドで要求し、レスポンスをセットする NotesHTTPRequest クラスと NotesJSONNavigator クラスは 10.0.1 以降のバージョンで使用可能

Slide 54

Slide 54 text

レスポンスの処理 AWS への要求に対する応答を処理します

Slide 55

Slide 55 text

HTTP リクエストの レスポンスコード set nav = req.Get( url ) If 0 = InStr( req.ResponseCode, “200” ) Then Print “失敗しました:” & req.Responsecode End If ResponseCode プロパティには、 Get メソッドが成功すると “HTTP/1.1 200 OK“ がセットされます。 署名の日付が不一致だったり、AWS への認証で拒否されたり、指定 したアクションが無効だったなど Get メソッドが失敗した場合は "HTTP/1.1 400 Bad Request" や "HTTP/1.1 403 Forbidden" の ように “200” が含まれない。

Slide 56

Slide 56 text

アクション「CreateStack」を要求して返される JSON形式のレスポンス(例) { “CreateStackResponse”:{ “CreateStackResult”:{ “StackId”:“arn:aws:cloudformation:ap-northeast-1:415468486598:stack/UserShor tName01a/a12345a1-1234-12ab-ab12-12abc123456a“ }, ”ResponseMetadata”:{ “RequestId”:“2a1fea35-a27d-41fb-b5c0-7c16dbfdaf49“ } } } { “Error”:{ “Code”:“AlreadyExistsException”, “Message”:“Stack [UserShortName01a] already exists”, “Type”:“Sender“ }, "RequestId":"9d0b9099-231d-4dd5-a425-016dc06d5da2“ } 成功した場合 失敗した場合

Slide 57

Slide 57 text

JSON データの解析に使用するクラス NotesJSONNavigator Dim nav as NotesJSONNavigator : req.PreferJSONNavigator = True : set nav = req.Get( url ) : ‘※次ページへつづく HTTP リクエストのレスポンスが JSON で戻るため NotesJSONNavigator へセットする

Slide 58

Slide 58 text

JSON 上の特定の位置にある要素の値を取得するクラス NotesJSONElement Dim elm As NotesJSONElement Dim pointer As String Dim stackId As String pointer = "/CreateStackResponse/CreateStackResult/StackId" Set elm = nav.GetElementByPointer( pointer ) If elm Is Nothing Then Print "ポインタ「" & pointer & "」が見つかりません。" Else stackId = elm.Value End If 指定したポインタにある要素を NotesJSONElement へセット JSON 上のポインタ JSON オブジェクトに特定のポインタがあれば、その値を保持する NotesJSONElement クラスは 10.0.1 以降のバージョンで使用可能

Slide 59

Slide 59 text

アクション要求によっては HTTP リクエストが エラーになる?! req.PreferJSONNavigator = True set nav = req.Get( url ) ここでエラー

Slide 60

Slide 60 text

アクション「DescribeInstances」を要求して返される XML形式のレスポンス(例) 040cb45c-2e5d-4980-96fd-334330e22ddd i-05c35fb2b5d6c97e5 10.0.101.60 43.206.101.248

Slide 61

Slide 61 text

XML ? JSON ? 戻り値の型はドキュメントに記載なし?! (苦し紛れの)コード Dim ret As Variant : req.PreferStrings = False req.PreferJSONNavigator = False ret = req.Get( url ) : If isArray( ret ) Then set nav = ss.CreateJSONNavigator( ret ) response = ret.Stringify() Else response = ret End If : Exit Sub Stringify メソッドは 11.0 以降のバージョンで使用可能 PreferJSONNavigator が False の場合に JSON が戻るとバイト配列がセットされた XML が戻ると文字列がセットされた 【注意】 上のコードは筆者の環境では動作しますが、決してお勧めしません。事前に戻り値のタイプ を調べ、戻り値が適切なデータ型にセットされるコードを書きましょう

Slide 62

Slide 62 text

戻り値の型に関する Document は無い?けれど常に JSON で返せますか...? リクエストヘッダーに Accept: application/json をセットすると JSON で返す、といった 情報が某海外QAサイトにあったので アクション DescribeInstances で試したところ XML が戻りました...残念!!!

Slide 63

Slide 63 text

XML データの解析に使用するクラス NotesDOMParser https://help.hcltechsw.com/dom_designer/12.0.2/basic/H_EXAMPLES_NOTESDOMPARSER_CLASS_EX.html XMLから任意のタグにある値を抽出したいとき、このペー ジにあるコードのサンプルが非常に参考になります

Slide 64

Slide 64 text

まとめ

Slide 65

Slide 65 text

API オペレーションで要求するときに 注意すること • アクションの戻り値の型をよく確認しましょう • NotesHTTPRequest や NotesJSONNavigator などの新しめ のクラスを使用する場合、不具合や制限についての情報収集と 十分なテストを行いましょう

Slide 66

Slide 66 text

まだやり切った感が足りない?! 改善したいポイント • 一部 AWS CLI コマンドを利用しているが、これをなくしたい • ハッシュ関数を LotusScript 化して Nomad でも使えるよう にしたい • Domino REST API に対応して Link to Domino を実現した い

Slide 67

Slide 67 text

「aws lotusscript」でググってみてください コードはブログにあります!! https://harunakano.blogspot.com/2022/04/aws-api.html

Slide 68

Slide 68 text

デモ環境をもっと深く知りたい方は ノーツコンソーシアムへ!! 本デモ環境はノーツコンソーシアム「DX 委員会」の活動の中で 生まれたものです 実際のデモ環境はもっとディープです

Slide 69

Slide 69 text

HCL Ambassador も参加している 「のの会」ほぼ毎月開催!! 過去回の資料はこちらにあります

Slide 70

Slide 70 text

ご清聴ありがとうございました