BLEのアドバタイズとスキャンリクエスト

とある展示会会場で、スマホアプリからBLE機器つなげようとしたんですが

スキャンしても全然見つからなくて困りました。

安直に「機器が多すぎて干渉してんじゃね?」って印象を持つのですが

もう少し詳しく調査したのでメモ

 

ちなみに会場内でBLE scanner起動するとめちゃくちゃでてくる。

多すぎワロタ。

f:id:Messerarche:20211018135803p:plain

 

しかし急に電波調査しようとおもっても、

パケットキャプチャ機器を持って来ているわけではないのでどうしたものかと思って調べてみたら、

MacでBLEのパケットキャプチャめいたことができる手順を発見。

IoTの要(かなめ)!BLE通信をMacだけでデバッグできるようになる方法! - Qiita

 

早速LightBlueとPacketLoggerをインストールして結果を見てみる。

f:id:Messerarche:20211018141818p:plain


だいたい3秒〜遅い時で13秒近く間隔を開けて

Advertising Reportが表示されていました。

そしてこれ、名前がAdvertising Reportとなっていたためにてっきり

BLE機器から飛んできたAdvertiseが表示されているのかなと勘違いしてだいぶ混乱しました。。。

 

アップルによるBluetoothアクセサリの設計ガイドラインに書かれていたこと - その後のその後

これによるとApple様のAdvertise推奨間隔が20msから長くても1sとのことなので

違和感はあったのですが。

 

 

で、後日周辺にBLE機器が少ないところで再トライ。

まずはパケットキャプチャしてみる。
キャプチャ設定した時の記事はこちら

BLEのsnifferを作成する - 暇人による偏った日記

f:id:Messerarche:20211018140849p:plain

この機器、アドバタイズ(ADV_IND)めちゃめちゃでてる。300ms間隔ぐらい。

そして真ん中に表示されているAppleの文字。

 

つまり、機器はアドバタイズ出しまくっているが

そんなこと気にせずにApple(Mac)はスキャンリクエストを

自分の好きなタイミングで出していて、それが3〜13秒だったと。

さっきの"Advertising Report"とは、Scan Responseの結果のことであると。

名前がややこしい。

 

今回使ったLightBlueとPacketLoggerの組み合わせは

あくまでMac側でやりとりしているパケットしか拾わないので、

BLE機器のアドバタイズ全部は拾ってなかったんですね。

改めて、周りにBLE機器がほぼない環境でスキャン。

f:id:Messerarche:20211018141724p:plain

今回は、2秒〜長くても6秒ぐらい。

やっぱり周辺の機器の多さは関係あるらしい。

 

BLEの通信仕様 - わふうの人が書いてます。

アドバタイザの周囲には複数のスキャナがいるときに、いくつかのスキャナが同時にSCAN_REQパケットを送信すると、パケットが衝突して、アドバタイザはパケットを正しく受信できなくなります。スキャナは、レスポンスが返ってこないときは、SCAN_RESパケットの送信を、ランダムな回数で間引いていきます。

これかなぁ。

 

久々にラズパイを買った

Raspberry pi買っていじくり回してる人みてたら欲しくなったので、

私も書いました。Raspberry pi 4 8GB。

大昔にも買ったことがあるんですが、OSのコンパイル が死ぬほどめんどくさくて四苦八苦した記憶。最近はそんな苦労とは無縁のようです。

 

Raspberry PiのOSインストールからSSH接続までなんて

無数に記事があるので書く必要はないのですが、

割と初歩的なところでめちゃめちゃつまづいたので、日記として記録。

 

64bit OSインストール

キットで買ったので、microSDにはNOOBSが入っていましたが

64bitOSは現時点でまだbetaなので、NOOBS上では選べません。

ということで一旦WindowsPCにつないで、microSDの中身を64bitOSで上書き!

 

f:id:Messerarche:20211008183032p:plain

手順はこの辺の冒頭を参照。すんなり成功。

Raspberry Pi 3/4 (RaspberryPi OS 64bit) 一括セットアップ手順: node-redでスマートホーム用 - Qiita


sshで接続したいのでboot領域にsshという空ファイルも作成しておきます。

ブート時にsshというファイルが見つかったら有効にするという仕組みらしいですが

なんかアナログだなぁ・・・。

 

ちなみにwpa_supplicant.confを作成しておくネット接続までいけるようですが

うっかり忘れてたので後ほど手動設定。

 

さて、モニタ・キーボード・マウスをPiに接続し

起動!・・・で早速謎の躓き×2。

1.microSDカードどこに刺すねん

Raspberry PiのセットアップとOS (Raspbian)の初期設定 – Indoor Corgi

裏面のこれかーー。

キットについてた説明書は日本語が怪しくてよくわからんし無駄に探した。

 

そして電源挿して、起動するかと思いきや

2.画面が虹色に輝いて止まったんだが???

Raspberry Pi 4(ラズパイ)起動!虹画面フリーズの原因は意外なものだった… │ きゅうり大爆発
HDMIポートが隣だったらしい。刺しやすい方に刺すってのはダメだった模様

 

 

各種設定

気を取り直して

user:pi、password:raspberryにて起動。

 

この時点ではインターネットにつながってないので

sudo raspi-config

でコンフィグレーション画面を表示。

System option→Wireless LANから

SSIDとpasswordを入力。

設定反映の再起動の後、

ifconfigを叩くと192.〜の自宅アドレスが出たので無事つながった模様。

 

PC(mac)でコンソールを起動し

ssh pi@raspberry.local

を叩いたところ、無事接続完了。

これでやっとスタートライン。

 

さて、ちょうど日経ネットワークがSSH特集やってたので、

フィンガープリント周り(接続初回に出るコレ↓)

ECDSA key fingerprint is SHA256:Q2rDOIyj+/I8YMR4JnHjE2bJuhb90g2Pprbt8b9Nh/0.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

を深堀しようと思っていましたが

それよりもっと気になったことがあったので調査。

 

mDNS

なんか普通にipアドレスの代わりにraspberry.local使ってますが

これは一体どう言う仕組み?と思って調べました

mDNS(マルチキャストDNS)に興味 - treedown’s Report

mDNSの謎について - 知見(・・)!

マルチキャストDNSという、LAN専用のDNS。

 

ということは、マルチキャストパケットが飛んでるんだろうなぁってことで

PC側でキャプチャ仕掛けてraspberry piを再起動。

 

f:id:Messerarche:20211008191613p:plain

お、飛んでる飛んでる。ちょうどログインプロンプトが出る直前ぐらいに出てきた。

宛先は224.0.0.251のマルチキャスト用アドレス。port5353。

 

f:id:Messerarche:20211008191701p:plain

Domain Nameにraspberrypi.localが入っているので、ここでPCが理解するというわけですね。

そして、PCが理解していると言うことはキャッシュがどこかにあるということで。

ごそごそしてたら最終的にこれを見つけました。

macOSでない他のホストを.localで解決することはできるのか

$dscacheutil -q host -a name raspberrypi.local
name: raspberrypi.local
ipv6_address: 2001:a450:3e45:1600:f797:89df:1694:f5a7
name: raspberrypi.local
ip_address: 192.168.2.34

おー、でてきた。

 

ついでにpi側でもmDNSサービスの起動を確認してみます(Linuxだとavahiというらしい)

pi@raspberrypi:~ $ systemctl list-unit-files --type=service | grep avahi
avahi-daemon.service                   enabled

確かに起動してますね。

 

今回はMacで繋ぎましたが、Windows10でもmDNSの機能が実装されているらしく、

そのまま繋がるとのこと。

 

LOST ARKのクラス解説動画の翻訳

automaton-media.com

 

いよいよロストアークが日本でサービス開始です。

ハクスラに飢えていたので非常に楽しみです。

 

MMORPGを始めるときの職業選びは毎回非常に悩むのですが、

ググってもどのクラスがおすすめなのか、今一つ掴みきれなかったので

海外の方が解説している動画を

英語の勉強がてらざっくり翻訳してまとめてみました。

勉強がてらなので間違ってたらごめんなさい。

クラス選びの一助になれば幸いです。

 

LOST ARK How To Pick Your Class in 2020 (all classes overview)

www.youtube.com

 

バーサーカー

大剣使いでめちゃくちゃ男臭い、範囲スキルが多い

ロストアークの中で一番遊びやすいしマスターもしやすい

スキルは王道なものが多いので操作が簡単

なぎ払いの範囲が広いのでポジショニングもしやすい

PvPでもPvEでも活躍できる、初心者におすすめ

ウォリアの中では速い方だけどファイターに比べたら遅い

攻撃をしてポイントをためてポイントを使って攻撃する簡単なお仕事

 

ウォーロード

タンク役だけど正直微妙

なぜならロストアークにヒーラー/タンク/DPSの役割はないから。

だいたいみんなDPSで、いくつかのクラスがややサポート寄りっていうだけ

そんな中でのタンク職

防御寄りのスキルと高い防御力、PTへの攻撃バフがある

挑発スキルもあるしいくつかのギミックをキャンセルさせることもできる

楽しいけどバーサーカーよりは難しい

難しい操作はいらないけど、ゲームの知識と反応速度が必要

パーティの需要は高い、3か4番目ぐらいには必要とされる存在

PvPでも明確な役割があって楽しいけど、

DPSを犠牲に味方のために立ち回らなければならない

 

デストロイヤー

でっかいハンマーで殴る職。動きは遅い、チャージスキルが大事

攻撃タイミングの把握が難しい

レイドにはあまり向いてない(ボスが結構素早い)

例外的にPvPは、敵の動きを短時間止めるスキルがあるから強い。

直感と、最も効率のよい攻撃のタイミングを把握する必要がある

序盤はそうでもないけど韓国では数ヶ月したらDPSのTOP2ぐらいには躍り出た

タイミングよく使う必要はあるが有能なシールドスキルもあるので耐久力も高い

 

ホーリーナイト

サポートクラスで攻撃・魔法のDPSを出す

ソードスキルとブックスキルを駆使する。タンク職ではない。

サポートスキルはたくさんある。特にヒールはバードとホーリーナイトしかもってない

ただし、回復量が少ないので正直微妙。攻撃防御その他のバフで活躍する。

PvPだと韓国ではホーリーナイトの人口多い

ロシアでは弱体化して実装されたので微妙

ホーリーナイトはPvEPvPどっちでも機能するが、

状況によってはバードの方が良いときもある。一緒に遊ぶ人の構成による

 

アルカナ

アサシンメイジって感じ。

2番目ぐらいに難しい職だと思う

魔法で殴るミドルレンジなクラス

めちゃ動き早いのはPvPで役に立つけど、PvEではいらない

ゲージがたまるとカードがひける。

タロットカードはランダム性能。

回避をあげたりクリティカルあげたり移動速度上げたり何が起きるかわからない

運ゲー要素が強い。

 

モナー

いろんな召喚ができて、見た目がめちゃめちゃ綺麗

PvEでもPvPでもそれなりに活躍できてどっちも楽しめる

アルカナよりは生存できる、アルカナよりはちょっと遅い

PvEではデストロイヤーとかブラスター並のダメージがだせるし

PvPでもトップ3ぐらいには入れる

 

バード

超重要なサポート職

どこでも必要とされる

ハープをもって鳥のように戦場を飛び回る

攻撃・防御バフでパーティ全員の生存率があがる

ロストアークにおけるポーションはPvEでも制限があるし、PvPだと使えない

そこにヒールと防御バフをかけられることは非常に大事

4人PTを作る時は必ずバードが1人はいる

 

バトルマスター

最速クラスで人気職

でもアルカナと並んで難しいクラスだと思う

移動速度や攻撃速度が早い、それはPvPでは活躍するけどPvEではあまり重要ではない

バードの近くにいないといけないから

ボス戦ではめちゃくちゃ集中して一つのミスも出さず100%正確に攻撃しなければならない

ちょっとタゲがこっちに向いたらHPの半分が持ってかれてDPSも下がる

それをカバーするために少ないダメージのスキルをたくさん当て続けなければならない

バードを抜いて残り3人の枠にバトルマスターを入れるか、デストロイヤーか、ブラスターかを決めるのはあなたの友人がどんな人なのかによる。

もちろんバトルマスターだけでロストアークの全コンテンツを終わらすことはできる。

PvPでは速度の恩恵を十分受けることができる。まるでアサシンのように活躍できる

 

インファイター

バトルマスターよりちょっと遅い、バトルマスターより攻撃が重い

PvPとPvEどっちにも適している、ちょうどいいバランス。

緑色と黄色のゲージを交互にためながら攻撃する

だいたいどのコンテンツにも適する、困難なシーンはない。

 

ソウルマスター

ロストアークでおすすめはどのキャラ?って聞かれたら

ソウルマスターって答えるぐらいおすすめ

なぜなら単純に中距離レンジから物理と魔法のDPSが出せて、

PvEからPvPまで楽々こなせるクラスだから

器用貧乏ではなく、なんでもできる何でも屋

PvEはバーサーカーなみに王道で簡単

PvPではソウルマスターはずっとトップ2に入ってるぐらい人気

PvEもトップ3ぐらいには入る

 

ランスマスター

武器を入れ替えるだけの簡単なお仕事

PvPとPvEどっちにも適している。

PvEよりはPvPのほうがやや適している、バトルマスターと似た理由で

DPSはトップ3には入らない、たぶんトップ5ぐらい・・・いやそれ以下かも

でも困難な場所もないし、いい感じの速度とシールドと簡単なメカニックで

十分楽しめると思う

 

デビルハンター

ダンテっぽい

ショットガンとスナイパーライフルを切り替えて戦う

3番目に難しい職だと思う

PvEに適している

ショットガンとスナイパーを切り替えながら戦うのはめちゃめちゃ気持ちいい

DPSはでないけど瞬間火力はすごい

PvPではデビルハンターに対処する方法がたくさんあって微妙になってしまっている

ガンナーをやりたいならこれ

 

ブラスター

クソデカキャノンかついだりタレットに変身したりする

自分自身は弱くて、立ってるだけな印象

設置したブラスターにボスが突っ込んでいくのを見るだけって感じ

レンジは遠距離だったり中距離だったり近距離だったり

攻撃判定が出るまでが遅いので予測しないといけない

打ち上げて落ちてくるまで数秒かかるミサイルや、

爆発に数秒かかる地雷スキルがある

ボスも人もうろうろするから当たらない

本当に上手であればデストロイヤーかブラスターでDPS1位2位を競うレベルではある

 

ホークアイ

遠距離DPSクラス

PvPもPvEもそこそこ活躍する

他のMMOでレンジャー系を遊んでたらプレイ感はだいたい同じ

核を使ったりメタルな弾丸を使うところは違うかも

ハイドして背後に回ったりもできる

ペットの鷹は2種類のスキルをもつ

単純な範囲攻撃と、自殺して大ダメージを与えるスキル

 

 

 

ブレイドとデモニックについても触れられていましたが、

未実装っぽかったので割愛。

 

他のサイトで集めた情報とちょいちょい評価が違ってて悩ましい

AWS SAA合格記

AWSソリューションアーキテクトアソシエイトに無事合格しました。

せっかくなので合格までの道筋を書きたいと思います。

 

学習のスタンス

巷に溢れている合格体験記はいかに資格を効率よく取るかに特化したものが多いです。

確かに資格があれば転職等には有利かもしれませんが、

それ技術者としてはどうなの?という思いが拭えません。

実機を触らずに合格!みたいな謳い文句の記事はもってのほかです。

そうではなくキチンとAWSが扱える人、

ソリューションアーキテクトならやりたいことが設計できる人、

を私は目指しましたので

そういう観点を持って学習したい方の参考になれば幸いです。

 

 1.書籍を読む

勉強開始時、まずはこの本を読みました。


AWS認定資格試験テキスト AWS認定 ソリューションアーキテクト-アソシエイト

 AWSは日々新しいサービスを出してきますので、最新の情報が必要です。

書籍購入の際はいつ改版されたかをまず確認してください。

この本はいくつかある参考書の中でも新しめだったので購入しました。

中身は、AWSに存在する様々なサービスが一つ一つ丁寧に説明されており

どんなサービスがあるかを把握するのに非常に役に立ちました。 

 

2.自分の理解した内容で構成図を書いてみる

ただ、ELBだのEFSだのECSだの(見た目ややこしい)単語は頭に入ってくるものの

いざ構築するとなった場合に各サービスがどういう位置付けなのか、

何をどうしたら動いて、どうしたら他のサービスと連携するのかがさっぱりでした。

 

それは勉強初期に本だけの知識で書いてみた構成図に如実に現れています

messerarche.hatenablog.com

今見ると恥ずかしいものですが、でもこういうレベルでした。

特に、サービスの「場所」がよくわかりませんでした。

VPC内なのか、AZなのか、リージョンなのか。

これが実機を触らねばと強く思ったきっかけでした。

もし、今まさに同じように勉強を始めた方がいらっしゃいましたら

自分の知っているサービスたちを書き出して、構成図を作ってみてください。

理解度がよくわかると思います。

 

3.実機を触る

そこから、AWSが使いこなせるようひたすら実機を触りました。

やり方としてはまずサービス、例えばEC2ならEC2にフォーカスして

「サービス名+ハンズオン」とかでググります。

そうすると動かし方を書いた記事が出てくるので、

その通り真似して動かしてみます。

でも、記事がAWSの仕様変更に追いついていなかったり、

知りたい内容が端折られていたりして(技術系記事あるある)

うまくいないことが多いです。

そこで、なんでうまくいかないのか?というのを調べたり、

公式ドキュメントやblackbeltを読んで情報を補完していきます。

そうすると動かし方や最新の情報が自然と身についていきます。

これを、気になったサービスに対して片っ端から行いました。

私が取り組んでみた分は全部記事にしているので、真似してもいいかもしれません。

AWS カテゴリーの記事一覧 - 暇人による偏った日記

 

無料枠だけでは試しきれないので、有料サービスも使いました。

どこぞの資格対策講座や書籍にお金使うよりは、1つでも減らして

実機の使用料に費やした方が断然コスパが良いです。

何より楽しいですしね。

実質3週間ぐらいを実機操作に費やしました。

 

実機操作がひと段落してから1ヶ月ぐらい忙しくて

まったくAWSは触れなかったのですが、

少し手が空いた隙に、試験日を登録しました。

実機操作できちんと基礎が身についていたら急に受けても合格できるはず!

ということを証明するため、試験日を「2日後」に設定しました。

 

4.模擬試験を解く

実機で触れてなかったところを補完するため、

2日間で仕上げにこの本を読みました。


徹底攻略 AWS認定 ソリューションアーキテクト – アソシエイト教科書
 

これも有名どころの本ですが、正直内容はお勧めしないです。

理由は、アーキテクチャ、セキュリティといったいわゆるベストプラクティスの軸にそって各サービスの使い方が記載されている構成なのですが、これがわかりにくすぎる。

当然軸によっては同じサービスの話題が出てきます。

例えば可用性におけるS3、セキュリティにおけるS3、コストにおけるS3など。

ずいぶんページが離れて同じサービスの違う側面が書かれているので

多分この本から勉強を始めたら、結局S3って何ができるの?となり混乱すると思います。

 

じゃあこの本は買う価値がないのか、といったらそうでもありません。

付録の、ネットからDLできる模擬問題が最高でした。

65問の大ボリュームかつ、ちゃんと半年に1回ぐらいのペースで更新がかかってます。

書籍より新しい話が問題に反映されているので、非常によい勉強になりました。

本は割と薄かったのでを読むのに大体半日、試験問題は2周して4時間ぐらいかけました。

 

 

5.受験

で、受験して無事合格しました。

f:id:Messerarche:20200822205130p:plain

スコアがイマイチだったのはちょっと不満ですが、

急に試験を受けても合格できた、という事実は

きちんと使える技術として根付いた証拠といえるでしょう。

 

 

とはいえまだまだ触ってないサービスも多々。

もっと色々触ってみつつ、気が向いたら別の資格も狙ってみたいと思います。

 

 

 

AWSを使い倒す(15.Step Functions)

lambdaとAPI Gatewayの組み合わせが動いたと思った矢先、

思わぬところで問題発生。

API Gatewayってタイムアウト29秒までしか設定できないのね。

lambdaで普通に1分ぐらいかかる処理仕込んでたので

API Gatewayが待ちきれない状態になってしまった・・・。

 

【API Gatewayタイムアウト対策】Step Functionsを組み合わせて非同期処理にしてみる | Developers.IO

ということでこのStep Functionsを使って解決を試みる。

記事を読むにStep Functions(のステートマシン)を介してlambdaを実行することで、

lambda実行中なら実行中、終わったら結果をステートマシンが代わりに「応答」してくれるようになるので、API Gatewayタイムアウトが回避できる。

代わりにAPI叩く人は結果返ってくるまで何回かAPIを叩かないといけないって感じ。

 

 

 

大変なのが

APIを叩いた時にユーザが渡してくるパラメータを

一度ステートマシンが受け取って

それをlambdaに渡す

ってしないといけないのでややこしい。

ここの理解にめちゃめちゃ時間がかかった。

 

 

まずは適当なlambda関数を作成する。

import json
def lambda_handler(event, context):
    msg = "bucket="+ event["s3bucket"]+",folder="+event["s3folder"]
    return msg

 eventとしてStep Functionsから引数を受け取れるか、の確認するだけなので

本当にシンプルな作り。

 

次にStep Functionのステートマシンの作成

f:id:Messerarche:20200710211005p:plain

 

作成画面

f:id:Messerarche:20200710211830p:plain

コードスニペットで作成、タイプは標準を選ぶ

 

定義を書く。

f:id:Messerarche:20200710211910p:plain

ここにどう書くか、を理解するのが大変だった

 

 

今回書いたのはずばりこのコード

{
  "StartAt": "Test",
  "States": {
    "Test": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:[中略]:function:test-lambda",
      "Parameters": {
     "s3bucket.$": "$.bucket",
     "s3folder.$": "$.folder"
    }, "End": true } } }

 大事なのは、ResourceとParameters

 

Resourceには、lambda関数のarnを記載する。

 

Parametersは記法に戸惑うが、API Gatewayから変数として受け取るのでこう書く。

具体例を書くと、以下のようなフォーマットでAPI Gatewayから情報が来た時に

"input": {
    "bucket: "nameofbucket",
    "folder": "nameoffolder"
}

 

"s3bucket.$": "$.bucket"の意味は

s3bucketは変数です、変数の中身は来た情報の中のbucketが指し示す値です

ということになる

上記のような解釈で今度はステートマシンが

"event": {
    "s3bucket": "nameofbucket",
    "s3folder": "nameoffolder"
}

と情報を再構築してlambdaに渡してくれる。

これを元にlambdaは

event["s3bucket"]

として値を受け取ることができる。

$.だの.$だのをつけないと、変数ではなく定数と解釈されて受け取れなくなる。

 この辺の何がどうなるはこちらで試されている

StepFunctionsの入力方法サンプルメモ集 - Qiita

 

 

作成すると、ARNが表示されるのでメモっておく。

f:id:Messerarche:20200711013205p:plain

 

 

API Gatewayの前にAPI Gateway用のIAMロールを作成しておく。

具体的には、StepFunctionsの実行権限を持ったロールが必要。

API Gateway を使用して Step Functions API を作成する - AWS Step Functions

 

 

ロールを作成したら、API Gatewayに移動

f:id:Messerarche:20200711014201p:plain

な形でメソッドとリソースを作成する。

executionがlambdaをキックするAPI、

statusがlambdaの進捗を確認するAPI。

 

メソッドの作成時に、StepFunctionsを選択する

f:id:Messerarche:20200711014610p:plain

重要なのはアクションのところ。

LambdaをキックするAPIにはStartExecution

進捗を確認するAPIにはDescribeExecution

と入力する。

実行ロールはさっき作ったIAMロールのarnを入力。

 

出来上がったら早速テストをする。

まずはlambdaの実行、つまりexecutionのPOSTから、テストの画面を開いた後

リクエスト本文に以下を入力

f:id:Messerarche:20200711015133p:plain

 

黒塗りのところにステートマシンのarnを記載する。

また、ステートマシンに渡したい変数を図のように記載する。

そしてテスト実行。

 

 

実行されたら

f:id:Messerarche:20200711015547p:plain

こんなレスポンスが返ってくる。

このexecutionArnを使って進捗確認を行うのでメモしておく。

 

次に進捗確認のほうのメソッド(/status)にうつる

リクエスト本文に、先ほどのexecutionArnを図のように記載する

f:id:Messerarche:20200711015918p:plain

これで実行すると、

先ほどキックしたlambdaが実行中であれば実行中、

実行完了していたら処理結果が返ってくる。

 

その進捗具合はステートマシンのログから確認ができる。

うまくいっているとこんな感じで

f:id:Messerarche:20200711020058p:plain

 

1.ExcecutionStartedにはAPIGatewayから送られてきた情報が

f:id:Messerarche:20200711020556p:plain

 

3でステートマシンがlamdaに渡した情報が

5でlambdaの実行結果が見える

f:id:Messerarche:20200711020947p:plain

 

一応この通りやれば動くハズ。

 

 

 

ここからは追加で

リクエスト本文にいちいちステートマシンのarn情報を記載しない方法と、

パスパラメータをステートマシン越しにlambdaへ渡す方法を記す。

 

まずは、実行したいステートマシンをあらかじめ記載しておく方法

f:id:Messerarche:20200711021539p:plain

この画面の統合リクエストのところをクリック

 

開いた画面の一番下、マッピングテンプレートを開く

ここにいろいろ書くことで、リクエスト本文の内容とかを書き換えることができる。

公式ドキュメントを参考に

API Gateway を使用して Step Functions API を作成する - AWS Step Functions

{
    "input": "$util.escapeJavaScript($input.json('$'))",
    "stateMachineArn": "arn:aws:states:us-east-1:123456789012:stateMachine:HelloWorld"
} 

こんな感じで記載する。

stateMachineArnはもちろん自分のステートマシンに合わせて書き換える

右下の保存を押す。これでAPI実行の度にステートマシンの情報を書かなくてもよくなる。

 

 

 

次はパスパラメータ

f:id:Messerarche:20200711022354p:plain

パスパラメータを使うためのリソースとメソッドを作成する。

 

テストを押した時にここに

f:id:Messerarche:20200711022445p:plain

(めちゃ適当に)値を入れて、これがlambdaまで伝われば成功

 

こちらも統合リクエストでマッピングテンプレートの設定を行うことで実現できる

#set( $body = $util.escapeJavaScript($input.json('$')) )
{
  "input": "{\"input\":$body,\"InputParams\":{\"bucket\":\"$input.params('bucket')\",\"folder\":\"$input.params('folder')\"}}",
"stateMachineArn": "arn:aws:states:us-east-1:123456789012:stateMachine:HelloWorld" }

ずばり書くとこんな感じ。

参考にしたのは以下

API GatewayでStepFunctionsと統合する時のTips - Qiita

API Gateway マッピングテンプレートとアクセスのログ記録の変数リファレンス - Amazon API Gateway

 

 

これをテストすると、API Gatewayからの出力はこうなる

"input": {
    "input": {},
    "InputParams": {
        "bucket": "a",
        "folder": "b"
    }
},

 

パスパラメータで引数を渡すし、実行時のステートマシン設定も不要になったので

テスト時にリクエスト本文に何も書く必要がなくなったため、

"input": {}、つまり記事の前半で参照していたinputには何も入らない。

代わりに、InputParams配下に自分の指定したパラメータが入っている。

 

 

ステートマシンにも変更が必要。

今まで受け取っていたinputの中身が空っぽになって、

代わりにInputParams配下に中身が入るので、そのような宣言がいる。

{
  "StartAt": "Test",
  "States": {
    "Test": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:[中略]:function:test-lambda",
      "InputPath": "$.InputParams",
      "End": true
    }
  }
}

 

InputPathで宣言してやる。以下が参考

InputPath およびパラメータ - AWS Step Functions

 

lambdaも実態に合わせて変更("s3bucket"とかをただの"bucket"にしただけ)

import json
def lambda_handler(event, context):
    msg = "bucket="+ event["bucket"]+",folder="+event["folder"]
    return msg

 

これで、パスパラメータからステートマシンに、ステートマシンからlambdaに変数を渡していく仕組みが動く。

 

 

動きは確認できたので、あとは実装だ・・・!

 

AWSをいじり倒す(14.API Gateway)

API Gatewatを使って、lambdaに変数を渡せるAPIを作ってみる

今回の目標は、

API Gatewayで用意したURLを叩くと

s3の指定したバケットに指定した名前のフォルダができるもの」を作る

 

先にlambda関数を作成する。

 コードはこんな感じ。
import json
import urllib.parse
import boto3

s3 = boto3.client('s3')


def lambda_handler(event, context):
    bucket=event['pathParameters']['bucket']
    folder=event['pathParameters']['folder']

    response = s3.put_object(
        Bucket=bucket,
        Body='',
        Key=folder
    )

pathParametersでバケット名とフォルダ名を受け取るところが肝。

ちなみにバケットを新しく作るコードではない。

あくまで指定したバケットにフォルダを作るだけなので、バケットは先に作っておく。

 

まずはテストをしてみる。テストイベントの設定から

f:id:Messerarche:20200709233645p:plain


イベントテンプレートのAmazon API Gateway AWS Proxyを指定する

f:id:Messerarche:20200709233750p:plain

 

出てきたイベント内容の、pathParametersにbucketとfolderの情報を書き込む。

API叩いた時に飛んでくるリクエストの中身をここに書いて模擬できるというわけだ。

変更する必要がある箇所は2箇所

f:id:Messerarche:20200709234402p:plain

まずはresouceとpathのところ。

https://example.com/slp/[バケット名]/[フォルダ名]

みたいな感じでAPIを作りたいのでそう書く。

pathのところには[バケット名]と[フォルダ名]を実際の値で埋めたものを書く

 

もう一つはここ、pathParameters

f:id:Messerarche:20200709234812p:plain

lambdaに渡す変数を指定する。さっきのコードで

bucket=event['pathParameters']['bucket']

folder==event['pathParameters']['folder']

のところで受け取る値となる

 

作り終えたらテスト実行。

確認しに行くと・・・できてるが、フォルダじゃなくてファイルになってる・・・

f:id:Messerarche:20200709235732p:plain

フォルダを作るには、

test-folder-12345/ みたいに最後にスラッシュを付けないといけないようだ。

ということで

folder = folder +"/"

をくっつけてリトライ

 

f:id:Messerarche:20200710000513p:plain

うむ。

 

では本題のAPI Gateway

 

参考:ゼロから作りながら覚えるAPI Gateway環境構築 | Developers.IO

 

f:id:Messerarche:20200709222411p:plain

Websocketはチャットみたいな頻繁にやり取りするものに使うとして

HTTPとRESTはどっちがいいのか

Amazon API Gatewayは「HTTP API」と「REST API」のどちらを選択すれば良いのか? #reinvent | Developers.IO

勉強という意味では機能の多いRESTで十分に慣れたほうがよさそうかな。

 

早速設定してみる

f:id:Messerarche:20200709224055p:plain

REST、新しいAPIを選択。

API名も適当につける。

 

いろいろ設定できそうな画面ができてきた。

f:id:Messerarche:20200709224348p:plain

 

 

リソース=ディレクトリみたいなもの。

例えばtestリソースを作るとAPI叩く時のURLが

https://example.com/test

になる。

 

アクションからリソースの作成を選択した画面

f:id:Messerarche:20200709224941p:plain

 リソース名とパス名で別のものを付けられるようだけど、別にすると混乱しそう

 

なお、 階層構造で作ることができる。

f:id:Messerarche:20200709230255p:plain

 

 

次に、作りたいフォルダ名をlambdaに変数として渡したいので

パスパラメータの設定をする

AWS Lambda + API Gateway で/hoge/{group}/{user}のように階層構造のREST APIでパスパラメータの受け渡し – 或る阿呆の記

設定自体は{}でくくるだけ

f:id:Messerarche:20200709231012p:plain

こんな感じ。バケット名とフォルダ名を受け取るつもり

f:id:Messerarche:20200709231351p:plain

 これでhttps://example.com/slp/mf/[バケット名]/[フォルダ名]

な感じのURLを叩けばバケット名とフォルダ名がlambdaに渡されるようにする

 

次にメソッドの作成

 メソッドでHTTPのメソッドを指定できる。

 

f:id:Messerarche:20200709231528p:plain

やりたい処理に対してどれを選べばいいんだよ?ってなるかもしれないが

大まかに書くと、

GETがリソースの取得

POSTがリソースの新規登録

PUTが既存リソースの更新

DELETEがリソースの削除

という感じ。

とは言ってもAPIは多種多様でこれはこれと定めるのは難しい。

有名サービス間でも使い方が微妙に違っていて

こう使うべしみたいな論で本が一冊出てるレベル。

O'Reilly Japan - Web API: The Good Parts


今回は新しいフォルダを作る、なのでPOSTかな。

POSTを確定すると連携先のlambda関数の指定が出てくる

f:id:Messerarche:20200709232330p:plain

統合タイプはもちろんLambda関数

Lambdaプロキシ統合の使用にチェック。

これでパスパラメータが使えるようになる

Lambda関数に事前に作っておいた関数を指定する

 

設定するとこんな画面が出てくる

f:id:Messerarche:20200710001409p:plain



テストを押すと

f:id:Messerarche:20200710001025p:plain

おー、lambdaでやったテストと同じことができそう。

早速、パスのところのfolderとbucketに値を入れてテスト

他の場所に値を入れる必要はなし

 

結果・・・怒られた。

f:id:Messerarche:20200710002000p:plain



 

API Gateway コンソールを使用してメソッドをセットアップする - Amazon API Gateway

バックエンドが返したレスポンスに対応するメソッドレスポンスが定義されていない場合、API Gateway はクライアントにレスポンスを返しません。代わりに、500 Internal server error エラーレスポンスを返します。

 

確かに、lambdaから応答を返す設定は何もしてないので、怒られて当然か。

 

S3を確認するとちゃんとfolderはできていた。

lambda関数はちゃんと動いているようだ

f:id:Messerarche:20200710001833p:plain

 

というわけでlambda関数にレスポンスのコードを書く。

Amazon API Gateway + AWS Lambda でのレスポンス形式 – サーバーワークスエンジニアブログ

基本的にはstatusCodeをreturnするだけでよいみたい。簡単〜

 

応答処理を入れたバージョン。

import json
import urllib.parse
import boto3

s3 = boto3.client('s3')

def lambda_handler(event, context):

    bucket=event['pathParameters']['bucket']
    folder=event['pathParameters']['folder']
    folder = folder +"/"

    try:
        response = s3.put_object(
            Bucket=bucket,
            Body='',
            Key=folder
        )
        
        print(response)
        print(response['ResponseMetadata']['HTTPStatusCode'])
        return {
            'statusCode': response['ResponseMetadata']['HTTPStatusCode'],
            'body': json.dumps('Success to make folder')
        }
    except Exception as e:
        print(e)
        return {
            'statusCode': 500,
            'body': json.dumps(e.response['Error']['Code'])
        }


うまくいったらput_objectのresponseに書かれているステータスコードを(200だろうけど)をstatusCodeとしてreturn。

失敗したらstatusCodeを500と

エラーメッセージを取り出して返却するようにしてみた。

 

ではテスト

まずは成功事例、実在するバケットを指定して実行

f:id:Messerarche:20200710015044p:plain

うむ。

 

次に失敗事例として、バケット名を存在しないものにして実行

f:id:Messerarche:20200710015143p:plain

思惑通り動作した。

 

最後にデプロイを行う。

デプロイを行うと外部に公開されることとなるが、

誰からでもアクセスできてしまうので認証を入れ込む

 

APIキーを作る。

f:id:Messerarche:20200710022618p:plain

 

作成画面はいたってシンプル

f:id:Messerarche:20200710022718p:plain

 

できた。表示のところを押すとキーが表示される

f:id:Messerarche:20200710022924p:plain


API設定に戻ってきて、メソッドリクエストを選択

f:id:Messerarche:20200710023130p:plain

APIキーの必要性をtrueに設定

f:id:Messerarche:20200710023252p:plain

 

終わったらいよいよデプロイ

f:id:Messerarche:20200710023323p:plain

 

ステージ名devで作成

f:id:Messerarche:20200710023422p:plain

 

devステージにURLが出現。デプロイはこれで完了。

f:id:Messerarche:20200710023613p:plain

 

 

次に使用量プランを通じてAPIキーを設定する

f:id:Messerarche:20200710023719p:plain

 

スロットリングとクォータのチェックを外す。

どちらもAPIの呼び出し制限に関する設定だ

f:id:Messerarche:20200710023839p:plain

 

APIステージとの関連付け。さっきのdevのこと

f:id:Messerarche:20200710023940p:plain

追加するとこんな感じ。

f:id:Messerarche:20200710024051p:plain

 

次でAPIキーの紐付け

f:id:Messerarche:20200710024207p:plain

さっき作ったAPIキーの名前を入力して追加。

 

ではいよいよ実行。

どのURLにアクセスすればいいかはlambdaの画面から確認ができる。

f:id:Messerarche:20200710030130p:plain

キーまで全部丸見え。

 

 

では手元のPCから実行してみる

$ curl -X POST -H 'x-api-key:[APIキー]' https://[URL]/dev/slp/mf/[bucket名]/[folder名]

"Success to make folder"

  

できてるできてる。

f:id:Messerarche:20200710025921p:plain

 

APIキーのところを抜いて叩くとエラー

{"message":"Forbidden"}

 

ちゃんと機能してる。

ということで無事完成!

 

lambda完全に理解した

画像


 

今までの軌跡。

構成図をアイコンも使ってカッコよくしてみた

f:id:Messerarche:20200710043349p:plain

 

 

 

2020年春アニメおすすめ

NETFLIXもしくはAmazonPrimeVideoでみることができるアニメオンリーで

個人的におすすめと思ったものまとめ。

2020/4〜6放送分。

 

絶対みるべき

kakushigoto-anime.com

久米田さんといえば世の中の風刺で有名だが

いつものキレはそのままにほんのり感動を混ぜた良作。

序盤から意味深な伏線をふわっと残すので、気になって最後まで楽しく見れた。

 

 

kaguya.love

当然1期から見るのをおすすめ。

安心して見られるギャグ+ラブコメ。見る清涼剤。

声優の声色の使い分けっぷりもすごい

3期もあるらしいという噂

 

 

www.ghostintheshell-sac2045.jp

 

見た目でめちゃめちゃ損してると思った。

ガチガチの3Dを我慢して見ると、やはりストーリーは攻殻で引き込まれる。

ネットリンチとか割と身近に問題になってる話も織り交ぜつつ

キャラ同士の掛け合いは相変わらずの面白さ。

3Dならではのカチカチなアクションも、

ある意味AIにサポートされた機械的な動きにマッチしていてアリかなとすら思えてくる

 

 

見ても良いと思う

hamehura-anime.com

 

乙女ゲーが舞台ということでどうにも最初は気乗りしなかったが、

見ていくうちに慣れてきて、だんだん面白くなり、最後も綺麗に終わった。

悪役令嬢というジャンルを理解するため教養として見ておくべき、という側面もある

 

 

singyesterday.com

恋愛のヤキモキ感も見ていてもどかしい、そのもどかしさを楽しむアニメ。

キャラもよく、人間臭い悩みも身に滲みる。

ただ、アニメにすると会話の中で大事な「間」がどうにもテンポの悪さに感じてしまった。

 

 

ネタとして

hachinan-anime.com

OPだけは聞いた方がよい。

デーモン閣下×宝野アリカってだけでヤバい。

www.youtube.com

サムネがすでにヤバい