Mr.Children映像化ライブセットリスト集

Mr.Children映像化ライブセットリスト集

映像化されているMr.Childrenライブのセットリストを全曲一覧でまとめて内容です♪
曲探しの参考になれば。

特にオススメの元気の出る10曲は次の記事で投稿しています♪

やる気が溢れる 元気が出る Mr.Children エネルギーソング

Mr.Children 30th Anniversary Tour 半世紀へのエントランス

オススメポイント

  • ☆☆☆☆:名曲揃いですがコロナ禍というタイミングもあって タガタメ 染みます♪

セットリスト

Mr.Children 30th Anniversary Tour 半世紀へのエントランス - 2022.6.19 YANMAR STADIUM NAGAI – 完全版

  1. OPENING
  2. 終わりなき旅
  3. 名もなき詩
  4. 海にて、心は裸になりたがる
  5. シーソーゲーム ~勇敢な恋の歌~
  6. innocent world.
  7. <MC>
  8. 彩り
  9. 口笛
  10. <MC>
  11. 車の中でかくれてキスをしよう
  12. <MC>
  13. Sign
  14. タガタメ ☆☆☆☆
  15. Documentary film
  16. DANCING SHOES
  17. LOVEはじめました
  18. フェイク
  19. ニシエヒガシエ
  20. Worlds end
  21. <MC>
  22. 永遠
  23. others
  24. <SE>
  25. Tomorrow never knows
  26. 光の射す方へ
  27. fanfare
  28. エソラ
  29. <MC>
  30. GIFT
  31. <ENCORE> / <MC>
  32. HANABI
  33. <MC>
  34. 生きろ
  35. ENDROLL
    全25曲

Mr.Children 30th Anniversary Tour 半世紀へのエントランス - 2022.5.10 TOKYO DOME – 完全版

  1. OPENING
  2. Brand new planet
  3. youthful days
  4. 海にて、心は裸になりたがる
  5. シーソーゲーム ~勇敢な恋の歌~
  6. innocent world
  7. <MC>
  8. Over
  9. Any
  10. <MC>
  11. くるみ
  12. 僕らの音
  13. タガタメ ☆☆☆☆
  14. Documentary film
  15. DANCING SHOES
  16. ロックンロールは生きている
  17. ニシエヒガシエ
  18. Worlds end
  19. <MC>
  20. 永遠
  21. others
  22. <SE>
  23. Tomorrow never knows
  24. fanfare
  25. エソラ
  26. <MC>
  27. GIFT
  28. <ENCORE> / <MC>
  29. Your Song
  30. <MC>
  31. 生きろ
    全23曲

Mr.Children Dome Tour 2019 “Against All GRAVITY”

オススメポイント

  • ☆☆☆☆☆:名曲と知っていたのですがAgainst All GRAVITYのライブ映像の SUNRISE は段違いです♪

セットリスト

01 OPENING
02 Your Song
03 Starting Over
04 himawari
05 〈S.MC〉
06 everybody goes 〜秩序のない現代にドロップキック〜
07 〈MC〉
08 HANABI
09 Sign
10 〈MC〉
11 名もなき詩
12 〈MC〉
13 CANDY
14 旅立ちの唄
15 〈MC〉
16 ロードムービー
17 addiction
18 Dance Dance Dance
19 Monster
20 SUNRISE ☆☆☆☆☆
21 Tomorrow never knows
22 Prelude
23 innocent world
24 海にて、心は裸になりたがる
25 SINGLES
26 Worlds end
27 〈MC〉
28 皮膚呼吸
29 END ROLL

Mr.Children Tour 2018-19 重力と呼吸

01 OPENING
02 SINGLES
03 Monster
04 himawari
05 幻聴
06 〈MC〉
07 HANABI
08 NOT FOUND
09 忘れ得ぬ人
10 〈MC〉
11 花 -Mémento-Mori-
12 addiction
13 Dance Dance Dance
14 ハル
15 and I love you
16 しるし
17 〈S.MC〉
18 海にて、心は裸になりたがる
19 擬態
20 Worlds end
21 〈MC〉
22 皮膚呼吸
23 here comes my love
24 風と星とメビウスの輪
25 〈MC〉
26 秋がくれた切符
27 〈S.MC〉
28 Your Song
29 END ROLL

Mr.Children DOME & STADIUM TOUR 2017 Thanksgiving 25

  1. <Prologue>
  2. OPENING
  3. CENTER OF UNIVERSE
  4. シーソーゲーム 〜勇敢な恋の歌〜
  5. 名もなき詩
  6. <MC>
  7. GIFT
  8. Sign
  9. <MC>
  10. ヒカリノアトリエ
  11. <MC>
  12. 君がいた夏
  13. innocent world
  14. Tomorrow never knows
  15. <MC>
  16. Simple
  17. <VTR>
  18. 思春期の夏 〜君との恋が今も牧場に〜
  19. 365日
  20. HANABI
  21. <MC>
  22. 1999年、夏、沖縄
  23. 足音 〜Be Strong
  24. ランニングハイ
  25. ニシエヒガシエ
  26. ポケット カスタネット
  27. himawari
  28. Printing
  29. Dance Dance Dance
  30. fanfare
  31. エソラ
  32. <ENCORE>
  33. overture
  34. 蘇生
  35. <MC>
  36. 終わりなき旅
  37. ENDROLL

Mr.Children、ヒカリノアトリエで虹の絵を描く

  1. <Document 1>
  2. <Opening>
  3. お伽話
  4. <Document 2>
  5. <Document 3>
  6. You make me happy
  7. PIANO MAN
  8. <Document 4>
  9. クラスメイト
  10. <Document 5>
  11. <MC>
  12. 妄想満月
  13. 虹の彼方へ
  14. <Document 6>
  15. しるし
  16. こころ
  17. <MC>
  18. <Document 7>
  19. ヒカリノアトリエ
  20. <Document 8>
  21. メインストリートに行こう
  22. 跳べ
  23. <Document 9>
  24. 終わりなき旅
  25. <End Roll>

Mr.Children Stadium Tour 2015 未完

  1. <Prologue"未完">
  2. <OPENING>
  3. 未完
  4. 擬態
  5. ニシエヒガシエ
  6. 光の射す方へ
  7. CHILDREN’S WORLD
  8. <MC>
  9. 運命
  10. FIGHT CLUB
  11. 斜陽
  12. I Can Make It
  13. <MC>
  14. 忘れ得ぬ人
  15. <MC>
  16. and I love you
  17. タガタメ
  18. <SE>
  19. 蜘蛛の糸
  20. REM
  21. WALTZ
  22. フェイク
  23. ALIVE
  24. <SE>
  25. 進化論
  26. 終わりなき旅
  27. 幻聴
  28. 足音 〜Be Strong
  29. <ENCORE>
  30. I wanna be there
  31. overture〜蘇生
  32. fantasy
  33. Tomorrow never Knows
  34. innocent world
  35. <ENDING>
  36. Starting Over
  37. <END ROLL>

Mr.Children TOUR 2015 REFLECTION

  1. <Prologue>
  2. <OPENING>
  3. fantasy
  4. ロックンロールは生きている
  5. 旅人
  6. fanfare
  7. <MC>
  8. Melody
  9. FIGHT CLUB
  10. 斜陽
  11. I Can Make It
  12. <MC>
  13. 口笛
  14. <MC>
  15. HANABI
  16. <MC>
  17. 口がすべって
  18. <SE>
  19. 蜘蛛の糸
  20. REM
  21. WALTZ
  22. 放たれる
  23. <SE>
  24. 進化論
  25. 足音 〜Be Strong
  26. 幻聴
  27. <ENCORE>
  28. Everything(It’s you)
  29. エソラ
  30. Marshmallow day
  31. <MC>
  32. Starting Over
  33. <ENDING>
  34. 未完
  35. <END ROLL>

(an imitation) blood orange

DISC 1

  1. OPENING
  2. 過去と未来と交信する男
  3. LOVE はじめました
  4. Worlds end
  5. NOT FOUND
  6. (MC)
  7. 花言葉
  8. やわらかい風
  9. 抱きしめたい
  10. (MC)
  11. Surrender
  12. Pink~奇妙な夢
  13. 常套句
  14. CENTER OF UNIVERSE
  15. 擬態
  16. fanfare
  17. (MC)
  18. イミテーションの木
  19. pieces
  20. Happy Song
  21. hypnosis
  22. End of the day
  23. innocent world
  24. エソラ
  25. Marshmallow day
  26. (ENCORE)
  27. 天頂バス
  28. HERO
  29. 祈り ~涙の軌道
  30. ENDROLL

Mr.Children TOUR POPSAURUS 2012

DISC 1

  1. OPENING
  2. エソラ
  3. 箒星
  4. youthful days
  5. LOVE
  6. GIFT
  7. Everything(It's you)
  8. <MC>
  9. デルモ
  10. End of the day
  11. 終わりなき旅
  12. Dance Dance Dance
  13. ニシエヒガシエ
  14. フェイク
  15. <SE>
  16. 365日
  17. しるし
  18. <MC>
  19. くるみ
  20. Sign
  21. <MC>
  22. 1999 年、夏、沖縄
  23. ロックンロールは生きている
  24. Round About ~孤独の肖像~
  25. Worlds end
  26. fanfare
  27. innocent world
  28. <ENCORE>
  29. ラララ
  30. 彩り
  31. 光の射す方へ
  32. overture ~ 蘇生
  33. 祈り ~涙の軌道
  34. END ROLL

BONUS
Talk about 20th ANNIVERSARY & Selected Live from POPSAURUS 2012
 GIFT(2012.4.29 / 福岡 Yahoo! JAPAN ドーム)
 終わりなき旅(2012.4.22 / 埼玉 西武ドーム)
 innocent world(2012.5.25 / 東京ドーム)
 東京(2012.5.23 / 東京ドーム)
 Simple(2012.6.6 / ナゴヤドーム)

Mr.Children STADIUM TOUR 2011 SENSE -in the field-

  1. OPENING
  2. かぞえうた
  3. Prelude
  4. HOWL
  5. 未来
  6. I'm talking about Lovin'
  7. innocent world
  8. <MC>
  9. Replay
  10. 君が好き
  11. <MC>
  12. Mirror
  13. I
  14. CENTER OF UNIVERSE
  15. <SE>
  16. 365日
  17. ハル
  18. ロックンロールは生きている
  19. ニシエヒガシエ
  20. Everything is made from a dream
  21. 風と星とメビウスの輪
  22. HERO
  23. 擬態
  24. エソラ
  25. <ENCORE>
  26. fanfare
  27. 星になれたら
  28. Tomorrow never knows
  29. かぞえうた
  30. 終わりなき旅
  31. END ROLL

Mr.Children TOUR 2011 “SENSE”

  1. OPENING
  2. NOT FOUND
  3. <MC>
  4. HOWL
  5. 名もなき詩
  6. I’m talking about Lovin’
  7. エソラ
  8. <MC>
  9. HANABI
  10. くるみ
  11. 花 -Mémento-Mori-
    12.【es】~ Theme of es ~
  12. Dive
  13. シーラカンス ~ 深海
  14. I
  15. ロザリータ
  16. <SE>
  17. 365日
  18. ロックンロールは生きている
  19. フェイク
  20. ポケット カスタネット
  21. HERO
  22. 擬態
  23. Prelude
  24. ENCORE ~ <MC>
  25. 横断歩道を渡る人たち
  26. fanfare
  27. Forever
  28. <MC>
  29. かぞえうた
  30. ENDROLL

Split the Difference

DVD

  1. Documentary
  2. NOT FOUND
  3. Everything(It's you)
  4. SUNRISE
  5. Another Mind
  6. Surrender
  7. ファスナー
  8. 終わりなき旅
  9. TIME AFTER TIME
  10. 横断歩道を渡る人たち
  11. ニシエヒガシエ
  12. End Roll

DVD特典映像
 隔たり
 Jealous Guy
 Heavenly kiss
 僕らの音
 しるし

~SUPERMARKET FANTASY~ IN TOKYO DOME

  1. OPENING
  2. ラヴ コネクション
  3. Dance Dance Dance
  4. Worlds end
  5. MC
  6. HANABI
  7. ロードムービー
  8. 風と星とメビウスの輪
  9. ALIVE
  10. LOVE はじめました
  11. Monster
  12. ニシエヒガシエ
  13. CANDY
  14. MC
  15. Simple
  16. Drawing
  17. 彩り
  18. fanfare
  19. 箒星
  20. 名もなき詩
  21. エソラ
  22. 終わりなき旅
  23. 365日
  24. and I love you
  25. GIFT
  26. END ROLL

Mr.Children Tour 2009~終末のコンフィデンスソングス~

オススメポイント

  • ☆☆☆☆:お客さんがメインで歌っている innocent world の大合唱
  • ☆☆☆:ライブで歌うのは今のところこのライブだけが唯一となる熱い曲 少年

セットリスト

  1. OPENING
  2. 終末のコンフィデンスソング
  3. everybody goes -秩序のない現代にドロップキック-
  4. 光の射す方へ
  5. MC
  6. 水上バス
  7. つよがり
  8. MC
  9. ロックンロール
  10. 東京
  11. 口がすべって
  12. ファスナー
  13. フェイク
  14. MC
  15. 車の中でかくれてキスをしよう
  16. HANABI
  17. youthful days
  18. エソラ
  19. innocent world ☆☆☆☆
  20. 風と星とメビウスの輪
  21. GIFT
  22. 少年 ☆☆☆
  23. 花の匂い
  24. 優しい歌
  25. END ROLL

Mr.Children"HOME"TOUR 2007 ~in the field~

  1. OPENING
  2. 彩り
  3. 名もなき詩
  4. 星になれたら
  5. シーソーゲーム~勇敢な恋の歌~
  6. CROSS ROAD
  7. Tomorrow never knows
  8. my life
  9. ひびき
  10. もっと
  11. HERO
  12. Imagine
  13. CENTER OF UNIVERSE
  14. Dance Dance Dance
  15. フェイク
  16. Any
  17. 口笛
  18. Sign
  19. ポケット カスタネット
  20. Worlds end
  21. 終わりなき旅
  22. しるし
  23. Wake me up!
  24. innocent world
  25. 旅立ちの唄
  26. END ROLL

Mr.Children “HOME” TOUR 2007

  1. OPENING
  2. 彩り
  3. and I love you
  4. youthful days
  5. 箒星
  6. Another Story
  7. もっと
  8. いつでも微笑みを
  9. PIANO MAN
  10. ランニングハイ
  11. Imagine
  12. CENTER OF UNIVERSE
  13. Dance Dance Dance
  14. フェイク
  15. Any
  16. to U
  17. タガタメ
  18. ポケット カスタネット
  19. Worlds end
  20. 終わりなき旅
  21. しるし
  22. あんまり覚えてないや
  23. overture ~ 蘇生
  24. 彩り

MR.CHILDREN DOME TOUR 2005“ I ♥ U ” ~ FINAL IN TOKYO DOME ~

  1. OPENING
  2. LOVEはじめました
  3. Dance Dance Dance
  4. ニシエヒガシエ
  5. 跳べ
  6. innocent world
  7. 言わせてみてぇもんだ
  8. くるみ
  9. CANDY
  10. 靴ひも
  11. 隔たり
  12. ファスナー
  13. Monster
    Bonus Track 抱きしめたい
    Bonus Track Simple
    Bonus Track Over
    Bonus Track 君が好き
    Bonus Track 2日遅れのクリスマス
  14. CENTER OF UNIVERSE
  15. ランニングハイ
  16. 名もなき詩
  17. ラララ
  18. overture~蘇生
  19. Worlds end
  20. Hallelujah
  21. and I love you
  22. 未来
  23. 僕らの音
  24. 潜水
  25. Sign
    Bonus Track 靴ひも
    Bonus Track 未来
    Bonus Track and I love you

Mr.Children Tour 2004 シフクノオト

  1. OPENING
  2. 終わりなき旅
  3. 光の射す方へ
  4. PADDLE
  5. 名もなき詩
  6. 口笛
  7. Everything(It's you)
  8. Pink~奇妙な夢
  9. 血の管
  10. ニシエヒガシエ
  11. Image
  12. overture~蘇生
    EX01. : SPECIAL LIVE at OKINAWA
    EX02. : SOCCER
  13. youthful days
  14. innocent world
  15. くるみ
  16. Any
  17. 天頂バス
  18. HERO~ENCORE~
  19. INTERVIEW
  20. Mirror
  21. MC
  22. Tomorrow Never Knows
  23. タガタメ
  24. Sign
    EX01: SPECIAL LIVE at OSAKA
    EX02: JEN'S PHOTO

wonederful world on DEC 21

  1. OPENING
  2. Dear wonderful world
  3. CENTER OF UNIVERSE
  4. NOT FOUND
  5. 名もなき詩
  6. 渇いたkiss
  7. Drawing
  8. つよがり
  9. MC
  10. 君が好き
  11. youthful days
  12. ファスナー
  13. Bird Cage
  14. ニシエヒガシエ
  15. LOVE はじめました
  16. ALIVE
  17. 終わりなき旅
  18. 光の射す方へ
    --- ENCORE ---
  19. 虹の彼方へ
  20. Any
  21. いつでも微笑みを
  22. overture
  23. 蘇生
  24. It's a wonderful world
  25. HERO
  26. HERO
  27. Dear wonderful world
  28. ファスナー
  29. いつでも微笑みを
  30. It's a wonderful world
  31. talks & interview

Mr.Children CONCERT TOUR POPSAURUS 2001

  1. OPENING
  2. I'll be
  3. ラララ
  4. 君がいた夏
  5. LOVE
  6. 星になれたら
  7. 車の中でかくれてキスをしよう
  8. 抱きしめたい
  9. Printing
  10. Dance Dance Dance
  11. Round About~孤独の肖像~
  12. Dive
  13. シーラカンス
  14. 手紙
  15. マシンガンをぶっ放せ
  16. ニシエヒガシエ
  17. 光の射す方へ
  18. 深海
  19. Tomorrow never knows
  20. Hallelujah
  21. everybody goes -秩序のない現代にドロップキック-
  22. innocent world
  23. 独り言
  24. 優しい歌

Mr.Children Concert Tour Q 2000~2001

  1. OPENING
  2. その向こうへ行こう
  3. 光の射す方へ
  4. ニシエヒガシエ
  5. 終わりなき旅
  6. Heavenly kiss
  7. クラスメイト
  8. ロードムービー
  9. 抱きしめたい
  10. Surrender
  11. つよがり
  12. 十二月のセントラルパークブルース
  13. スロースターター
  14. everybody goes-秩序のない現代にドロップキック-
  15. 名もなき詩
  16. CENTER OF UNIVERSE
  17. NOT FOUND
  18. Everything is made from a dream
  19. Hallelujah
    --- ENCORE ---
  20. 友とコーヒーと嘘と胃袋
  21. 口笛

TOUR '99 DISCOVERY

  1. OPENING
  2. DISCOVERY
  3. アンダーシャツ
  4. 名もなき詩
  5. Prism
  6. Everything(It's you)
  7. I'll be
  8. 花 -Memento-Mori-
  9. Simple
  10. ラヴ コネクション
  11. Dance Dance Dance
  12. ニシエヒガシエ
  13. ラララ
  14. Tomorrow never knows
  15. 終わりなき旅
  16. 光の射す方へ
    --- ENCORE ---
  17. everybody goes -秩序のない現代にドロップキック-
  18. Image

regress or progress '96~'97 IN TOKYO DOME

  1. OPENING
  2. 旅人
  3. ラヴ コネクション
  4. 傘の下の君に告ぐ
  5. Round About ~孤独の肖像~
  6. Dance Dance Dance
  7. 抱きしめたい
  8. Talk
  9. my life
  10. Dive
  11. シーラカンス
  12. 手紙
  13. ありふれた Love Story ~男女問題はいつも面倒だ~
  14. Mirror
  15. Making Songs
  16. 名もなき詩
  17. So Let´s Get Truth
  18. 臨時ニュース
  19. マシンガンをぶっ放せ
  20. ゆりかごのある丘から
  21. 花 -Memento-Mori-
  22. 深海
  23. Brandnew my lover
  24. タイムマシーンに乗って
  25. everybody goes -秩序のない現代にドロップキック-
  26. ALIVE
  27. Everything(It's you)
  28. ボレロ

JavaのSpringSecurityでAESの暗号化/復号化処理を実装する

サクっと作るなら以下が参考になります。

http://terasolunaorg.github.io/guideline/current/ja/Security/Encryption.html

暗号化

    public static String encryptTextByAesWithGcm(String secret, String salt, String plainText) {
        TextEncryptor aesTextEncryptor = Encryptors.delux(secret, salt);

        return aesTextEncryptor.encrypt(plainText);
    }

復号化

    public static String decryptTextByAesWithGcm(String secret, String salt, String cipherText) {
        TextEncryptor aesTextEncryptor = Encryptors.delux(secret, salt);

        return aesTextEncryptor.decrypt(cipherText);
    }

補足

ここからが個人的には重要

1.secretはプレーンテキストでいいのですが、saltはプレーンテキストではダメなので以下みたいになります。

String salt = new String(Hex.encodeHexString("salt".getBytes()));

2.参考サイト

暗号化の結果について
encryptメソッドの返り値 (暗号化の結果) は実行毎に異なる値を返すが、鍵とソルトが同一であれば復号処理の結果は同一になる (正しく復号できる) 。

の記載、初期化ベクトル (iv)の役割よるものです。
ivは、同じ鍵を使用して同じ平文データを複数回暗号化するときに異なる暗号文を生成します。
ivはランダムな値で、セッションごとに生成される。

セッションごと?確かにソースをSpringSecurityのソースを追っていくと、以下になっている。

    /**
     * Creates a standard password-based bytes encryptor using 256 bit AES encryption.
     * Derives the secret key using PKCS #5's PBKDF2 (Password-Based Key Derivation
     * Function #2). Salts the password to prevent dictionary attacks against the key. The
     * provided salt is expected to be hex-encoded; it should be random and at least 8
     * bytes in length. Also applies a random 16-byte initialization vector to ensure each
     * encrypted message will be unique. Requires Java 6. NOTE: This mode is not
     * <a href="https://en.wikipedia.org/wiki/Authenticated_encryption">authenticated</a>
     * and does not provide any guarantees about the authenticity of the data. For a more
     * secure alternative, users should prefer
     * {@link #stronger(CharSequence, CharSequence)}.
     * @param password the password used to generate the encryptor's secret key; should
     * not be shared
     * @param salt a hex-encoded, random, site-global salt value to use to generate the
     * key
     *
     * @see Encryptors#stronger(CharSequence, CharSequence)
     */
    public static BytesEncryptor standard(CharSequence password, CharSequence salt) {
        return new AesBytesEncryptor(password.toString(), salt, KeyGenerators.secureRandom(16));
    }

以下のJavaDocによると、、、

https://spring.pleiades.io/spring-security/site/docs/current/api/org/springframework/security/crypto/encrypt/AesBytesEncryptor.html

new AesBytesEncryptorの第三引数の KeyGenerators.secureRandom(16) がiv

確かに乱数

では、復号化にも同じ値のivがいるのかなと思ったらソース見たら以下のように暗号化後のテキストから取得しているようなので大丈夫そうでした。

    @Override
    public byte[] decrypt(byte[] encryptedBytes) {
        synchronized (this.decryptor) {
            byte[] iv = iv(encryptedBytes);
            CipherUtils.initCipher(this.decryptor, Cipher.DECRYPT_MODE, this.secretKey, this.alg.getParameterSpec(iv));
            return CipherUtils.doFinal(this.decryptor,
                    (this.ivGenerator != NULL_IV_GENERATOR) ? encrypted(encryptedBytes, iv.length) : encryptedBytes);
        }
    }

    private byte[] iv(byte[] encrypted) {
        return (this.ivGenerator != NULL_IV_GENERATOR)
                ? EncodingUtils.subArray(encrypted, 0, this.ivGenerator.getKeyLength())
                : NULL_IV_GENERATOR.generateKey();
    }

まとめ

ということで改めて復習です。

Secret:
Secretは一般的にユーザーが選択する文字列で、秘密情報を保護するために使用されます。
Secretベースのセキュリティでは、ユーザーのSecretから導かれた鍵を生成します。このとき、パスワードを安全に保管し、強力な鍵導出関数(PBKDF2、bcrypt、Scryptなど)を使用することが重要です。

Salt:
SaltはSecretベースのセキュリティで使用され、Secretに追加されるランダムなデータです。
Saltはユーザーごとに異なり、同じSecretを持つユーザーのハッシュ値を異なるものにします。これにより、レインボーテーブル攻撃から保護されます。

初期化ベクトル (iv):
ivは、同じ鍵を使用して同じ平文データを複数回暗号化するときに異なる暗号文を生成します。
ivはランダムな値で、セッションごとに生成される。

Javaコーディング規約・実装注意事項整理

Javaにおけるコーディング規約・実装注意事項整理

一般的なJavaのコーディング規約はよくGoogleとかにまとめられているのですが、いざ実際現場に適用すると多すぎて担当者が理解しきれないので、最低限を整理してみました。

観点として,全て共通する一般的な観点とクラス設計,エラー処理,マルチスレッド,性能と分けています。

参考書籍

こちらの本が良い本だったので影響を受けて自分でもまとめようと思いまとめました。

良いコード/悪いコードで学ぶ設計入門―保守しやすい 成長し続けるコードの書き方

一般的観点

  • メソッドやクラスの役割や責務を明確にし、シンプルな設計を心掛けること
  • インデントやスペース、命名規則などのコーディング規約に従い、一貫性のあるコードを書くこと
  • マジックナンバー(直接的な数値)を使わず、意味のある定数や列挙型を使用すること
  • メソッドやクラスの長さを適切に制御し、読みやすさを向上させること
  • 分岐処理では条件分岐を漏らさず記載し、必ずElse節を書くこと
  • 固定値はシステム設定の外部ファイルに定義し、リファクタリングや設定変更が容易にできるようにすること
  • データベースアクセスやネットワーク通信などの外部リソースにアクセスする際は、適切なエラーハンドリングを行い、リトライやロールバックなどのリカバリー処理を実装すること

クラス設計観点

  • メソッドの入力引数や戻り値の型には具体的なクラスやインターフェースを使用し、できる限り抽象化すること
  • 外部からのインプット引数/戻り値はnullである可能性を考慮し、適切なnullチェックを行うこと
  • 不変な変数には極力final修飾子を付け、再代入を防ぐこと

エラー処理観点

  • Catchに指定するExceptionは上位クラスのExceptionにまとめないこと
  • Catchした例外は必ずログに出力し、上位にThrowする際はCatchした例外を保持してThrowすること

マルチスレッド観点

  • マルチスレッド環境での競合状態を避けるために、適切な同期やロックを使用すること
  • 変数のスコープを意識して使用すること(サーブレット定義の変数はシングルトンとなる)
  • 使用するJavaライブラリの処理がスレッドセーフかどうか意識して使うこと(SimpleDateFormatなど)
  • マルチスレッド対応のクラス(ConcurrentHashMapやThreadLocalなど)を過信せず正しく使用すること

性能観点

  • リソースの解放漏れを避けるため、try-with-resources文を使用してリソースの自動クローズを行うこと
  • 文字列の連結や変更が頻繁に行われる場合は、StringBuilderやStringBufferを使用して効率的な文字列操作を行うこと
  • 大規模なループ処理の場合には、パフォーマンスを意識して最適化すること(無駄な処理や重複した操作の排除)
  • 再帰呼び出しを行う場合は、スタックオーバーフローのリスクに対処するために適切な終了条件を設定すること

まとめ

これら全てを理解して実装していくのは結構大変ですよね。
丸暗記ではなく,ダメな背景を理解して定期的に見直し,体の一部にしていきたいと思います。

SpringMVCを使ったJavaプログラムにおけるシングルトンとスタティック変数・メソッドの効果を検証してみた

マルチスレッドでのスタティック変数・メソッドの効果を検証してみた

JavaのSpringMVCを使用して、シングルトンパターンとスタティック変数、スタティックメソッドを実装してみました。これらはJavaアプリケーションでよく使用される概念なんですが、ちょっと混乱してきたので、自分なりの整理結果になります。詳細は以下をご覧ください。

検証ソース

  • コントローラソース
@Controller
@RequestMapping("/hello")
public class HelloWorldController {
    private int counter = 0;

    @RequestMapping("/thread")
    public ModelAndView thread(@RequestParam("id") String id) {
        System.out.println("Method: " + new Object(){}.getClass().getEnclosingMethod().getName());
        System.out.println("Parameter:" + id);

        counter = CommonUtil.countup(counter, id);

        CommonUtil com = new CommonUtil();
        counter = com.countdown(counter, id);

        String NewTime1 = CommonUtil.newtime(id);
        String NewTime2 = CommonUtil.newtime(id);

        System.out.println("NewTime1:" + NewTime1);
        System.out.println("NewTime2:" + NewTime2);
        ModelAndView modelAndView = new ModelAndView("thread");
        modelAndView.addObject("id", id);
        modelAndView.addObject("NewTime1", NewTime1);
        modelAndView.addObject("NewTime2", NewTime2);
        return modelAndView;
    }
}
  • 共通処理クラス
public class CommonUtil {

    public static int countup(int var, String id) {
        System.out.println("Method: " + new Object(){}.getClass().getEnclosingMethod().getName());
        var++;
        System.out.println(var);
        return(var);
    }

    public int countdown(int var, String id) {
        System.out.println("Method: " + new Object(){}.getClass().getEnclosingMethod().getName());
        var--;
        System.out.println(var);
        return(var);
    }

    public static String newtime(String id) {
        System.out.println("Method: " + new Object(){}.getClass().getEnclosingMethod().getName());
        // 現在日時を取得
        LocalDateTime now = LocalDateTime.now();
        // フォーマットを指定して文字列に変換
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        String nowStr = now.format(formatter);      
        System.out.println(nowStr);
        return(nowStr);
    }
}
  • 画面表示用HTML
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Thread</title>
</head>
<body>
  <h2>title</h2>
  <p th:text="${id}"></p>
  <p th:text="${NewTime1}"></p>
  <p th:text="${NewTime2}"></p>
</body>
</html>

ソースコードは単純だと思います。
キーはコントローラクラスの変数「private int counter = 0;」
これは SpringのDIコンテナで管理されている Controller のデフォルトのスコープだとシングルトンのためスレッドセーフではありません
では、それを検証していきましょう。

アクセスURL

/hello/thread?id=001
/hello/thread?id=002

マルチスレッドでの検証となるため、URLは二つ用意します。
ログが分かりやすいようにパラメータに id を付与します。
id 自体には処理結果に全く関係ありません。
では、結果です。

結果

順次処理の実行結果

まずは別々にアクセスが来た場合
カウントアップされ直後にカウントダウンされ 1 -> 0、1 -> 0 を繰り返す結果となります。

Method: thread
Parameter:001
Method: countup
1
Method: countdown
0
Method: newtime
2023/04/30 10:04:50
Method: newtime
2023/04/30 10:04:50
NewTime1:2023/04/30 10:04:50
NewTime2:2023/04/30 10:04:50
Method: thread
Parameter:002
Method: countup
1
Method: countdown
0
Method: newtime
2023/04/30 10:04:52
Method: newtime
2023/04/30 10:04:52
NewTime1:2023/04/30 10:04:52
NewTime2:2023/04/30 10:04:52

同時実行の実行結果

では、次に同時実行のケースです。
同時にリクエストが来た場合、以下の結果をなることがあります。
一時的に「counter = 2」になっていることが分かると思います。
要件として「counter」に何をカウントしたいかによりますが、このケースは予期せず起こったケースとなることが多いのではないでしょうか。
もし別々のリクエストでも同じカウントでトータルをカウントしたいケースを想定した場合、「private static int counter = 0;」と明示的にstatic変数にすべきと思います。

Method: thread
Parameter:001
Method: countup
1
Method: thread
Parameter:002
Method: countup
2
Method: countdown
1
Method: newtime
2023/04/30 10:14:05
Method: newtime
2023/04/30 10:14:05
NewTime1:2023/04/30 10:14:05
NewTime2:2023/04/30 10:14:05
Method: countdown
0
Method: newtime
2023/04/30 10:14:13
Method: newtime
2023/04/30 10:14:13
NewTime1:2023/04/30 10:14:13
NewTime2:2023/04/30 10:14:13

ちなみにこの動作確認のやり方としては、1つ目のリクエスト処理中に2つ目のリクエスト処理を先に処理させています。
具体的にはEclipseのデバック機能を使って以下のブレイクポイントを設定しておき、1つ目のリクエスト処理を止めておき、最初に2つ目のリクエスト処理を進めています。

今回は、変数「private int counter = 0;」がキーであるため、
CommonUtilのメソッド「public static int countup(int var, String id)」と「public int countdown(int var, String id)」は
敢えて、countupメソッドの方をstaticメソッドとしていますが、
いずれのケースでも変数「private int counter = 0;」をスタティック変数として使用している結果がわかると思います。
(もし、countdownメソッドの方がスタティック変数を使っていないければ、結果が0にならないはずなので)

補足結果

「public static String newtime(String id)」メソッドでは、変数「private int counter = 0;」を使用していません。
変わりに内部で作成した「String nowStr」を使用しています。
この変数はstaticメソッドのnewtimeメソッド内で作成されていますが、スレッドセーフな変数になります。

public static String newtime(String id) {
        System.out.println("Method: " + new Object(){}.getClass().getEnclosingMethod().getName());
        // 現在日時を取得
        LocalDateTime now = LocalDateTime.now();
        // フォーマットを指定して文字列に変換
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        String nowStr = now.format(formatter);      
        System.out.println(nowStr);
        return(nowStr);
    }

同時実行の実行結果

今回も同時実行して1つ目のリクエスト処理中に2つ目のリクエスト処理を先に処理させています。
ただし、今回は時間がそれぞれ正しく(上書きされずに)取得されて出力されていることがわかると思います。

Method: thread
Parameter:001
Method: countup
1
Method: countdown
0
Method: newtime
Method: thread
Parameter:002
Method: countup
1
Method: countdown
0
Method: newtime
2023/04/30 10:46:22
Method: newtime
2023/04/30 10:46:42
NewTime1:2023/04/30 10:46:22
NewTime2:2023/04/30 10:46:42
2023/04/30 10:46:03
Method: newtime
2023/04/30 10:47:12
NewTime1:2023/04/30 10:46:03
NewTime2:2023/04/30 10:47:12

今回のブレイクポイントは以下に設定しています。

ちなみに画面の表示結果は以下のようになります。

まとめ

最初に書いた通り、キーは変数「private int counter = 0;」です。
これはぱっと見ると、メンバ変数であり、スレッドセーフのように見えますが、SpringのDIコンテナで管理されているインスタントのデフォルトのスコープだと
シングルトン
のためスレッドセーフではありません。
これを常に意識して使いましょう。
補足としてメソッドがstaticかそうではないかは影響しないことが確認できました。

HTMLテーブルの列の表示非表示や行の入れ替えをJavaScriptで実装する方法

JavaScriptでtableを操作するサンプル

HTMLテーブルを操作することは、Web開発において重要なスキルの一つです。この記事では、JavaScriptを使ったHTMLテーブルの列の表示非表示や行の入れ替えの方法を解説します。

ドラッグドロップで列を入れ替える

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Tableの列の入れ替え</title>
  <style>
    table {
      border-collapse: collapse;
    }
    th, td {
      border: 1px solid #ccc;
      padding: 0.5rem;
      text-align: center;
      cursor: move;
    }
  </style>
</head>
<body>
  <table id="myTable">
    <thead>
      <tr>
        <th>名前</th>
        <th>年齢</th>
        <th>性別</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>山田太郎</td>
        <td>20</td>
        <td>男性</td>
      </tr>
      <tr>
        <td>鈴木花子</td>
        <td>25</td>
        <td>女性</td>
      </tr>
      <tr>
        <td>田中一郎</td>
        <td>30</td>
        <td>男性</td>
      </tr>
    </tbody>
  </table>

  <script>
    let draggingColumn;

    // ドラッグ開始時に実行する関数
    function handleDragStart(e) {
      // ドラッグされた列の位置を保存する
      draggingColumn = e.target.cellIndex;
    }

    // ドラッグオーバー時に実行する関数
    function handleDragOver(e) {
      // ドロップ先の列の位置を取得する
      const dropIndex = e.target.cellIndex;

      // ドラッグされた列とドロップ先の列が異なる場合
      if (draggingColumn !== dropIndex) {
        const rows = document.querySelectorAll('#myTable tbody tr');
        rows.forEach(row => {
          // ドラッグされた列とドロップ先の列のセルを取得する
          const draggingCell = row.cells[draggingColumn];
          const dropCell = row.cells[dropIndex];

          // ドラッグされた列をドロップ先の列の前に挿入する
          if (draggingColumn < dropIndex) {
            row.insertBefore(dropCell, draggingCell);
          } else {
            row.insertBefore(draggingCell, dropCell);
          }
        });
      }
    }

    // 各列にイベントリスナーを登録する
    const columns = document.querySelectorAll('#myTable th');
    columns.forEach(column => {
      column.setAttribute('draggable', true);
      column.addEventListener('dragstart', handleDragStart);
      column.addEventListener('dragover', handleDragOver);
    });
  </script>
</body>
</html>

このコードでは、各列にdragstart、dragoverの2つのイベントリスナーを登録しています。dragstartイベントが発生した際には、ドラッグされた列の位置を変数draggingColumnに保存しています。そして、dragoverイベントが発生した際には、ドロップ先の列の位置を変数dropIndexに取得し、ドラッグされた列とドロップ先の列が異なる場合には、querySelectorAllメソッドを用いてテーブルのtbody要素内にあるすべての行を取得し、forEachメソッドを用いて各行に対して以下の処理を実行しています。

1.ドラッグされた列とドロップ先の列のセルを取得する。
2.ドラッグされた列をドロップ先の列の前に挿入する。

こうすることで、列の入れ替えを実現することができます。

ボタン操作で行を入れ替える

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Move Table Row Sample</title>
    <style>
      table {
        border-collapse: collapse;
      }
      th, td {
        border: 1px solid black;
        padding: 0.5em;
      }
      .dragged {
        opacity: 0.5;
      }
    </style>
  </head>
  <body>
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Age</th>
        <th>Gender</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>John Doe</td>
        <td>25</td>
        <td>Male</td>
        <td><button onclick="moveUp(this)">Up</button><button onclick="moveDown(this)">Down</button></td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jane Smith</td>
        <td>30</td>
        <td>Female</td>
        <td><button onclick="moveUp(this)">Up</button><button onclick="moveDown(this)">Down</button></td>
      </tr>
      <tr>
        <td>3</td>
        <td>Bob Johnson</td>
        <td>40</td>
        <td>Male</td>
        <td><button onclick="moveUp(this)">Up</button><button onclick="moveDown(this)">Down</button></td>
      </tr>
      <tr>
        <td>4</td>
        <td>Alice Williams</td>
        <td>35</td>
        <td>Female</td>
        <td><button onclick="moveUp(this)">Up</button><button onclick="moveDown(this)">Down</button></td>
      </tr>
    </tbody>
  </table>
  <script>
    function moveUp(button) {
      const row = button.parentNode.parentNode;
      if (row.previousElementSibling) {
        row.parentNode.insertBefore(row, row.previousElementSibling);
      }
    }
    function moveDown(button) {
      const row = button.parentNode.parentNode;
      if (row.nextElementSibling) {
        row.parentNode.insertBefore(row.nextElementSibling, row);
      }
    }
  </script>
  </body>
</html>

このサンプルでは、

要素内の行をドラッグして入れ替えることができます。行をドラッグしたとき、dragstartイベントが発生して、ドラッグ中の行を保持します。ドラッグ中の行が他の行の上に移動すると、dragoverイベントが発生して、ドラッグ中の行を他の行の前または後ろに移動します。行をドロップすると、dragendイベントが発生して、ドラッグ中の行をリセットします。

列の一部を非表示にする

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>テーブルの列の表示非表示を切り替えるサンプル</title>
  <script>
    function hideColumn(columnIndex) {
      var table = document.getElementsByTagName("table")[0];
      var rows = table.rows;
      for (var i = 0; i < rows.length; i++) {
        rows[i].cells[columnIndex].style.display = "none";
      }
    }

    function showColumn(columnIndex) {
      var table = document.getElementsByTagName("table")[0];
      var rows = table.rows;
      for (var i = 0; i < rows.length; i++) {
        rows[i].cells[columnIndex].style.display = "";
      }
    }
  </script>
</head>
<body>
  <table>
    <thead>
      <tr>
        <th>名前</th>
        <th>年齢</th>
        <th>メールアドレス</th>
        <th>電話番号</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>山田 太郎</td>
        <td>25</td>
        <td>taro.yamada@example.com</td>
        <td>012-345-6789</td>
      </tr>
      <tr>
        <td>鈴木 次郎</td>
        <td>30</td>
        <td>jiro.suzuki@example.com</td>
        <td>03-1234-5678</td>
      </tr>
    </tbody>
  </table>
  <button onclick="hideColumn(1)">2番目の列を非表示にする</button>
  <button onclick="showColumn(1)">2番目の列を表示する</button>
</body>
</html>

上記のコードでは、hideColumn関数を使用して、2番目の列を非表示にし、showColumn関数を使用して、2番目の列を表示することができます。

行の一部を非表示にする

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hide Table Row Sample</title>
    <style>
      .hidden {
        display: none;
      }
    </style>
  </head>
  <body>
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Age</th>
          <th>Gender</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>John Doe</td>
          <td>30</td>
          <td>Male</td>
        </tr>
        <tr>
          <td>Jane Smith</td>
          <td>25</td>
          <td>Female</td>
        </tr>
        <tr>
          <td>Bob Johnson</td>
          <td>40</td>
          <td>Male</td>
        </tr>
      </tbody>
    </table>

    <button onclick="toggleGender('Male')">Toggle Male Rows</button>

    <script>
      function toggleGender(gender) {
        const rows = document.querySelectorAll('table tbody tr');
        rows.forEach((row) => {
          const genderCell = row.querySelector('td:nth-child(3)');
          if (genderCell.innerText === gender) {
            row.classList.toggle('hidden');
          }
        });
      }
    </script>
  </body>
</html>

このサンプルでは、各行の3列目(Gender列)の値がMaleである行を非表示にするために、行全体にhiddenクラスを追加します。toggleGender()関数は、ボタンがクリックされたときに、各行のGender列の値が引数で指定された値(この場合はMale)と一致する場合に、その行を表示または非表示に切り替えるために、行全体に対してhiddenクラスをトグルします。

やる気が溢れる 元気が出る Mr.Children エネルギーソング

仕事に前向きになれるエンジニア的 Mr.Children エネルギーソング

私は普段エンジニアとして生活しているのですが、Mr.Childrenは毎日と言っていいほど助けられているので、そんな日々を定期的に振り返り元気をもらうための場としてこの記事を投稿しました。

エンジニアの仕事に関わらずかもしれませんが,仕事はいい事ばかりではなく,どちらかというといろんなしがらみがあって大変です。 そんな時に私が心の拠り所にしているミスチルソングをランキング形式で紹介します。

実際に聞くのは断然ライブ映像がオススメです♪
歌からもらえるエネルギーが200%増しなのでオススメのライブも紹介します。

ライブごとのオススメは次の記事でまとめていきます♪

Mr.Children映像化ライブセットリスト集

個人的 TOP10 紹介

10位.星になれたら

長く助走をとった方がより
遠くに飛べるって聞いた

いつも良い事ばかりではないけど
コツコツ頑張っていれば
頑張った分だけ良い事が起こそうで🙂

星になれたら ライブは結構レアだと思います
オススメは SENSE -in the field-

Mr.Children STADIUM TOUR 2011 SENSE -in the field-【Blu-ray】 [ Mr.Children ]

9位.ヨーイドン

数字やデータで未来はつくれない
ぽかりと空いた心の穴埋め問題は一人では解けない

仕事ってよく結果だって言われますよね
でも仕事のやりがいってきっとそれだけじゃない

ヨーイドン はまだライブで歌われていないのですよね
名曲なのに♪

8位.Prelude

前奏曲(プレリュード)が聞こえてくる
さぁ 耳を澄ませてごらん

仕事で新しい事を始める時は不安がいっぱい
でも心の中にあるワクワク感にも目を向けたい

一言
このライブの Prelude やばいです かなりお気に入りです

Mr.Children Dome Tour 2019 “Against ALL GRAVITY”【Blu-ray】 [ Mr.Children ]

7位.幻聴

一歩 また一歩 確実に進む そんなイメージを忘れずに

辛いことには必ず終わりがある
諦めずに1歩、1歩進んで
3ヶ月かかった課題がやっと昨日で解決😊

おすすめは 重力と呼吸
このライブ自体全体的に頑張っていこうという雰囲気が漂っていて好きです♪

Mr.Children Tour 2018-19 重力と呼吸【Blu-ray】 [ Mr.Children ]

6位.ALIVE

迷いや悩みなど一生消えぬものと思えたなら
ボクらはスーパーマン

迷いや悩みのない人なんていない
みんなそれぞれの場所で頑張ってる
人と比べることに意味はない

古い曲ですが、未完ライブで歌われた名曲です♪
Mr.Children Stadium Tour 2015 未完

5位.I\'ll be

いつも心にしてたアイマスクを外してやればいい
不安や迷いと無二の親友になれればいい
旅立とう 明日は無いぞってな具合に
胸に刻みながら一歩ずつ進んで
いつだって夢中だ

時にはトラブル続きで終わらない日々もある
だけど何事にも必ず終わりはある
だからこの曲♪

不安や迷いと無二の親友になれればいいという表現が天才だと思う
名曲だけどライブで歌われたのはかなりレア
CONCERT TOUR POP SAURUS 2001

4位.未来

自分を信じたなら ほら未来が動き出す

何かが終わる一方で始まることもあるタイミングの時はこの曲♪
何事も前向きに捉えて頑張ろう

SENSE -in the field-で歌われている名曲です♪

Mr.Children STADIUM TOUR 2011 SENSE -in the field-【Blu-ray】 [ Mr.Children ]

3位.皮膚呼吸

苦しみに息が詰まったときも
また姿 変えながら
そう今日も 自分を試すとき

仕事なので時には大変な時もある
プレッシャーは期待の裏返し
と 捉え方を変えて頑張るぞ!
という曲♪

2回目の Against ALL GRAVITY ですが
こちらはしっとりと歌い上げます

Mr.Children Dome Tour 2019 “Against ALL GRAVITY”【Blu-ray】 [ Mr.Children ]

2位.彩り

僕のした単純作業が
この世界を回り回って
まだ出合ったこともない人の笑い声を作ってゆく

仕事の曲というとこの曲を一番最初に思い出す気がする♪
年の節目とか定期的に思い出したい曲
彩りをモットーに明日からも頑張ろう

オススメLIVEは彩りといったらこれ
HOME~in the field~

Mr.Children HOME TOUR 2007 -in the field- [ Mr.Children ]

1位.Worlds end

僕らはきっと試されてる
どれくらいの強さで
明日を信じていけるのかを

辛いとき苦しい時
それでも頑張って最後に結果が出るかどうかって
この言葉がすべての真理なんだと思う

Worlds end のオススメライブはやっぱり30周年記念LIVE半世紀へのエントランスです♪

Mr.Children 30th Anniversary Tour 半世紀へのエントランス

まとめ

あくまでも今の自分に響く曲なので、定期的に見直すかもしれません。 何よりミスチルの曲を10曲だけ選ぶなんて普通はできない(^^;) 全部素晴らしい曲なので。

AWS Lambda 入門~おすすめ本5冊の紹介~

概要〜サーバレス基礎からAmplifyを使った本格開発までのおすすめ書籍〜

最近、AWS Lambdaの本増えてきましたよね。ということで今回はLambdaのおすすめ本の紹介です。

基礎編から本格的な専門書、アーキテクト、実際にAmplifyを使った開発と徐々にレベルアップする内容になっているのでLambdaを学びたい人は一つずつ読んでいってみてください。

Lambdaおすすめ本 5冊

今回紹介するAWS Lambdaのおすすめ本の一覧です。
忙しい方はここだけ確認してください。

基礎から学ぶ サーバーレス開発

基礎から学ぶ サーバーレス開発

まずは基本編です。Lambdaというかサーバレスとは?という導入編です。サーバレスとはどういうものか丁寧に書かれています。まずはサーバでの開発と比較してサーバレスにはどういったメリットデメリットがあるのかこの本で学びましょう。

目次

  • CHAPTER 01 サーバーレスとは
    • 1 サーバーレスの概要
    • 2 サーバーレスが注目された要因と新たなる課題
    • 3 サーバーレスのメリット・デメリット
  • CHAPTER 02 サーバーレス開発でよく使うサービス
    • 4 AWS Lambda
    • 5 Amazon API Gateway
    • 6 Amazon Aurora Serverless
    • 7 Amazon CloudWatch
    • 8 Amazon Simple Queue Service (Amazon SQS)
    • 9 AWS CodeCommit
    • 10 AWS CodePipeline
    • 11 AWS CodeBuild
    • 12 AWS CodeDeploy
    • 13 Amazon Simple Storage Service (Amazon S3)
    • 14 AWS Step Functions
    • 15 Amazon DynamoDB
    • 16 AWS Cloud9
    • 17 AWS X-Ray
  • CHAPTER 03 サーバーレスアプリケーションの構築
    • 18 フレームワーク
    • 19 CI/CD
    • 20 AWSにおけるCI/CD
    • 21 デプロイ手法
    • 22 トラフィックシフト
    • 23 昇格
  • CHAPTER 04 サーバーレスの運用監視
    • 24 サーバーレスのコスト
    • 25 サーバーレスにおける監視
  • CHAPTER 05 サーバーレス開発におけるセキュリティ
    • 26 サーバーレス開発におけるセキュリティの考え方
    • 27 Lambda@Edgeの利用
  • CHAPTER 06 サーバーレスの構築例
    • 28 完全サーバーレスでのWebページ構築事案
    • 29 完全サーバーレスでのWebページのバッチ部分
    • 30 APIバックエンドにAmazon RDSを用いた事例および2019年のアップデートについて
    • 31 サーバーレスで作る在宅勤務中の勤務時間登録システム
    • 32 AWS LambdaをAlexaのエンドポイントとして使う事例
  • CHAPTER 07 サーバーレスの失敗談と問題解決
    • 33 失敗談①~Amazon RDSを起動させ続けた
    • 34 失敗談②~AWS Lambda でスロットリングが発生してしまった
    • 35 SPA+サーバーレスで再読み込みをするとAccessDeniedになってしまう問題の解決方法

AWSではじめる クラウド開発入門

AWSではじめる クラウド開発入門

東大の人気授業が書籍化された内容です。Lambdaに限らずクラウド開発入門という位置付けなのでいろんな開発内容が書かれていて、クラウドでこうやって開発するんだとわかる内容になってます。最後の方は、かなり実践的で勉強になります。

目次

  • Chapter 1 はじめに
    • 1-1 本書の目的内容
    • 1-2 本書のフィロソフィー
    • 1-3 AWS アカウント
    • 1-4 環境構築
    • 1-5 前提知識
    • 1-6 本書で使用する表記について
  • Chapter 2 クラウド概論
    • 2-1 クラウドとは?
    • 2-2 なぜクラウドを使うのか?
  • Chapter 3 AWS入門
    • 3-1 AWSとは?
    • 3-2 AWSの機能・サービス
    • 3-3 Region と Availability Zone
    • 3-4 AWSでのクラウド開発
    • 3-5 CloudFormationとAWS CDK
  • Chapter 4 Hands-on #1:初めてのEC2インスタンスを起動する
    • 4-1 準備
    • 4-2 SSH
    • 4-3 アプリケーションの説明
    • 4-4 プログラムを実行する
    • 4-5 小括
  • Chapter 5 Hands-on #2: AWS でディープラーニングを実践
    • 5-1 なぜ機械学習をクラウドで行うのか?
    • 5-2 GPU による深層学習の高速化
    • 5-3 準備
    • 5-4 アプリケーションの説明
    • 5-5 スタックのデプロイ
    • 5-6 ログイン
    • 5-7 Jupyter Notebook の起動
    • 5-8 PyTorch はじめの一歩
    • 5-9 実践ディープラーニング! MNIST手書き数字認識タスク
    • 5-10 スタックの削除
  • Chapter 6 Docker 入門
    • 6-1 クラウドシステムの構築に向けて
    • 6-2 機械学習の大規模化
    • 6-3 Docker とは
    • 6-4 Docker チュートリアル
    • 6-5 Elastic Container Service (ECS)
  • Chapter 7 Hands-on #3 : AWS で自動質問回答ボットを走らせる
    • 7-1 Fargate
    • 7-2 準備
    • 7-3 Transformer を用いた question-answering プログラム
    • 7-4 アプリケーションの説明
    • 7-5 スタックのデプロイ
    • 7-6 タスクの実行
    • 7-7 タスクの同時実行
    • 7-8 スタックの削除
  • Chapter 8 Hands-on #4: AWS Batch を使って機械学習のハイパーパラメータサーチを並列化する
    • 8-1 クラウドを用いた機械学習モデルの最適化
    • 8-2 AWS Batch
    • 8-3 準備
    • 8-4 MNIST 手書き文字認識(再訪)
    • 8-5 アプリケーションの説明
    • 8-6 スタックのデプロイ
    • 8-7 Docker image を ECR に配置する
    • 8-8 単一のジョブを実行する
    • 8-9 並列に複数の Job を実行する
    • 8-10 スタックの削除
    • 8-11 クラウドを用いた機械学習アプリケーションの開発とデバッグ
    • 8-12 小括
  • Chapter 9 ウェブサービスの作り方
    • 9-1 個人のためのクラウドからみんなのためのクラウドへ
    • 9-2 ウェブサービスの仕組み Twitter を例に
    • 9-3 REST API
    • 9-4 Twitter API
  • Chapter 10 Serverless architecture
    • 10-1 Serverful クラウド (従来型)
    • 10-2 Serverless クラウドへ
    • 10-3 サーバーレスクラウドを構成するコンポーネント
  • Chapter 11 Hands-on #5: サーバーレス入門
    • 11-1 Lambda ハンズオン
    • 11-2 DynamoDB ハンズオン
    • 11-3 S3 ハンズオン
  • Chapter 12 Hands-on #6: Bashoutter
    • 12-1 準備
    • 12-2 アプリケーションの説明
    • 12-3 アプリケーションのデプロイ
    • 12-4 API リクエストを送信する
    • 12-5 大量のAPIリクエストをシミュレートする
    • 12-6 Bashoutter GUI を動かしてみる
    • 12-7 アプリケーションの削除
    • 12-8 小括
  • Chapter 13 Hands-on #7: boto3 道場
    • 13-1 boto3 の基本
    • 13-2 S3 道場
    • 13-3 DynamoDB 道場
    • 13-4 小括
  • Chapter 14 Hands-on #8: シン・Bashoutter
    • 14-1 シン・Bashoutter プロジェクトの概要
    • 14-2 STEP1:ドメインの設定とCloudFront の配置
    • 14-3 STEP2:Cognito によるユーザー認証の追加
  • Chapter 15 Hands-on #9: 深層学習を用いたアート自動生成アプリケーション
    • 15-1 Neural Art Canvas プロジェクト
    • 15-2 Neural style transfer
    • 15-3 ローカルで Neural style transfer を実行
    • 15-4 Step Functions
    • 15-5 Lambda layers
    • 15-6 アプリケーションの説明
    • 15-7 アプリケーションのデプロイ
    • 15-8 画像の生成 (コマンドラインから)
    • 15-9 画像の生成 (GUIから)
    • 15-10 アプリケーションの削除
  • Appendix 環境構築
    • A-1 本書で必要な計算機環境
    • A-2 AWS アカウントの取得
    • A-3 AWS のシークレットキーの作成
    • A-4 AWS CLI のインストール
    • A-5 AWS CDKのインストール
    • A-6 WSL のインストール
    • A-7 Docker のインストール
    • A-8 Python venv クイックガイド
    • A-9 ハンズオン実行用の Docker image の使い方

AWS Lambda実践ガイド 第2版 impress top gearシリーズ

AWS Lambda実践ガイド 第2版

ここからがLambdaの本格化書籍です。まずはLambdaの専門書といったらこれという一冊です。人気本で第二版も発売されてます。Lambdaの基礎からSAMを使った本格化開発まで記載されている良書です。Lambdaの専門書としてまずはこの本をおさえた方が良い内容になってます。

基本を抑えつつ現場で役に立つバージョン管理やエイリアスといった運用面の記載や、コールドスタートやコネクションなど現場で知っておかなければならない制限事項についても書かれており、本当にLambdaと言ったらこれという良書だと思います。

目次

  • 第1章 Lambda で実現するサーバーレスシステム
  • 第2章 Lambda 事始め
  • 第3章 Lambda の実行環境とイベント
  • 第4章 Lambda の開発環境と SAM
  • 第5章 S3 のイベント処理
  • 第6章 API Gateway、DynamoDB、SES との連携
  • 第7章 SQS やSNS を使った連携

AWSによるサーバーレスアーキテクチャ

AWSによるサーバーレスアーキテクチャ

アーキテクト部分からの一冊です。サーバレスアーキテクチャの本ということですが、Lambdaの解説書になっているのでLambdaの専門書という一面もあります。基礎からアーキテクトまで書かれていて参考になります。

目次

  • 第1部 導入
    • 第1章 サーバーレスの世界へ
      • 1.1 ここに至るまでの流れ
      • 1.2 サーバーレスアーキテクチャの原則
      • 1.3 サーバーからサーバーレスへの乗り換え
      • 1.4 サーバーレスの長所と短所
      • 1.5 まとめ
    • 第2章 アーキテクチャとパターン
      • 2.1 ユースケース
      • 2.2 アーキテクチャ
      • 2.3 パターン
      • 2.4 まとめ
    • 第3章 サーバーレスアプリケーションの構築
      • 3.1 24-Hour Video
      • 3.2 Amazon SNS の設定
      • 3.3 動画ファイルのアクセス権限の設定
      • 3.4 メタデータの生成
      • 3.5 仕上げ
      • 3.6 演習問題
      • 3.7 まとめ
    • 第4章 クラウドの設定
      • 4.1 セキュリティモデルとID管理
      • 4.2 ログとアラート
      • 4.3 料金
      • 4.4 演習問題
      • 4.5 まとめ
  • 第2部 コア機能
    • 第5章 認証と認可
      • 5.1 サーバーレス環境における認証
      • 5.2 24-Hour Videoへの認証の追加
      • 5.3 AWS との統合
      • 5.4 委任 トークン
      • 5.5 演習問題
      • 5.6 まとめ
    • 第6章 オーケストレーターとしての AWS Lambda
      • 6.1 AWS Lambdaの内部
      • 6.2 プログラミングモデル
      • 6.3 バージョニング、エイリアス、環境変数
      • 6.4 CLI の使い方
      • 6.5 AWS Lambdaのパターン
      • 6.6 Lambda関数のテスト
      • 6.7 演習問題
      • 6.8 まとめ
    • 第7章 Amazon API Gateway
      • 7.1 インターフェイスとしてのAmazon API Gateway
      • 7.2 Amazon API Gateway の操作
      • 7.3 ゲートウェイの最適化
      • 7.4 ステージとバージョン
      • 7.5 演習問題
      • 7.6 まとめ
  • 第3部 アーキテクチャの拡張
    • 第8章 ストレージ
      • 8.1 賢いストレージ
      • 8.2 セキュアなアップロード
      • 8.3 ファイルへのアクセス制限
      • 8.4 演習問題
      • 8.5 まとめ
    • 第9章 データベース
      • 9.1 Firebase 入門
      • 9.2 24-Hour VideoへのFirebase の追加
      • 9.3 ファイルへのアクセスの保護
      • 9.4 演習問題
      • 9.5 まとめ
    • 第10章 仕上げの学習
      • 10.1 デプロイとフレームワーク
      • 10.2 よりよいマイクロサービスのために
      • 10.3 AWS Step Functions
      • 10.4 AWS Marketplaceが開くビジネスチャンス
      • 10.5 これからの展開のために
  • 付録A サーバーレスアーキテクチャのためのサービス
    • A.1 Amazon API Gateway
    • A.2 Amazon SNS (Simple Notification Service)
    • A.3 Amazon 53 (Simple Storage Service)
    • A.4 Amazon SQS (Simple Queue Service)
    • A.5 Amazon SES (Simple Email Service)
    • A.6 Amazon RDS (Relational Database Service) & Amazon DynamoDB
    • A.7 Amazon CloudSearch
    • A.8 Amazon Elastic Transcoder
    • A.9 Amazon Kinesis Data Streams
    • A.10 Amazon Cognito
    • A.11 Auth0
    • A.12 Firebase
    • A.13 その他のサービス
  • 付録B インストールとセットアップ
    • B.1 システムの準備
    • B.2 IAM ユーザーとCLI のセットアップ
    • B.3 ユーザーアクセス権限の設定
    • B.4 新しいS3バケットの作成
    • B.5 IAMロールの作成
    • B.6 Lambda関数のための準備
    • B.7 Amazon Elastic Transcoder の設定
    • B.8 npm のセットアップ
  • 付録C 認証と認可について
    • C.1 認証と認可の基本
    • C.2 JWT
  • 付録D AWS Lambdaの内部
    • D.1 実行環境
    • D.2 制限
    • D.3 古いランタイムの扱い方
  • 付録 E モデルとマッピング
    • E.1 動画リストの取得
  • 付録 F Amazon S3のイベントメッセージ構造
    • F.1 S3 イベントメッセージの構造
    • F.2 覚えておくべきこと
  • 付録 G Serverless Framework & AWS SAM
    • G.1 Serverless Framework
    • G.2 AWS SAM
    • G.3 まとめ

AWS Amplify Studioではじめるフロントエンド+バックエンド統合開発

AWS Amplify Studioではじめるフロントエンド+バックエンド統合開発

最後はより実践編という位置付けでAmplifyを使った開発の内容の本にしました。Lambdaの基礎ではないため、これまでの本で基礎をおさえつつ再度のAmplifyでアプリ開発の本格入門という位置付けの本のしています。Amplify自体いろんな機能があって覚えることがたくさんなのですが、それら丁寧に解説してくれる内容になってます。

Lambdaの真価が問われるのはバックエンドとしてフロントエンドから連携されたアプリだと思っており、それを簡単に実現してくれるAmplifyには個人的には非常に期待しています。本の内容としては、Amplifyの一機能としてLambdaの使用方法を説明した内容になるのでLambdaに特化した内容ではないのですが、実業務でのLambdaで完結することはあまりないと思うで、一番実践に近い本だと思っています。

目次

  • Chapter1 AWS Amplifyを使おう
    • 1.1. AWS Amplifyを準備する
    • 1.2. サンプルアプリを作成する
  • Chapter2 Amplify Studioでバックエンドを設計する
    • 2.1. Reactアプリケーションの作成
    • 2.2. Amplify Studioとユーザー認証
    • 2.3. データモデルの設計
  • Chapter3 FigmaによるUI設計
    • 3.1. Figmaの基本操作
    • 3.2. Figmaでデザインする
    • 3.3. グラフィックの作成
    • 3.4. データモデル用のコンポーネントの利用
  • Chapter4 Reactによるフロントエンド開発
    • 4.1. Reactアプリケーションの基本
    • 4.2. Reactコンポーネントの設計
    • 4.3. ステートフックと副作用フック
    • 4.4. Reactコンポーネントを活用する
  • Chapter5 DataStoreによるデータベースアクセス
    • 5.1. コレクションコンポーネントの利用
    • 5.2. ReactとDataStoreの利用
    • 5.3. モデルデータの操作
  • Chapter6 GraphQLによるデータの利用
    • 6.1. Amplify MockとGraphQL
    • 6.2. コードからGraphQLを利用する
    • 6.3. GraphQLによるデータの書き換え
  • Chapter7 S3ストレージとLambda関数
    • 7.1. Amazon S3の利用
    • 7.2. ファイルの基本操作
    • 7.3. Lambda関数の利用
    • 7.4. LambdaからAWSの機能を使う
  • Chapter8 JavaScriptベースによるフロントエンド開発
    • 8.1. JavaScriptベースのアプリケーション作成
    • 8.2. Amplifyの機能を利用する

LINE Messaging API を使ってAWS Lambdaに連携する

概要

最近、LINE Messaging API x AWS Lambda x Google スプレッドシート を連携してサクッと便利ツールを作っている日々です♪
個人的にサクッと作れる便利ツールとして、UILINE Messaging APIにして、ロジックAWS Lambdaに、DBGoogle スプレッドシートで作るという構成が簡単に出来て気に入っています。

そこで今回はLINE Messaging API x AWS Lambda の連携編になります。
LINE Messaging API と AWS Lambda をWebhookを使ってHTTPSで連携します。
LINE Developersアカウントがあれば誰でも簡単・無料で出来るので、気になった人はやってみてください。

Lambdaの良書が増えてきたので、おすすめ本5冊を以下で紹介しています。Lambdaについて本格的に勉強したい方はぜひ読んでみてください。

AWS Lambdaおすすめ書籍5冊の紹介

前提条件

  • LINE Developersアカウント(LINE Business ID)取得
    • 無料で作成できるのでアカウントがない人は取得しましょう。
  • AWS Lambda関数の HTTP(S) エンドポイント割り当て
    • LINEからLambdaに連携するために、Lambda関数にHTTP(S) エンドポイントが必要になります。Lambdaを作成する際に、関数 URL を有効化する方法が簡単ですが、アクセス制御はしっかり行ってHTTP(S) エンドポイントを公開しましょう。

公式ページ

Messaging APIを始めよう
https://developers.line.biz/ja/docs/messaging-api/getting-started/

LINE Developersにログイン

まずは、LINEにログインします。
LINE Developersアカウント(LINE Business ID)を作成していない人はアカウントを作成から作成します。

https://account.line.biz/login

プロバイダー/チャネル作成 

ログイン後、LINE DevelopersコンソールというLINEの画面でプロバイダーチャネルを作成します。

  • プロバイダー:サービスを提供し、ユーザーの情報を取得する開発者個人、企業、または団体等のことです。個人で運用する場合は自由に登録すれば良いと思います。
  • チャネル:LINEが提供する機能を、サービス提供者が利用するための通信路です。今回の場合は、AWS Lambdaと LINE Messaging API を使って連携するLINEアプリのことです。

参考ページ
https://developers.line.biz/ja/docs/line-developers-console/overview/

プロバイダー作成

それではプロバイダーから作成していきます。
LINE Developersコンソールの画面操作だけで作成できるので簡単です。

LINE Developersコンソールにログイン後、表示される左メニューのプロバイダーを選択しし、プロバイダーの作成を選択します。

作成画面が表示されるため、任意のプロバイダー名を入力し、作成ボタンで作成されます。
簡単ですね。

チャネル作成

続いてチャネルの作成に移ります。
こちらもLINE Developersコンソールの画面操作だけで作成できます。

プロバイダーを選択する(今回は、AWS Lambdaとの連携が目的なのでLambdaProviderというプロバイダーを作成しています)と、チャネルの設定画面が表示されるため、AWS Lambdaと連携する Messaging API をクリックします。

チャネルの種類Messaging API になっていること、プロバイダー作成したプロバイダーになっていることを確認しましょう。あとは、必須項目を自身の情報で入力すれば大丈夫です。
利用規約を確認して、作成ボタンを押しましょう。

チャネル設定

無事にチャネルが作成されたらチャネルの設定に移ります。
この設定作業でAWS Lambdaとの連携情報認証情報LINEアプリの応答メッセージの設定などを行います。

作成したチャネルを選択します。(今回は、MessagingLambdaというチャネル名で作成しています)

Messaging API設定をクリックします。

ページ中央にあるWebhook URLに連携するAWS Lambdaの公開されたURLを編集ボタンを押して設定します。

URLを設定すると、検証ボタンやWebhookの利用Webhookの再送エラーの統計情報の設定ができるようになるので、必要な設定を行います。
Webhookの利用は必ず必要になるので、必ずONにします。

ページ下部にあるチャネルアクセストークンを設定します。
LambdaからこのLINEアプリに連携する際に指定するキーになる情報なので外部に漏れないないように管理しましょう。

応答/あいさつメッセージのカスタマイズ

ページ中央部にある応答メッセージあいさつメッセージ編集ボタンからこのLINEアプリにメッセージを送った時の応答メッセージLINEアプリを友だち追加した時のあいさつメッセージを編集できます。必要であれば編集しましょう。

編集ボタンをクリックすると以下の応答設定用の専用画面が表示されるため、専用画面で設定を変更します。

今回、AWS Lambdaから応答メッセージを自動作成して送信予定のため、応答メッセージオフに設定します。

AWS Lambdaの実装

いよいよここからはAWS Lambda側の実装になります。
前提条件のところに書きましたが、LINEと連携するためHTTP(S) エンドポイントが公開されているLambda関数の使用が前提になります。
今回は、最も基本的なLINEからLambdaにメッセージを送った時にLambdaからLINEへの応答メッセージを送る方法と、LambdaからLINEへプッシュメッセージを送る方法を記載します。

応答メッセージを送る

LINEからLambdaにメッセージを送った時に送られたメッセージをもとにして応答メッセージを送信するAPIは以下になります。

https://developers.line.biz/ja/reference/messaging-api/#send-reply-message

具体的には以下のhttpsリクエストを応答メッセージとして送信する必要があります。

curl -v -X POST https://api.line.me/v2/bot/message/reply \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer {channel access token}' \
-d '{
    "replyToken":"{Reply token}",
    "messages":[
        {
            "type":"text",
            "text":"Hello, user"
        },
        {
            "type":"text",
            "text":"May I help you?"
        }
    ]
}'

  • channel access token:LINE Developersコンソールで発行したチャネルアクセストークンを設定します。
  • Reply token:メッセージのやり時の度にLINEからLambdaに送られたリクエストメッセージの中からReply tokenを取得して設定します。

LINEから送られてくるリクエストメッセージのReply tokenの具体例は以下になります。replyToken部から取得しましょう。
text部にLINEから送られてくるメッセージが格納されており、userId部がLINEの送信者を特定するIDになります。(userIdは次の「プッシュメッセージを送る」で使用します)

{
  "destination": "xxxxxxxxxx",
  "events": [
    {
      "type": "message",
      "message": {
        "type": "text",
        "id": "14353798921116",
        "text": "Hello, world"
      },
      "timestamp": 1625665242211,
      "source": {
        "type": "user",
        "userId": "U80696558e1aa831..."
      },
      "replyToken": "{Reply token}",
      "mode": "active",
      "webhookEventId": "01FZ74A0TDDPYRVKNK77XKC3ZR",
      "deliveryContext": {
        "isRedelivery": false
      }
    }
  ]
}

実際にLambdaで replyToken を取得して、応答メッセージを送信するサンプルは以下になります。

import json
import requests
from pprint import pprint

def lambda_handler(event, context):
    #=========================
    # LINEからのリクエスト解析
    #=========================
    bodyjson = json.loads(event['body'])
    messagetext = bodyjson['events'][0]['message']['text']
    print("messagetext: " + messagetext)
    replyToken = bodyjson['events'][0]['replyToken']
    print("replyToken: " + replyToken)

    #=========================
    # LINEへのレスポンス作成
    #=========================
    resmessage = [
        {'type':'text','text':messagetext}
    ]
    payload = {'replyToken': replyToken, 'messages': resmessage}
    # カスタムヘッダーの生成(dict形式)
    headers = {'content-type': 'application/json', 'Authorization': 'Bearer XXX'}
    # headersにカスタムヘッダーを指定
    r = requests.post("https://api.line.me/v2/bot/message/reply", headers=headers, data=json.dumps(payload))
    print("LINEレスポンス:" + r.text)
    return

LINEから送られてきたメッセージをそのまま送り返すサンプルになっています。
LINEからのメッセージと replyToken を取得して、応答メッセージ用のhttpsリクエストに設定して送信すればOKです。簡単ですね。

プッシュメッセージを送る

次はLambdaからLINEにプッシュメッセージを送るAPIは以下になります。

https://developers.line.biz/ja/reference/messaging-api/#send-push-message

具体的には以下のhttpsリクエストを送信することでプッシュメッセージを送ることができます。

curl -v -X POST https://api.line.me/v2/bot/message/push \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer {channel access token}' \
-d '{
    "to": "{user id}",
    "messages":[
        {
            "type":"text",
            "text":"Hello, world1"
        },
        {
            "type":"text",
            "text":"Hello, world2"
        }
    ]
}'

  • channel access token:LINE Developersコンソールで発行したチャネルアクセストークンを設定します。
  • user id:プッシュメッセージを送りたい相手の userId を設定します。(userId は「応答メッセージを送る」で確認したLINEからメッセージが送られてきた時のリクエスト内容から確認できます)

実際にLambdaでプッシュメッセージを送信するサンプルは以下になります。

import json
import requests
from pprint import pprint

def lambda_handler(event, context):
    #===========================
    # LINEへのPUSHメッセージ作成
    #===========================
    resmessage = [
        {'type':'text','text':'メッセージ1'},
        {'type':'text','text':'メッセージ2'}
    ]
    payload = {'to': 'XXX', 'messages': resmessage}
    # カスタムヘッダーの生成(dict形式)
    headers = {'content-type': 'application/json', 'Authorization': 'Bearer XXX'}
    # headersにカスタムヘッダーを指定
    r = requests.post("https://api.line.me/v2/bot/message/push", headers=headers, data=json.dumps(payload))
    print("LINEレスポンス:" + r.text)
    return
  • ['to': 'XXX']:プッシュメッセージを送りたい相手の userId を設定します。
  • [Bearer XXX]:LINE Developersコンソールで発行したチャネルアクセストークンを設定します。

送信先のuserIdとチャネルアクセストークンを設定するだけになります。こちらも簡単ですね。

まとめ

今回は、LINE Messaging API x AWS Lambda の連携編を説明しました。
基本的にはLINE Developersコンソール上の設定作業がメインで、Lambda上の実装はMessaging API のリファレンス通りやるだけなので比較的簡単にできたのではないでしょうか。
これで何かあったらLINEにメッセージを送るとツールを動かせたり、定期的にLambdaを起動してLINEにメッセージを送ったりできるので簡単なツールだったら自分でサクッと作ってしまおうかなと思って個人的には気に入っている方法になります。
興味がある方がいたらぜひやってみてください。

AWS Lambda で Python プログラミング~Boto3 サンプル集S3編~

概要~個人的によく使うLambda(Python Boto3)のサンプル集~

Lambdaプログラミングしていて良く使うコードサンプルをまとめていきます。
随時更新予定です(^^)

公式APIリファレンス

AWS公式のAPIリファレンスは以下のURLで何かあったら参照して正しく使いましょう。

https://boto3.amazonaws.com/v1/documentation/api/latest/index.html

S3サンプル

S3ファイルダウンロード

ダウンロードするS3のバケット名、オブジェクト名、Lambdaのローカル環境に保存するファイル名を指定します。
ローカル環境上に同名のファイルがあった場合は上書きされます。

import boto3
s3 = boto3.client('s3')

# バケット名、ダウンロードオブジェクト名、ダウンロードファイル名
S3_BUCKET_NAME = 'sample-bucket'
S3_OBJECT_DOWNLOAD_FILE_NAME = 'sample.jpg'
LOCAL_SAVE_FILE_NAME = '/tmp/sample.jpg'

def lambda_handler(event, context):

    # S3ダウンロード
    s3.download_file(S3_BUCKET_NAME, S3_OBJECT_DOWNLOAD_FILE_NAME, LOCAL_SAVE_FILE_NAME)

    return

S3ファイルアップロード

アップロード先のS3のバケット名、オブジェクト名、Lambdaのローカル環境にあるアップロード対象のファイル名を指定します。
Lambdaのローカル環境にアップロードファイルがある前提のため、事前にアップロードファイルは作成しておく必要があります。
S3上に同名のオブジェクトがあった場合は上書きされます。

import boto3
s3 = boto3.client('s3')

# バケット名、オブジェクト名、アップロード対象ファイル名
S3_BUCKET_NAME = 'sample-bucket'
S3_OBJECT_UPLOAD_FILE_NAME = 'S3sample.jpg'
LOCAL_UPLOAD_FILE_NAME = '/tmp/sample.jpg'

def lambda_handler(event, context):

    # TODOアップロード対象ファイル作成処理

    # S3アップロード
    s3.upload_file(LOCAL_UPLOAD_FILE_NAME, S3_BUCKET_NAME, S3_OBJECT_UPLOAD_FILE_NAME)

    return

S3ファイルダウンロード(メモリ上で扱う場合)

ローカル環境に保存せず、そのままメモリ上でバイトデータとして扱う場合は以下になります。

import boto3

s3 = boto3.resource('s3')

# バケット名、ダウンロードオブジェクト名
S3_BUCKET_NAME = 'sample-bucket'
S3_OBJECT_DOWNLOAD_FILE_NAME = 'sample.jpg'

def lambda_handler(event, context):
    # S3ダウンロード
    bucket = s3.Bucket(S3_BUCKET_NAME)
    obj = bucket.Object(S3_OBJECT_DOWNLOAD_FILE_NAME)
    response = obj.get()
    body = response['Body'].read()

    # 別のBotoクライアントにバイトのまま渡す場合
    # response = client.xxxxxx(Image={'Bytes': body})
    # ダウンロードファイルが画像ではなくJSONファイルの場合
    # print(json.loads(body.decode('utf-8')))

S3ファイルのリスト表示

ファイルのリスト表示するS3のバケット名を指定します。

import boto3

s3 = boto3.client('s3')

# バケット名
S3_BUCKET_NAME = 'sample-bucket'

def lambda_handler(event, context):

    # オブジェクトのリスト表示
    response = s3.list_objects_v2(Bucket=S3_BUCKET_NAME)

    for obj in response['Contents']:
        print(obj['Key'])

    return

S3事前署名付きURL発行

S3に保存してあるファイルを一時的に公開するときに使用する事前署名付きURLを発行するサンプルです。
事前署名付きURLを発行するS3のバケット名、オブジェクト名、URLの有効期限(秒)を指定します。

import boto3
s3 = boto3.client('s3')

# バケット名、事前署名URL発行オブジェクト名、有効期限(秒)
S3_BUCKET_NAME = 'ai-sample-bucket'
S3_OBJECT_PRESIGNES_FILE_NAME = 'sample.jpg'
EXPIRATION = 3600

def lambda_handler(event, context):

    # 事前署名URL発行
    response = s3.generate_presigned_url('get_object',
        Params={'Bucket': S3_BUCKET_NAME,
        'Key': S3_OBJECT_PRESIGNES_FILE_NAME},
        ExpiresIn=EXPIRATION)

    print(response)

    return

参考

Boto3ライブラリは、boto3.clientとboto3.resourceの2つの主要なクラスがあります。

boto3.clientは、AWSサービスのAPIアクションを呼び出すためのクライアントを提供します。例えば、s3クライアントを作成して、S3バケットを作成したり、オブジェクトを取得したり、削除したりすることができます。これは低レベルのAPIであり、AWSリソースとのやり取りがJSONデータで行われます。

一方、boto3.resourceは、AWSリソースを表すPythonオブジェクトを提供します。これは、より高レベルのAPIであり、AWSリソースとPythonオブジェクトのやり取りが可能です。例えば、s3リソースを使用して、バケットを作成したり、オブジェクトを取得したり、削除したりすることができます。また、オブジェクトにはファイルの内容にアクセスするためのread()メソッドがあり、オブジェクトに対してPythonオブジェクトと同じように操作できます。

それぞれで出来ること、やりたいことを理解して使い分けましょう。

EC2(WindowsServer)にSSM Fleet Managerを使ってRDP接続してみる

概要~AWSのEC2(WindowsServer)にAWS Systems Managerのフリートマネージャーを使ってRDP接続してみる~

皆さんはWindowsサーバのEC2を立てた後、どのようにRDP接続していますか?
私はしばらく踏み台サーバを構築して踏み台サーバを経由してアクセスしていたのですが、最近Fleet Managerの存在を知ったのですぐに乗り換えました(^^)便利です。
ただ、乗り換えにあたりいくつか注意点があったのでその内容を共有します。

Fleet Manager RDP接続切り替え手順

今回の記事内容は既存のEC2インスタンスにFleet Managerで接続する接続方法の切り替え手順になります。EC2インスタンスを新しく作成してFleet Managerから接続するのは以下の記事のように比較的簡単に出来るのでそれらの記事を参照にしてください。

【RDP切り替え手順】

  1. RDP接続先のEC2のIAMロールにAmazonSSMManagedInstanceCoreを追加する
  2. SSM Agentを最新化する
  3. RDP接続ポートを3389にする

それでは手順の詳細を説明していきます。

手順1:EC2のIAMロールにAmazonSSMManagedInstanceCoreを追加

Fleet Managerを使ったRDP接続には専用のIAMポリシーが追加になります。AmazonSSMManagedInstanceCoreというポリシーをIAMロールに追加しましょう。
AmazonSSMFullAccessというポリシーもありますが、このポリシーではダメなので注意しましょう。

このIAMポリシーを持つIAMロールをEC2に付与することで、フリートマネージャーが該当のEC2をマネージドノードとして認識でき、フリートマネージャーのマネージドノードの一覧に表示されるようになります。(反映には時間がかかるようで私の場合、IAMロール設定後10分程度一覧に表示されるまで時間がかかりました)

ちなみにこの画面はAWS Systems Managerのトップ画面の左メニューにあるフリートマネージャーをクリックすることで遷移できます。

手順2:SSM Agentを最新化する

手順1を実行することで基本的にはフリートマネージャーからのRDP接続の準備が完了なのですが、私の場合、これだけではエラーになったため、あと2つの切り替え手順を記載します。ちなみにこの状態でRDP接続をするためには、フリートマネージャーの画面から ノードアクションリモートデスクトップ(RDP)との接続をクリックします。

表示されたリモートデスクトップ接続画面からユーザー認証情報(通常のRDP接続に使っているID/パスワード認証)か、キーペア(EC2作成時に指定したキーペアを使った認証)かを選び、Connectをクリックします。

接続を試みているようですが、、、

最終的にはリモートデスクトップセッションが確立できないとかで、タイムアウトしました。。。

この原因を調査したのですが、直接的な原因がわからず、結論としてはSSM Agentのバージョンアップをしたところ、解決しました。
(私のEC2は2020年頃作成したもので、SSMエージェントは自動インストールされており、当時のバージョンは3.0.XXX.Xくらいだったと思います)

SSM Agentの最新化は以下のフリートマネージャーの画面操作で簡単にできます。
アカウント管理SSMエージェントの自動更新

↓のバージョンが上がったことを確認しましょう。

手順2は以上です。

手順3:RDP接続ポートを3389にする

この手順は敢えてデフォルトのRDP接続ポートを変更していた人のみの手順になります。
私はポート変更していたので、ここで結構ハマリました。
なぜなら3389以外のポートにしていた場合、エラーメッセージが↓の認証エラーでした。。。

リモートデスクトップセッションを確立できません。
有効な認証情報が提供されていること、および指定したユーザがリモートデスクトップ経由でログインできることを確認してください。
Authentication failed

このエラーに従って接続ユーザやキーペアの正当性を繰り返し確認したり、新しいログインユーザを作成してみたり、もう一台EC2を立ち上げてそのEC2からの接続を試みたり等、試しましたが、その場合は正しくRDPできてしまう。。。ただ、フリートマネージャーを使ったRDPは必ずこのエラーになってしまう。。。

既存のEC2からの乗り換えは難しいかと諦めかけたときにそう言えばデフォルトのRDPポートを変えていることに気が付き、もしかしたらと試してみたら無事に接続できました。

リモートデスクトップのデフォルトポートの変更はAWSとは関係のない話しなので変更手順は以下のサイト等参照にします(^^;)

https://learn.microsoft.com/ja-jp/windows-server/remote/remote-desktop-services/clients/change-listening-port

以上です!

まとめ

私の環境ではいくつかのエラーが発生し乗り換え手順が必要になりましたが、基本的にはフリートマネージャーはかなり便利に使えると思います。
いくつか接続後の注意点としては、

  1. ファイル共有が出来ない(ローカル環境からファイルをコピペするが出来ない)ことは、S3をローカル環境とEC2のファイル共有に利用することが運用しています。
  2. 日本語が入力できない

ことが挙げられ、2番目(今のところ出来なそう)はなんとかならないかなぁと思っているところです。