<br />
<b>Warning</b>:  Undefined global variable $stdata321 in <b>/home/physalis/physalisgp02.com/public_html/awsblog/wp-content/themes/affinger/functions.php</b> on line <b>6855</b><br />
<br />
<b>Warning</b>:  Undefined global variable $stdata322 in <b>/home/physalis/physalisgp02.com/public_html/awsblog/wp-content/themes/affinger/functions.php</b> on line <b>6855</b><br />
<br />
<b>Warning</b>:  Undefined global variable $stdata323 in <b>/home/physalis/physalisgp02.com/public_html/awsblog/wp-content/themes/affinger/functions.php</b> on line <b>6855</b><br />
<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>とあるAWSエンジニアの戯言</title>
	<atom:link href="https://awsblog.physalisgp02.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://awsblog.physalisgp02.com</link>
	<description>IT技術に関する覚書</description>
	<lastBuildDate>Mon, 03 Apr 2023 10:40:46 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.0.2</generator>
	<item>
		<title>Octgn でガンダムウォーのネット対戦（Octgn 3.7対応＆日本語翻訳）</title>
		<link>https://awsblog.physalisgp02.com/2023/04/03/octgn-%e3%81%a7%e3%82%ac%e3%83%b3%e3%83%80%e3%83%a0%e3%82%a6%e3%82%a9%e3%83%bc%e3%81%ae%e3%83%8d%e3%83%83%e3%83%88%e5%af%be%e6%88%a6%ef%bc%88octgn-3-7%e5%af%be%e5%bf%9c%ef%bc%86%e6%97%a5%e6%9c%ac/</link>
					<comments>https://awsblog.physalisgp02.com/2023/04/03/octgn-%e3%81%a7%e3%82%ac%e3%83%b3%e3%83%80%e3%83%a0%e3%82%a6%e3%82%a9%e3%83%bc%e3%81%ae%e3%83%8d%e3%83%83%e3%83%88%e5%af%be%e6%88%a6%ef%bc%88octgn-3-7%e5%af%be%e5%bf%9c%ef%bc%86%e6%97%a5%e6%9c%ac/#respond</comments>
		
		<dc:creator><![CDATA[syo]]></dc:creator>
		<pubDate>Mon, 03 Apr 2023 10:07:04 +0000</pubDate>
				<category><![CDATA[Octgn×ガンダムウォー]]></category>
		<category><![CDATA[octgn]]></category>
		<category><![CDATA[ガンダムウォー]]></category>
		<guid isPermaLink="false">https://awsblog.physalisgp02.com/?p=294</guid>

					<description><![CDATA[ソース管理 &#160; https://github.com/SyoAwsBlog/gw-octgn &#160; にコミットしてるので、プルリク（翻訳手伝い、スクリプト手直し（MTG版からGWに合 ... <p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<h2>ソース管理</h2>
<p>&nbsp;</p>
<p><a href="https://github.com/SyoAwsBlog/gw-octgn">https://github.com/SyoAwsBlog/gw-octgn</a></p>
<p>&nbsp;</p>
<p>にコミットしてるので、プルリク（翻訳手伝い、スクリプト手直し（MTG版からGWに合わせて）、応援カンパ（githubスポンサー寄付）、などなど募集してます。</p>
<h2>対戦の様子</h2>
<p>現時点版で、対戦すると、こんな様子になります。</p>
<div class="arve" data-mode="normal" data-oembed="1" data-provider="youtube" id="arve-youtube-ite7fzowfzm69e05c8b1a49a970282110" style="max-width:920px;">
<span class="arve-inner">
<span class="arve-embed arve-embed--has-aspect-ratio" style="aspect-ratio: 460 / 259">
<span class="arve-ar" style="padding-top:56.304348%"></span><iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen class="arve-iframe fitvidsignore" data-arve="arve-youtube-ite7fzowfzm69e05c8b1a49a970282110" data-src-no-ap="https://www.youtube-nocookie.com/embed/itE7FzOwfzM?feature=oembed&amp;iv_load_policy=3&amp;modestbranding=1&amp;rel=0&amp;autohide=1&amp;playsinline=0&amp;autoplay=0" frameborder="0" height="518" sandbox="allow-scripts allow-same-origin allow-presentation allow-popups allow-popups-to-escape-sandbox" scrolling="no" src="https://www.youtube-nocookie.com/embed/itE7FzOwfzM?feature=oembed&#038;iv_load_policy=3&#038;modestbranding=1&#038;rel=0&#038;autohide=1&#038;playsinline=0&#038;autoplay=0" width="920" title="Octgnでガンダムウォー（移植過程）( 004：TS同士のソロ対戦）"></iframe>

</span>

</span>
<script type="application/ld+json">{"@context":"http:\/\/schema.org\/","@id":"https:\/\/awsblog.physalisgp02.com\/2023\/04\/03\/octgn-%e3%81%a7%e3%82%ac%e3%83%b3%e3%83%80%e3%83%a0%e3%82%a6%e3%82%a9%e3%83%bc%e3%81%ae%e3%83%8d%e3%83%83%e3%83%88%e5%af%be%e6%88%a6%ef%bc%88octgn-3-7%e5%af%be%e5%bf%9c%ef%bc%86%e6%97%a5%e6%9c%ac\/#arve-youtube-ite7fzowfzm69e05c8b1a49a970282110","type":"VideoObject","embedURL":"https:\/\/www.youtube-nocookie.com\/embed\/itE7FzOwfzM?feature=oembed&iv_load_policy=3&modestbranding=1&rel=0&autohide=1&playsinline=0&autoplay=0","name":"Octgn\u3067\u30ac\u30f3\u30c0\u30e0\u30a6\u30a9\u30fc\uff08\u79fb\u690d\u904e\u7a0b\uff09( 004\uff1aTS\u540c\u58eb\u306e\u30bd\u30ed\u5bfe\u6226\uff09","thumbnailUrl":"http:\/\/img.youtube.com\/vi\/itE7FzOwfzM\/default.jpg","uploadDate":"2023\/04\/03","description":"Octgn\u3067\u30ac\u30f3\u30c0\u30e0\u30a6\u30a9\u30fc\uff08\u79fb\u690d\u904e\u7a0b\uff09( 004\uff1aTS\u540c\u58eb\u306e\u30bd\u30ed\u5bfe\u6226\uff09"}</script>
</div>

<p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></content:encoded>
					
					<wfw:commentRss>https://awsblog.physalisgp02.com/2023/04/03/octgn-%e3%81%a7%e3%82%ac%e3%83%b3%e3%83%80%e3%83%a0%e3%82%a6%e3%82%a9%e3%83%bc%e3%81%ae%e3%83%8d%e3%83%83%e3%83%88%e5%af%be%e6%88%a6%ef%bc%88octgn-3-7%e5%af%be%e5%bf%9c%ef%bc%86%e6%97%a5%e6%9c%ac/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Lambda + GlueのCrawlerのステータス取得（StepFunctions向け）</title>
		<link>https://awsblog.physalisgp02.com/2020/08/03/lambda-glue%e3%81%aecrawler%e3%81%ae%e3%82%b9%e3%83%86%e3%83%bc%e3%82%bf%e3%82%b9%e5%8f%96%e5%be%97%ef%bc%88stepfunctions%e5%90%91%e3%81%91%ef%bc%89/</link>
					<comments>https://awsblog.physalisgp02.com/2020/08/03/lambda-glue%e3%81%aecrawler%e3%81%ae%e3%82%b9%e3%83%86%e3%83%bc%e3%82%bf%e3%82%b9%e5%8f%96%e5%be%97%ef%bc%88stepfunctions%e5%90%91%e3%81%91%ef%bc%89/#respond</comments>
		
		<dc:creator><![CDATA[syo]]></dc:creator>
		<pubDate>Mon, 03 Aug 2020 03:25:43 +0000</pubDate>
				<category><![CDATA[Lambdaサンプルソース]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Crawler]]></category>
		<category><![CDATA[Glue]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[Sample]]></category>
		<category><![CDATA[StepFunctions]]></category>
		<category><![CDATA[サンプル]]></category>
		<guid isPermaLink="false">https://awsblog.physalisgp02.com/?p=258</guid>

					<description><![CDATA[前説 そんな訳？で、前回に引き続きStepFunctionから利用するLambdaシリーズ？という事で、Glue Crawlerの状態取得のLambdaサンプルを掲載します。 前回のLambdaと併せ ... <p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<h2><span class="st-dash-design">前説</span></h2>
<p>そんな訳？で、<a href="https://awsblog.physalisgp02.com/2020/07/28/lambda-glue%e3%81%aecrawler%e3%81%ae%e5%ae%9f%e8%a1%8c%ef%bc%88stepfunctions%e5%90%91%e3%81%91%ef%bc%89/">前回</a>に引き続き<span class="st-mymarker-s">StepFunctionから利用するLambdaシリーズ</span>？という事で、Glue Crawlerの状態取得のLambdaサンプルを掲載します。</p>
<p>前回のLambdaと併せて、<span class="st-mymarker-s">「Crawlerの実行」</span>→<span class="st-mymarker-s">「Crawlerが実行完了するまで？秒毎にループ」</span>といったStepFunctionの定義が可能となります。</p>
<h2><span class="st-dash-design">githubにて公開</span></h2>
<p>Lambda＋Glue（Crawlerステータス取得）のサンプルソースです。ダウンロードは下記より。<br />
<a href="https://github.com/SyoAwsBlog/ShoLambdaSample09">https://github.com/SyoAwsBlog/ShoLambdaSample09</a></p>
<ul>
<li>環境変数で対象のCrawlerが指定可能</li>
<li>GlueのCrawlerのステータスを返却する</li>
</ul>
<p>などの仕様を盛り込んでいます。</p>
<p>StepFunctionsで判定する時は、「Choices」で判定するイメージです。</p>
<pre><code class="language-jsonp">{
   "Choices":[{
      "Variable":"$.response",
      "StringEquals":"FAILED",
      "Next": "エラーで終了のタスクへ"
     },
     {
      "Variable":"$.response",
      "StringEquals":"READY",
      "Next": "正常終了の後続タスクへ"
     }
   ]
}
</code></pre>
<p>&nbsp;</p>
<h2><span class="st-dash-design">利用可能な環境変数</span></h2>
<figure class="wp-block-table">
<table>
<thead>
<tr>
<th>変数名</th>
<th>変数値</th>
</tr>
</thead>
<tbody>
<tr>
<td>LogLevel</td>
<td>ログの出力レベルを(0～4）までの間で設定する</td>
</tr>
<tr>
<td>TargetCrawlerName</td>
<td>対象のCrawler名</td>
</tr>
</tbody>
</table>
</figure>
<h2><span class="st-dash-design">概要</span></h2>
<p>今回も、<a href="https://awsblog.physalisgp02.com/2020/06/23/%e5%ae%9f%e6%88%a6%e7%9a%84%e3%81%aalambda%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/">サンプル１</a>のソースを雛形としています。</p>
<p>特に難しい事もなく、</p>
<ul>
<li>環境変数から対象のCrawler名を取得してパラメータを生成する</li>
<li>対象Crawlerのステータスを取得してきて、Lambdaの戻り値にマッピングする</li>
</ul>
<p>ただ、それだけです。</p>
<h2><span class="st-dash-design">主要な基底処理</span></h2>
<p>今回は、getTasksをオーバーライドせずに利用していますが、処理の流れを説明します。</p>
<pre><code class="language-js">  AbstractBizCommon.prototype.getTasks = function (event, context) {
    var base = AbstractBizCommon.prototype;
    try {
      base.writeLogTrace("AbstractBizCommon# getTasks :start");

      return [
        this.beforeMainExecute,
        this.businessMainExecute,
        this.afterMainExecute,
      ];
    } catch (err) {
      base.printStackTrace(err);
      throw err;
    } finally {
      base.writeLogTrace("AbstractBizCommon# getTasks :end");
    }
  };
</code></pre>
<ul>
<li>beforeMainExecute　・・・　起動引数の返却</li>
<li>businessMainExecute　・・・　パラメータの生成＆Crawlerのステータス取得</li>
<li>afterMainExecute　・・・　戻値の整形</li>
</ul>
<p>という処理の流れになっています。また今回は処理結果をLambdaのプログラムとしての戻り値を制御する必要があるので、GlueCrawlerStatusModule.jsで「<span class="st-mymarker-s">afterAllTasksExecute</span>」の実装を行っています。</p>
<h2>あとがき</h2>
<p>StepFunctions × Lambda × Glue × Athena の組み合わせを使いこなせると、大量データ（今風に言うとビックデータ？）の編集・集計バッチの在り方が劇的に変化するので、簡単に利用できると良いな、、、と思ってサンプルソースをあげてます。</p>
<p>お手元のAWS環境で、サクっと実証実験する時にでも使ってください。</p>
<p>&nbsp;</p>
<p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></content:encoded>
					
					<wfw:commentRss>https://awsblog.physalisgp02.com/2020/08/03/lambda-glue%e3%81%aecrawler%e3%81%ae%e3%82%b9%e3%83%86%e3%83%bc%e3%82%bf%e3%82%b9%e5%8f%96%e5%be%97%ef%bc%88stepfunctions%e5%90%91%e3%81%91%ef%bc%89/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Lambda + GlueのCrawlerの実行（StepFunctions向け）</title>
		<link>https://awsblog.physalisgp02.com/2020/07/28/lambda-glue%e3%81%aecrawler%e3%81%ae%e5%ae%9f%e8%a1%8c%ef%bc%88stepfunctions%e5%90%91%e3%81%91%ef%bc%89/</link>
					<comments>https://awsblog.physalisgp02.com/2020/07/28/lambda-glue%e3%81%aecrawler%e3%81%ae%e5%ae%9f%e8%a1%8c%ef%bc%88stepfunctions%e5%90%91%e3%81%91%ef%bc%89/#respond</comments>
		
		<dc:creator><![CDATA[syo]]></dc:creator>
		<pubDate>Tue, 28 Jul 2020 09:00:36 +0000</pubDate>
				<category><![CDATA[Lambdaサンプルソース]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Crawler]]></category>
		<category><![CDATA[Glue]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[Sample]]></category>
		<category><![CDATA[サンプル]]></category>
		<guid isPermaLink="false">https://awsblog.physalisgp02.com/?p=250</guid>

					<description><![CDATA[前説 前回のサンプルソースが取り組んでみたら、かなりの大物になったので、今回は記述量少なめなシンプルなパターンです。最近、StepFunctionsはGlueとの連携をサポートしはじめたようですが、C ... <p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<h2>前説</h2>
<p><a href="https://awsblog.physalisgp02.com/2020/07/21/lambda%e3%81%a7pdf%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%82%92%e3%83%9a%e3%83%bc%e3%82%b8%e5%88%86%e5%89%b2%ef%bc%88s3%e3%83%88%e3%83%aa%e3%82%ac%e3%83%bc-lambda-s3%ef%bc%89/">前回のサンプルソース</a>が取り組んでみたら、かなりの大物になったので、今回は記述量少なめなシンプルなパターンです。最近、<a href="https://aws.amazon.com/jp/blogs/aws/new-compute-database-messaging-analytics-and-machine-learning-integration-for-aws-step-functions/">StepFunctionsはGlueとの連携をサポート</a>しはじめたようですが、C<span class="st-mymarker-s">rawlerの実行には対応していなかった</span>ようなので、Lambdaから<span class="st-mymarker-s">Crawlerを起動するサンプルソース</span>を掲載します。</p>
<p>個人的な嗜好としては、Glueのジョブを使うパターンが少な目なので、ちょっと残念なアップデートでした。</p>
<p>「Glue（<span class="st-mymarker-s">Crawler</span>）から、Athenaで集計する。」をStepFunctionsでバッチ化するパターンが、<span class="st-mymarker-s">今のところ実務では多め</span>です。<br />
AWS利用料も、<span class="st-mymarker-s">Glueジョブ使うより安い</span>のでオススメです。</p>
<p>本投稿から、しばらくStepFunction絡みで、自分が使う再利用可能なLambda達を書いていこうかな？と思ってます。</p>
<h2><span class="st-dash-design">githubにて公開</span></h2>
<p>Lambda＋Glue（Crawler実行）のサンプルソースです。ダウンロードは下記より。<a href="https://github.com/SyoAwsBlog/ShoLambdaSample08">https://github.com/SyoAwsBlog/ShoLambdaSample08</a></p>
<ul>
<li>環境変数で対象のCrawlerが指定可能</li>
<li>GlueのCrawlerを実行す</li>
</ul>
<p>などの仕様を盛り込んでいます。</p>
<p>ここ最近のサンプルソースの中では、「サンプルらしい！」と言えるほどシンプル機能（笑</p>
<h2><span class="st-dash-design">利用可能な環境変数</span></h2>
<figure class="wp-block-table">
<table>
<thead>
<tr>
<th>変数名</th>
<th>変数値</th>
</tr>
</thead>
<tbody>
<tr>
<td>LogLevel</td>
<td>ログの出力レベルを(0～4）までの間で設定する</td>
</tr>
<tr>
<td>TargetCrawlerName</td>
<td>対象のCrawler名</td>
</tr>
</tbody>
</table>
</figure>
<h2><span class="st-dash-design">概要</span></h2>
<p>今回は、久しぶりに<a href="https://awsblog.physalisgp02.com/2020/06/23/%e5%ae%9f%e6%88%a6%e7%9a%84%e3%81%aalambda%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/">サンプル１</a>のソースを雛形としています。</p>
<p>今回は、特に難しい事もなく、</p>
<ul>
<li>環境変数から対象のCrawler名を取得してパラメータを生成する</li>
<li>Crawlerを実行する</li>
</ul>
<p>ただ、それだけです。</p>
<h2><span class="st-dash-design">主要な基底処理</span></h2>
<p>今回は、getTasksを末端のクラスでオーバーライドしてますが、処理の流れを説明します。</p>
<pre><code class="language-js">  GlueCrawlerSubmitModule.prototype.AbstractBaseCommon.getTasks = function (
    event,
    context
  ) {
    var base = GlueCrawlerSubmitModule.prototype.AbstractBaseCommon;
    try {
      base.writeLogTrace("GlueCrawlerSubmitModule# getTasks :start");

      return [this.beforeMainExecute, this.businessMainExecute];
    } catch (err) {
      base.printStackTrace(err);
      throw err;
    } finally {
      base.writeLogTrace("GlueCrawlerSubmitModule# getTasks :end");
    }
  };
</code></pre>
<ul>
<li>beforeMainExecute　・・・　起動引数の返却</li>
<li>businessMainExecute　・・・　パラメータの生成＆Crawlerの実行</li>
</ul>
<p>複雑な処理もないし、パラメータ作って、AWSのAPI実行するだけなので、初学向き・・・ですかね。</p>
<h2>あとがき</h2>
<p>比較的重たいサンプルソースが続いたので、ライトな感じで行数少な目なサンプルソースです。</p>
<p>しばらくは、StepFunctionsから呼び出して使う系のLambdaシリーズを続けようかと思います。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></content:encoded>
					
					<wfw:commentRss>https://awsblog.physalisgp02.com/2020/07/28/lambda-glue%e3%81%aecrawler%e3%81%ae%e5%ae%9f%e8%a1%8c%ef%bc%88stepfunctions%e5%90%91%e3%81%91%ef%bc%89/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>X Server 上のWordPressでGoogle Adsenseに合格するためにやった事（2020/07版）</title>
		<link>https://awsblog.physalisgp02.com/2020/07/22/x-server-%e4%b8%8a%e3%81%aewordpress%e3%81%a7google-adsense%e3%81%ab%e5%90%88%e6%a0%bc%e3%81%99%e3%82%8b%e3%81%9f%e3%82%81%e3%81%ab%e3%82%84%e3%81%a3%e3%81%9f%e4%ba%8b%ef%bc%882020-07%e7%89%88/</link>
					<comments>https://awsblog.physalisgp02.com/2020/07/22/x-server-%e4%b8%8a%e3%81%aewordpress%e3%81%a7google-adsense%e3%81%ab%e5%90%88%e6%a0%bc%e3%81%99%e3%82%8b%e3%81%9f%e3%82%81%e3%81%ab%e3%82%84%e3%81%a3%e3%81%9f%e4%ba%8b%ef%bc%882020-07%e7%89%88/#respond</comments>
		
		<dc:creator><![CDATA[syo]]></dc:creator>
		<pubDate>Wed, 22 Jul 2020 08:38:13 +0000</pubDate>
				<category><![CDATA[ブログ運営]]></category>
		<category><![CDATA[Adsense]]></category>
		<category><![CDATA[xserver]]></category>
		<category><![CDATA[Xサーバ]]></category>
		<category><![CDATA[アドセンス]]></category>
		<category><![CDATA[エックスサーバ]]></category>
		<guid isPermaLink="false">https://awsblog.physalisgp02.com/?p=231</guid>

					<description><![CDATA[前説 本投稿ではブログ記事の書き方・文章の質・量については、そんなに触れる気はありません。ブログの中身は千差万別でGoogle様のポリシー違反にならない範囲で好きに書いてオンリーワンを目指せば良いし、 ... <p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<h2>前説</h2>
<p>本投稿では<span class="st-mymarker-s">ブログ記事の書き方・文章の質・量</span>については、そんなに触れる気はありません。ブログの中身は千差万別でGoogle様のポリシー違反にならない範囲で好きに書いてオンリーワンを目指せば良いし、合格する為のコツなんて物はありません。<br />
あったとしても、googleの「中の人」しか知りえない情報で<span class="st-mymarker-s">世の中に公開されていない</span>からです。</p>
<p>私の場合は、</p>
<p><strong>「価値の低い広告枠: コンテンツが存在しない」</strong></p>
<p>を理由に、２～３回不合格となりましたが、記事の中身というよりも、<span class="st-mymarker-s">技術的な対処</span>で合格できたと思っているので、その点について記事にしておきたいと思います。</p>
<p>こういう文章が良い、こんな書き方が良い、というのは、ググれば色々出てきますしね。</p>
<h2>最低限用意する内容</h2>
<ul>
<li>自己紹介</li>
<li>プライバシーポリシー</li>
<li>お問い合わせフォーム</li>
</ul>
<p>この３点は、用意しておかないといけないみたいですので、Wordpressの固定ページに用意して、トップ画面の分かりやすい所からリンクしておきましょう。（これは他のHow To サイトで良く掲載されてるので割愛します）</p>
<h2>X-Serverのサブドメイン対応（<a href="https://developer.mozilla.org/ja/docs/Web/HTTP/Redirections">HTTPリダイレクト</a>の設定）</h2>
<p>GoogleAdsenseで初めて申請する時には、サブドメインを利用する事ができません。一方、X-ServerではWordpressをサブドメインで構築する方も一定数いるかと思います。</p>
<p>ここの設定の仕方が分からずに諦める人も多いんじゃないだろうかと思うので、本サイトがGoogle Adsenseに合格した時の設定内容を載せておきます。</p>
<p><img class="aligncenter size-full wp-image-238" src="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/http設定.jpg" alt="" width="848" height="422" srcset="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/http設定.jpg 848w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/http設定-300x149.jpg 300w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/http設定-768x382.jpg 768w" sizes="(max-width: 848px) 100vw, 848px" /></p>
<p>２つの「.htaccess」ファイルに修正が必要です。<span class="st-mymarker-s">間違えるとブログサイトが閲覧できなくなります</span>ので、修正前にファイルをコピーして、<span class="hutoaka">必ず</span><span class="st-mymarker-s">バックアップ</span>を残しておいてください。</p>
<p>ファイルへのアクセスは、X-Serverのインフォパネルから、「ファイル管理」のボタンをクリックして操作してください。<br />
※ クリックしてダウンロードする時に、<span class="st-mymarker-s">ファイル名先頭の「.」（ドット）が無くなる事</span>があるので<span class="st-mymarker-s">ファイル名は注意</span></p>
<p><strong>＜public_html＞直下の「.htaccess」ファイルの中身　　サブドメインへの転送（リダイレクト設定）<br />
～～ここから～～<br />
省略</strong></p>
<p>&lt;IfModule mod_rewrite.c&gt;<br />
<strong>RewriteEngine on</strong><br />
<strong>RewriteBase /</strong><br />
<strong>RewriteCond %{HTTPS} !=on [NC]</strong><br />
<strong>RewriteCond %{HTTP_HOST} ^<span class="hutoaka">physalisgp02</span>\.<span class="hutoaka">com</span>$ [NC]</strong><br />
<strong>RewriteRule .* https://<span class="hutoaka">awsblog.physalisgp02.com</span>/%{REQUEST_URI} [R=301,L]</strong><br />
<strong>RewriteCond %{HTTPS} =on [NC]</strong><br />
<strong>RewriteCond %{HTTP_HOST} ^<span class="hutoaka">physalisgp02</span>\.<span class="hutoaka">com</span>$ [NC]</strong><br />
<strong>RewriteRule .* https://<span class="hutoaka">awsblog.physalisgp02.com</span>/%{REQUEST_URI} [R=301,L]</strong><br />
<strong>RewriteCond %{HTTPS} !=on [NC]</strong><br />
<strong>RewriteCond %{HTTP_HOST} ^<span class="hutoaka">www</span>\.<span class="hutoaka">physalisgp02</span>\.<span class="hutoaka">com</span>$ [NC]</strong><br />
<strong>RewriteRule .* https://<span class="hutoaka">awsblog.physalisgp02.com</span>/%{REQUEST_URI} [R=301,L]</strong><br />
<strong>RewriteCond %{HTTPS} =on [NC]</strong><br />
<strong>RewriteCond %{HTTP_HOST} ^<span class="hutoaka">www</span>\.<span class="hutoaka">physalisgp02</span>\.<span class="hutoaka">com</span>$ [NC]</strong><br />
<strong>RewriteRule .* https://<span class="hutoaka">awsblog.physalisgp02.com</span>/%{REQUEST_URI} [R=301,L]</strong><br />
&lt;/IfModule&gt;</p>
<p><strong>～～ここまで～～</strong></p>
<p><strong>ブログ用サブドメイン直下の「.htaccess」ファイルの中身　　（httpアクセスを、http<span class="hutoaka">s</span>へ転送）<br />
～～ここから～～<br />
省略</strong></p>
<p>&lt;IfModule mod_rewrite.c&gt;<br />
<strong>RewriteEngine On</strong><br />
<strong>RewriteBase /</strong><br />
<strong>RewriteCond %{HTTPS} !=on [NC]</strong><br />
<strong>RewriteCond %{HTTP_HOST} ^<span class="hutoaka">awsblog</span>\.<span class="hutoaka">physalisgp02</span>\.com$ [NC]</strong><br />
<strong>RewriteRule .* http<span class="hutoaka">s</span>://<span class="hutoaka">awsblog.physalisgp02.com</span>/%{REQUEST_URI} [R=301,L]</strong><br />
RewriteRule ^index\.php$ &#8211; [L]<br />
RewriteCond %{REQUEST_FILENAME} !-f<br />
RewriteCond %{REQUEST_FILENAME} !-d<br />
RewriteRule . /index.php [L]<br />
&lt;/IfModule&gt;</p>
<p><strong>～～ここまで～～</strong></p>
<p>太字にした所が大事な設定ですが、これらの修正を加えて、X-Server上のファイルを上書きしてください。</p>
<p><span class="hutoaka">赤字の部分</span>は、もちろん自分の取得したドメインに修正して使ってください。</p>
<h2>WordPressのHTTPS対応</h2>
<p><img class="aligncenter size-full wp-image-241" src="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/設定.png" alt="" width="828" height="481" srcset="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/設定.png 828w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/設定-300x174.png 300w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/設定-768x446.png 768w" sizes="(max-width: 828px) 100vw, 828px" /></p>
<p>WordPressのダッシュボードで、「設定」→「一般」から、</p>
<ul>
<li>WordPressアドレス（URL）</li>
<li>サイトアドレス（URL）</li>
</ul>
<p>を、「<strong>http<span class="hutoaka">s</span></strong>」に変更する事で、ブログへのアクセスを全て、「<strong>http<span class="hutoaka">s</span></strong>」に強制する事ができます。こちらの設定も忘れずに！</p>
<h2><strong>Google XML Sitemaps (プラグイン)の設定見直し</strong></h2>
<p><img class="aligncenter size-large wp-image-242" src="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SearchConsole-1024x517.jpg" alt="" width="920" height="464" srcset="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SearchConsole-1024x517.jpg 1024w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SearchConsole-300x152.jpg 300w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SearchConsole-768x388.jpg 768w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SearchConsole.jpg 1158w" sizes="(max-width: 920px) 100vw, 920px" /></p>
<p>&nbsp;</p>
<p>Google Adsenseの申請をする前に、自分のブログ（<strong>http<span class="hutoaka">s</span>://～</strong>）を<span class="st-mymarker-s">Google Search Consoleに登録</span>して「カバレッジ」を確認し、<span class="st-mymarker-s">エラーがない</span>事を確認してください。<br />
エラーがある間は、高確率でGoogle Adsenseの申請しても、２～３日後に不合格の連絡がきます。</p>
<p>エラーの種類によって対応方法は異なりますが、Sitemapの設定を見直す事でエラーをなくせる事が多いかと思います。</p>
<h2>PageSpeed Insightsの評価</h2>
<p>Google Search Consoleの「ウェブに関する主な指標」で、「PageSpeed Insightsを試す」が実施できますので、可能な限り良い評価が出るように、プラグインなどで対策をしましょう。</p>
<p><strong>＜パソコンアクセスの評価＞</strong></p>
<p><img class="aligncenter size-full wp-image-244" src="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/速度テスト１.jpg" alt="" width="863" height="315" srcset="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/速度テスト１.jpg 863w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/速度テスト１-300x110.jpg 300w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/速度テスト１-768x280.jpg 768w" sizes="(max-width: 863px) 100vw, 863px" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong>＜モバイルアクセスの評価＞</strong></p>
<p><img class="aligncenter size-full wp-image-245" src="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/速度テスト2.jpg" alt="" width="866" height="311" srcset="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/速度テスト2.jpg 866w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/速度テスト2-300x108.jpg 300w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/速度テスト2-768x276.jpg 768w" sizes="(max-width: 866px) 100vw, 866px" /></p>
<p>と、この記事を書きながら、モバイルの評価が下がってるの気がついた。。。（＾＾A<br />
Google Adsenseの広告を入れるとモバイルの評価が悪くなるようです。（<span class="st-mymarker-s">ヤメテホシイわー</span>）</p>
<p>Google Adsenseに申請して広告を貼ってなかった頃は、<span class="st-mymarker-s">モバイルも80～92位の評価</span>を出せてました。</p>
<p>ギラギラのゴテゴテで、ヌルヌルキラキラした重たいデコレーションは、Google Adsenseの合格を貰った後からでも出来るので、Google Adsenseに申請する時は、サイト描画の速さ（PageSpeed Insightsの評価）にも気を配ると良いかもしれません。</p>
<p>（審査の評価ポイントに入ってるかどうかは分かりません、私は、かなり気を配ってました。）</p>
<h2>あとがき</h2>
<p>ブログ開設当初から目標にしていた、<span class="st-mymarker-s">Google Adsenseに合格</span>しました。</p>
<p>最初の1週目は、２～３日毎に申請しては不合格を繰り返してました。Google Search Consoleのエラー対応がゼロになったあたりから段々と審査で落とされる時間が長くなっていった感じがしました。</p>
<p>どんなに良い記事を書こうが、「<span class="st-mymarker-s">Google Search Consoleのエラー」がある間は、ロボット審査で問答無用</span>で落とされてる感があります。</p>
<p>Google Adsenseの審査にチャレンジする方は、上記の技術サイドでも全力で、<span class="st-mymarker-s">Googleに好印象を与えるよう努力して合格を勝ち取り</span>ましょう。</p>
<p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></content:encoded>
					
					<wfw:commentRss>https://awsblog.physalisgp02.com/2020/07/22/x-server-%e4%b8%8a%e3%81%aewordpress%e3%81%a7google-adsense%e3%81%ab%e5%90%88%e6%a0%bc%e3%81%99%e3%82%8b%e3%81%9f%e3%82%81%e3%81%ab%e3%82%84%e3%81%a3%e3%81%9f%e4%ba%8b%ef%bc%882020-07%e7%89%88/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>LambdaでPDFファイルをページ分割（S3トリガー + Lambda + S3）</title>
		<link>https://awsblog.physalisgp02.com/2020/07/21/lambda%e3%81%a7pdf%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%82%92%e3%83%9a%e3%83%bc%e3%82%b8%e5%88%86%e5%89%b2%ef%bc%88s3%e3%83%88%e3%83%aa%e3%82%ac%e3%83%bc-lambda-s3%ef%bc%89/</link>
					<comments>https://awsblog.physalisgp02.com/2020/07/21/lambda%e3%81%a7pdf%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%82%92%e3%83%9a%e3%83%bc%e3%82%b8%e5%88%86%e5%89%b2%ef%bc%88s3%e3%83%88%e3%83%aa%e3%82%ac%e3%83%bc-lambda-s3%ef%bc%89/#respond</comments>
		
		<dc:creator><![CDATA[syo]]></dc:creator>
		<pubDate>Tue, 21 Jul 2020 09:00:43 +0000</pubDate>
				<category><![CDATA[Lambdaサンプルソース]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[S3]]></category>
		<guid isPermaLink="false">https://awsblog.physalisgp02.com/?p=219</guid>

					<description><![CDATA[前説 Node.jsでPDFの操作をやった事がなかったので勉強がてら、手を出したらヒドイ目にあった。（ぇ 自前でPDFを、こねくり回すのはシンドイのでライブラリを探したけど、日本では、あまり「やってみ ... <p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<h2>前説</h2>
<p>Node.jsでPDFの操作をやった事がなかったので勉強がてら、手を出したらヒドイ目にあった。（ぇ<br />
自前でPDFを、こねくり回すのはシンドイのでライブラリを探したけど、日本では、あまり「やってみた系」がありませんでした。<br />
npmのライブラリを漁った所、<a href="https://www.npmjs.com/package/hummus">hummus</a>が良さそうだったので、このライブラリの検証がてらLambdaで実装してみました。</p>
<p>出力先のS3バケット名をLambdaの環境変数に指定して、S3インプットトリガーで起動するだけで、PDFファイルのページ毎分割ができるLambdaを実装しました。</p>
<p>このLambdaを利用する場合は、<span class="st-mymarker-s">S3のputトリガーを仕込むS3バケット</span>と、<span class="st-mymarker-s">分割したPDFファイルを保存するようのS3バケット</span>、必ず<span class="hutoaka">２つ</span>用意してください。</p>
<p>間違っても、<span class="st-mymarker-s">putトリガーを仕込んだS3バケット</span>に分割したPDFファイルを保存して<span class="st-mymarker-s">無限ループさせる</span>事がないようにしてください。</p>
<p>hummusのライブラリがサイズ（約12MB）が大きくて、S3に一度アップしてからじゃないとLambdaに登録できないので注意してください。</p>
<p>hummusは、内部でコンパイルしてるので、Windows環境で</p>
<p><span class="st-mymarker-s"><strong>「npm install hummus」しても動作しません。</strong></span></p>
<p>開発プロジェクトから作成したい方は、<span class="st-mymarker-s">AmazonLinuxのEC2を一時的に起動して開発プロジェクトを作る必要</span>があります。<br />
githubで公開してる物を落とした場合はAWS Lambdaで動作します。</p>
<h2><span class="st-dash-design">githubにて公開</span></h2>
<p>S3プットトリガー + Lambda + S3 のサンプルソースです。<br />
ダウンロードは下記より<br />
<a href="https://github.com/SyoAwsBlog/ShoLambdaSample07">https://github.com/SyoAwsBlog/ShoLambdaSample07</a></p>
<ul>
<li>S3putトリガーを受け取ってS3オブジェクトをLambdaの/tmp配下に保存する</li>
<li>PDFファイルをhummusに喰わせて構造解析する</li>
<li>1ページ毎のデータを構築して環境変数で指定したS3バケットに保存する</li>
<li>/tmp配下の保存したPDFファイルを削除する</li>
<li>S3putトリガーで受け取った原本のPDFファイルを削除する</li>
</ul>
<p>などの仕様を盛り込んでいます。</p>
<h2><span class="st-dash-design">利用可能な環境変数</span></h2>
<figure class="wp-block-table">
<table>
<thead>
<tr>
<th>変数名</th>
<th>変数値</th>
</tr>
</thead>
<tbody>
<tr>
<td>LogLevel</td>
<td>ログの出力レベルを(0～4）までの間で設定する</td>
</tr>
<tr>
<td>LogLevelForWorker</td>
<td>ログの出力レベルを(0～4）までの間で設定する(ワーカー処理（疑似スレッド処理）)</td>
</tr>
<tr>
<td>ExecutorsThreadsNum</td>
<td>並行処理の多重度を数字で指定</td>
</tr>
<tr>
<td>ExecutorsThreadsWait</td>
<td>ワーカー処理（疑似スレッド処理）毎に Sleepを入れられる（ミリ秒指定）</td>
</tr>
<tr>
<td>OutputS3BucketName</td>
<td>ページ分割したPDFファイルを保存するS3バケット名</td>
</tr>
</tbody>
</table>
</figure>
<h2><span class="st-dash-design">概要というか実装時の四方山話</span></h2>
<p>S3から取得したオブジェクトをメモリ展開したまま、ページ分割データをS3バケットにアップできたら良いなぁ～と思って、試行削除したのですが、、、</p>
<p><strong>「TypeError: Unable to start parsing PDF file」</strong></p>
<p>ライブラリの出力してくる、このエラーが潰せなかった。<br />
エラーとしては、不正な形式ファイルを読み込んだ時に発生するエラーっぽいのだけど、一旦、/tmpにおいて取り込むと処理できるという。。。<br />
（誰か、この謎を解いてください（ぇ</p>
<p>hummusにBufferから取り込む為のクラスも用意はされてるですが、上手く動かない。issueとかを見てると、デカいファイルの時は<span class="st-mymarker-s">ローカルにファイルを保存してしまった方が格段に処理が早い</span>とのコメントもあったので、/tmpに置く方式で実装しています。</p>
<h2><span class="st-dash-design">主要な基底処理（制御側）</span></h2>
<p>まずは制御側のS3putトリガーからデータ取得してハンドリングする制御処理から説明します。</p>
<p><strong>AbstractS3PutTriggerCommon　　565行目</strong></p>
<pre><code class="language-js">  AbstractS3PutTriggerCommon.prototype.AbstractBaseCommon.getTasks = function (
    event,
    context
  ) {
    var base = AbstractS3PutTriggerCommon.prototype.AbstractBaseCommon;
    try {
      base.writeLogTrace("AbstractS3PutTriggerCommon# getTasks :start");

      return [
        this.initS3PutTriggerParameter,
        this.waitExistsS3Object,
        this.beforeMainExecute,
        this.pdfParse,
        this.businessMainExecute,
        this.afterTmpDeleteExecute,
        this.afterMainExecute,
      ];
    } catch (err) {
      base.printStackTrace(err);
      throw err;
    } finally {
      base.writeLogTrace("AbstractS3PutTriggerCommon# getTasks :end");
    }
  };

</code></pre>
<ul>
<li>initS3PutTriggerParameter ・・・ putトリガーからS3取得のパラメータを返却</li>
<li>waitExistsS3Object　・・・ S3のオブジェクト存在確認</li>
<li>beforeMainExecute　・・・S3オブジェクトデータ（PDF）を/tmpに保存</li>
<li>pdfParse　・・・PDF構造解析データとページ分割制御データの作成</li>
<li>businessMainExecute　・・・非同期多重実行の制御</li>
<li>afterTmpDeleteExecute　・・・/tmpに保存したデータ削除</li>
<li>afterMainExecute　・・・ putトリガー元となったS3オブジェクト削除</li>
</ul>
<p>この処理では1ページ毎にファイル分割をしていますが、複数ページでファイル分割した場合は、「<span class="st-mymarker-s">pdfParse</span>」で作成しているワーカ処理用のデータを改造すると出来ると思います。</p>
<h2><span class="st-dash-design">主要な基底処理（ワーカー側）</span></h2>
<p><strong>AbstractWorkerS3UploaderCommon・・・226行目</strong></p>
<pre><code class="language-js">  AbstractWorkerS3UploaderCommon.prototype.AbstractBaseCommon.getTasks = function (
    event,
    context
  ) {
    var base = AbstractWorkerS3UploaderCommon.prototype.AbstractBaseCommon;
    try {
      base.writeLogTrace("AbstractWorkerS3UploaderCommon# getTasks :start");

      return [this.beforeMainExecute, this.businessMainExecute];
    } catch (err) {
      base.printStackTrace(err);
      throw err;
    } finally {
      base.writeLogTrace("AbstractWorkerS3UploaderCommon# getTasks :end");
    }
  };
</code></pre>
<p>&nbsp;</p>
<ul>
<li>beforeMainExecute　・・・　制御側から受け取ったデータを返却</li>
<li>businessMainExecute　・・・　1ページ分のPDFデータを作ってS3へアップロード</li>
</ul>
<p>と非常にシンプルな構成になっています。</p>
<p>「ExecutorsThreadsNum=5」にして、5多重とかにしても、一応、ちゃんと動いてるっポイです。</p>
<h2>あとがき</h2>
<p>軽い気持ちで手を出したら、イロイロ上手くいかない事や調査しないといけない事があって勉強になりました。</p>
<p>英語のコミュニティを漁るのは、しばらく、お腹イッパイです。</p>
<p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></content:encoded>
					
					<wfw:commentRss>https://awsblog.physalisgp02.com/2020/07/21/lambda%e3%81%a7pdf%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%82%92%e3%83%9a%e3%83%bc%e3%82%b8%e5%88%86%e5%89%b2%ef%bc%88s3%e3%83%88%e3%83%aa%e3%82%ac%e3%83%bc-lambda-s3%ef%bc%89/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQS + Lambda + Firehose のサンプルソース</title>
		<link>https://awsblog.physalisgp02.com/2020/07/14/sqs-lambda-firehose-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/</link>
					<comments>https://awsblog.physalisgp02.com/2020/07/14/sqs-lambda-firehose-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/#respond</comments>
		
		<dc:creator><![CDATA[syo]]></dc:creator>
		<pubDate>Tue, 14 Jul 2020 10:25:06 +0000</pubDate>
				<category><![CDATA[Lambdaサンプルソース]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Firehose]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[Sample]]></category>
		<category><![CDATA[SQS]]></category>
		<category><![CDATA[サンプル]]></category>
		<guid isPermaLink="false">https://awsblog.physalisgp02.com/?p=198</guid>

					<description><![CDATA[前説 サンプル４、サンプル５とデータ連携シリーズを掲載してきたので、今風に言うとデータレイク（S3）へのCSVファイル出力するの為にFirehoseへ連携するLambdaをサンプルとして公開しようと思 ... <p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<h2>前説</h2>
<p><a href="https://awsblog.physalisgp02.com/2020/07/02/dynamodb-stream-lambda-snssimple-notification-service-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/">サンプル４</a>、<a href="https://awsblog.physalisgp02.com/2020/07/08/s3-put%e3%83%88%e3%83%aa%e3%82%ac%e3%83%bc-lambda-dynamodb-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/">サンプル５</a>とデータ連携シリーズを掲載してきたので、今風に言うとデータレイク（S3）へのCSVファイル出力するの為に<span class="st-mymarker-s">Firehoseへ連携するLambda</span>をサンプルとして公開しようと思います。</p>
<p><a href="https://awsblog.physalisgp02.com/2020/07/02/dynamodb-stream-lambda-snssimple-notification-service-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/">サンプル４</a>、<a href="https://awsblog.physalisgp02.com/2020/07/08/s3-put%e3%83%88%e3%83%aa%e3%82%ac%e3%83%bc-lambda-dynamodb-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/">サンプル５</a>と今回のサンプルソースを全て繋げると</p>
<ul>
<li>S3にファイルをputし、putトリガーでLambdaを起動</li>
<li>DynamoDBに取り込み</li>
<li>DynamoDBからストリームでSNSへ配信</li>
<li>SQSにデータ蓄積</li>
<li>SQSからデータを取り出して分析用に加工しながらFirehose（S3）へ出力</li>
</ul>
<p>と<span class="st-mymarker-s">データ連携システム</span>をLambdaで実現する時の<span class="st-mymarker-s">主要な利用AWSサービス群</span>と、ちょっと編集するだけで、<span class="st-mymarker-s">繋がる・動くLambda</span>が用意できるようになります。</p>
<h2><span class="st-dash-design">githubにて公開</span></h2>
<p>SQS + Lambda + Firehose のサンプルソースです。 ダウンロードは下記より <a href="https://github.com/SyoAwsBlog/ShoLambdaSample06">https://github.com/SyoAwsBlog/ShoLambdaSample06</a></p>
<ul>
<li>SQSから一度に取得できる<a href="https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SQS.html#receiveMessage-property">メッセージ数はAPIで10件</a>まで上限があるので指定件数・リトライ数で可能な限り受信</li>
<li>データ連携を想定してるのでFirehoseへのputは成功するまでリトライ（落ちる時はLambdaの実行時間上限）</li>
<li>Firehoseへのputに成功したらSQSキューからメッセージを削除</li>
<li>SQSにメッセージが残っているようなら自身（Lambda）を再起呼び出し（上限設定あり）</li>
</ul>
<p>などの仕様を盛り込んでいます。</p>
<h2>利用可能な環境変数</h2>
<p>今回は、ちょっと利用できる環境変数が多いです。（＾＾A</p>
<figure class="wp-block-table">
<table>
<thead>
<tr>
<th>変数名</th>
<th>変数値</th>
</tr>
</thead>
<tbody>
<tr>
<td>LogLevel</td>
<td>ログの出力レベルを(0～4）までの間で設定する</td>
</tr>
<tr>
<td>LogLevelForWorker</td>
<td>ログの出力レベルを(0～4）までの間で設定する(ワーカー処理（疑似スレッド処理）)</td>
</tr>
<tr>
<td>ExecutorsThreadsNum</td>
<td>並行処理の多重度を数字で指定</td>
</tr>
<tr>
<td>ExecutorsThreadsWait</td>
<td>ワーカー処理（疑似スレッド処理）毎に Sleepを入れられる（ミリ秒指定）</td>
</tr>
<tr>
<td>SqsReceiveMaxSize</td>
<td>SQSから受信するメッセージ最大数（リトライして受信）</td>
</tr>
<tr>
<td>SqsReceiveErrRetryMax</td>
<td>SQSから受信エラーが発生した時のリトライ上限</td>
</tr>
<tr>
<td>SqsQueueUrl</td>
<td>メッセージを受信するSQSのURLを指定</td>
</tr>
<tr>
<td>SelfReCallMax</td>
<td>SQSにメッセージが残っている場合に自身（Lambda）を再起呼び出しするが、その回数上限</td>
</tr>
<tr>
<td>FirehoseStreamName</td>
<td>出力対象のストリーム名</td>
</tr>
</tbody>
</table>
<h2><span class="st-dash-design">概要</span></h2>
<p>今回<strong>も</strong><a href="https://awsblog.physalisgp02.com/2020/06/26/%e5%ae%9f%e6%88%a6%e7%9a%84%e3%81%aalambda%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9-%e3%81%9d%e3%81%ae%ef%bc%92/">サンプル２</a>を雛形として採用しています。</p>
<p><a href="https://awsblog.physalisgp02.com/wp-admin/post.php?post=182&amp;action=edit">前回同様</a>、クラス構成・カスタマイズの容易性を考えた時に、<a href="https://awsblog.physalisgp02.com/2020/06/26/%e5%ae%9f%e6%88%a6%e7%9a%84%e3%81%aalambda%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9-%e3%81%9d%e3%81%ae%ef%bc%92/">サンプル２</a>の方が分かりやすいと考えた為です。<br />
どういう事が言うと、、、</p>
<p><span class="st-mymarker-s">「SQSからデータを読み込むだけ読み込んで連携処理を委譲する。データ残件があるなら再処理する」</span>と<span class="st-mymarker-s">「連携データを受け取ってデータ加工し出力対象（今回はFirehose）へデータ連携」</span>が別クラスになっていた方がオーバーライドやカスタマイズが容易になるからという理由です。</p>
<p><span class="st-mymarker-s">具体例</span>で言うと出力先をFirehoseではなく、<span class="st-mymarker-s">外部API呼び出し</span>にカスタマイズするといった時に、<span class="st-mymarker-s">ワーカークラスを修正するだけ</span>で対応が可能となるからです。</p>
<h2>主要な基底処理（SQSデータ読み込み～自身（Lambda）の再起呼び出し）</h2>
<p>まずは制御側のSQSからデータを読み込んでいる処理の簡単な流れから説明します。</p>
<p><strong>AbstractSqsReceiveCommon　624行目付近</strong></p>
<pre><code class="language-js">  AbstractSqsReceiveCommon.prototype.AbstractBaseCommon.getTasks = function (
    event,
    context
  ) {
    var base = AbstractSqsReceiveCommon.prototype.AbstractBaseCommon;
    try {
      base.writeLogTrace("AbstractSqsReceiveCommon# getTasks :start");

      return [
        this.beforeMainExecute,
        this.businessMainExecute,
        this.afterMainExecute,
        this.reCallSelfExecute,
      ];
    } catch (err) {
      base.printStackTrace(err);
      throw err;
    } finally {
      base.writeLogTrace("AbstractSqsReceiveCommon# getTasks :end");
    }
  };</code></pre>
</figure>
<p>&nbsp;</p>
<ul>
<li>beforeMainExecute　・・・　指定件数の受信ができるか、0件受信になるまでSQSから受信</li>
<li>businessMainExecute　・・・　非同期多重実行の制御</li>
<li>afterMainExecute　・・・　SQSのキュー情報（メッセージ残件）を取得</li>
<li>reCallSelfExecute 　・・・　SQSにメッセージが残っているようなら自身（Lambda）を再起呼び出し</li>
</ul>
<p>この処理を実装しようとした時に、一番、驚いたことは、<span class="st-mymarker-s">「SQSからメッセージ受信が1回につき10件まで」</span>に<span class="hutoaka">制限</span>されている事です。</p>
<p>SAA資格とかで勉強した事がある人は分かると思いますが、「<span class="st-mymarker-s">SQSは耐久性があって大量データをキューイングできる。</span>」という触れ込みの設問が多々出題されます。</p>
<p>Lambdaで処理しようとした時に、「<span class="st-mymarker-s">APIでMAX10件しか取得できない！</span>」って、「<span class="st-mymarker-s">どーゆーことやねん！</span>」と思った物です。<br />
そんな訳で、「環境変数：SqsReceiveMaxSize」で指定して、ある程度の件数を捌けるようにしてます。<br />
連携データ仕様にもよりますが、実体験で<span class="st-mymarker-s">50～100件位</span>で処理させる事が多いですかね。</p>
<p>それでも処理しきらない時の為に、<span class="st-mymarker-s">SQSに残件があるかどうか確認して自身（Lambda）を再起呼び出しする機能</span>も組み込んであります。<br />
カスタマイズする時は、バグらせて<span class="st-mymarker-s">無限ループさせないように注意</span>してください。</p>
<p>やらかして「<span class="st-mymarker-s">Lambdaを無限ループさせちまった！？</span>」という時は、AWSコンソールから<span class="st-mymarker-s">対象のLambda関数を削除</span>してください。</p>
<h2>主要なワーカー処理（Firehoseへのput処理＆キューからメッセージ削除）</h2>
<p>制御側から受け取ったデータをFirehoseへputして、SQSキューから処理したメッセージを削除します。</p>
<p><strong>AbstractFirehosePutWorkerCommon　・・・　492行付近</strong></p>
<p>&nbsp;</p>
<pre><code class="language-js">  AbstractFirehosePutWorkerCommon.prototype.AbstractBaseCommon.getTasks = function (
    event,
    context
  ) {
    var base = AbstractFirehosePutWorkerCommon.prototype.AbstractBaseCommon;
    try {
      base.writeLogTrace("AbstractFirehosePutWorkerCommon# getTasks : start");
      return [
        this.beforeMainExecute,
        this.extractBizInfos,
        this.transformRecordInfos,
        this.businessMainExecute,
        this.afterMainExecute,
      ];
    } catch (err) {
      base.printStackTrace(err);
      throw err;
    } finally {
      base.writeLogTrace("AbstractFirehosePutWorkerCommon# getTasks : end");
    }
  };
</code></pre>
<p>&nbsp;</p>
<ul>
<li>beforeMainExecute　・・・　制御側から受け取ったデータを返却</li>
<li>extractBizInfos　・・・　データの展開（どのサービスを経由してきたによって要オーバーライド）</li>
<li>transformRecordInfos　・・・　DynamoDBのデータ構造を単純なマップ構造に変換</li>
<li>businessMainExecute　・・・　FirehoseへのPut処理</li>
<li>afterMainExecute　・・・　対象データをSQSキューから削除</li>
</ul>
<p>Firehoseへの登録に成功しない限り<span class="st-mymarker-s">何度でもリトライ</span>するようにしてあるので、「<span class="st-mymarker-s">環境変数：FirehoseStreamName</span>」のストリーム名やLambdaに付与するIAMロールのポリシー付与は<span class="st-mymarker-s">絶対に、絶対に間違わないでください。</span></p>
<p>Lambdaの<span class="st-mymarker-s">実行時間上限</span>まで動作する事になります。</p>
<p>Firehoseへの<span class="st-mymarker-s">putに成功したらSQSキューから削除</span>としたかったので、Firehoseのput処理成功時の次のPromise処理に、SQSキューからの削除を配置しています。</p>
<h2>主要なカスタマイズ①（出力レイアウト）</h2>
<p>AbstractFirehosePutWorkerCommon.businessMainExecuteから、getFileOutputLayoutを呼び出して出力フォーマットを変換しています。</p>
<p><strong>getFileOutputLayout　・・・　338行目付近　　　recordには対象の行データ</strong></p>
<pre><code class="language-js">      var recordData = "";
      var cols = base.getFileOutputColumns();

      for (var i = 0; i &lt; cols.length; i++) { var colName = cols[i]; if (i &gt; 0) {
          recordData = recordData + ",";
        }

        if (
          colName in record &amp;&amp;
          record[colName] &amp;&amp;
          record[colName].length &gt; 0
        ) {
          recordData = recordData + "" + record[colName];
        } else {
          recordData = recordData + "";
        }
      }

      recordData = recordData + "\n";
</code></pre>
<p>という感じで、<span class="st-mymarker-s">カンマ区切りのCSVデータ</span>に変換しています。</p>
<h2>主要なカスタマイズ➁（出力項目）</h2>
<p>AbstractFirehosePutWorkerCommon.getFileOutputLayoutから、getFileOutputColumnsを呼び出して出力対象とするDynamoDBの項目名を配列で決定しています。</p>
<p>こちらは、カスタマイズの<span class="st-mymarker-s">オーバーライド例</span>として、SampleFirehosePutWorkerModule側にオーバーライド関数：getFileOutputColumnsを実装しています。</p>
<p><strong>SampleFirehosePutWorkerModule　・・・　30行付近</strong></p>
<pre><code class="language-js">  SampleFirehosePutWorkerModule.prototype.AbstractBaseCommon.getFileOutputColumns = function (
    record
  ) {
    var base = SampleFirehosePutWorkerModule.prototype.AbstractBaseCommon;
    try {
      base.writeLogTrace(
        "SampleFirehosePutWorkerModule# getFileOutputColumns : start"
      );
      var cols = ["PrimaryKey", "SortKey"];
      return cols;
    } catch (err) {
      base.printStackTrace(err);
      throw err;
    } finally {
      base.writeLogTrace(
        "SampleFirehosePutWorkerModule# getFileOutputColumns : end"
      );
    }
  }.bind(SampleFirehosePutWorkerModule.prototype.AbstractBaseCommon);
</code></pre>
<p>&nbsp;</p>
<p>colsに代入する配列に、<span class="st-mymarker-s">DynamoDBの項目を設定</span>すると、その順序で<span class="st-mymarker-s">CSVデータが並び替えられて出力</span>されます。<br />
<span class="st-mymarker-s">データの送出元となったDynamoDBの項目名に合わせて、<span class="hutoaka">この関数</span>を書き換えてください。<br />
</span>後は、Lambdaの環境変数を整備してIAMロール＆ポリシーを整えるだけで流用できると思います。</p>
<h2>あとがき</h2>
<p>データ連携シリーズ（<a href="https://awsblog.physalisgp02.com/2020/07/02/dynamodb-stream-lambda-snssimple-notification-service-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/">サンプル４</a>、<a href="https://awsblog.physalisgp02.com/2020/07/08/s3-put%e3%83%88%e3%83%aa%e3%82%ac%e3%83%bc-lambda-dynamodb-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/">サンプル５</a>、サンプル６（今回））は、いかがだったでしょうか？</p>
<p>Firehoseまで連携できれば、ElasticsearchやS3に置いてglue&amp;Athenaなど分析系サービスにデータを繋げていく事ができるので、業務に応用のきく実戦的なLambdaを掲載できたのではないかと思います。</p>
<p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></content:encoded>
					
					<wfw:commentRss>https://awsblog.physalisgp02.com/2020/07/14/sqs-lambda-firehose-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>S3 putトリガー + Lambda + DynamoDB のサンプルソース</title>
		<link>https://awsblog.physalisgp02.com/2020/07/08/s3-put%e3%83%88%e3%83%aa%e3%82%ac%e3%83%bc-lambda-dynamodb-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/</link>
					<comments>https://awsblog.physalisgp02.com/2020/07/08/s3-put%e3%83%88%e3%83%aa%e3%82%ac%e3%83%bc-lambda-dynamodb-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/#respond</comments>
		
		<dc:creator><![CDATA[syo]]></dc:creator>
		<pubDate>Wed, 08 Jul 2020 09:11:36 +0000</pubDate>
				<category><![CDATA[Lambdaサンプルソース]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Dynamo]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[S3]]></category>
		<category><![CDATA[Sample]]></category>
		<category><![CDATA[サンプル]]></category>
		<guid isPermaLink="false">https://awsblog.physalisgp02.com/?p=182</guid>

					<description><![CDATA[前説 Webアプリやデータ連携バッチで、S3のputトリガーを起点にしてLambdaを起動して何らかの処理をする。Lambdaの使い方としてはアイデアとして思いつきやすい用法ですが、実は考慮しておいた ... <p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<h2>前説</h2>
<p>Webアプリやデータ連携バッチで、S3のputトリガーを起点にしてLambdaを起動して何らかの処理をする。Lambdaの使い方としてはアイデアとして思いつきやすい用法ですが、<span class="st-mymarker-s">実は考慮しておいた方が良い点</span>があるので、<span class="st-mymarker-s">実体験で得た情報</span>と共に説明していきます。 今回も出力側は、DynamoDBを選択しましたが、<a href="https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html#batchWriteItem-property">batchWriteItem</a>のAPIで<span class="st-mymarker-s">複数件データを登録＆リトライ処理</span>する辺りについても触れていきます。</p>
<p>だんだん、サンプルと言いながらソース記述量が増えていってるのは、突っ込まないで！</p>
<p>具体的なAWSサービス同士の連携を考えると、考慮しておきたい機構や仕組みなんかが増えていく。。。</p>
<h2><span class="st-dash-design">githubにて公開</span></h2>
<p>S3 putトリガー + Lambda + DynamoDB のサンプルソースです。 ダウンロードは下記より <a href="https://github.com/SyoAwsBlog/ShoLambdaSample05">https://github.com/SyoAwsBlog/ShoLambdaSample05</a></p>
<ul>
<li>S3でputトリガーからのLambda起動を使う際の注意点</li>
<li>DynamoDBへの複数件一括登録の再起呼び出しリトライループ</li>
</ul>
<p>などの<span class="st-mymarker-s">小技</span>を織り込んでみました。</p>

<h2>利用可能な環境変数</h2>

<figure class="wp-block-table">
<table>
<thead>
<tr>
<th>変数名</th>
<th>変数値</th>
</tr>
</thead>
<tbody>
<tr>
<td>LogLevel</td>
<td>ログの出力レベルを(0～4）までの間で設定する</td>
</tr>
<tr>
<td>LogLevelForWorker</td>
<td>ログの出力レベルを(0～4）までの間で設定する(ワーカー処理（疑似スレッド処理）)</td>
</tr>
<tr>
<td>ExecutorsThreadsNum</td>
<td>並行処理の多重度を数字で指定</td>
</tr>
<tr>
<td>ExecutorsThreadsWait</td>
<td>ワーカー処理（疑似スレッド処理）毎に Sleepを入れられる（ミリ秒指定）</td>
</tr>
<tr>
<td>BatchPutSize</td>
<td><a href="https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html#batchWriteItem-property">batchWriteItem</a>を処理する件数、リンク先のドキュメントに記載があるが最大25件未満なので、1～24までの間で設定すること</td>
</tr>
<tr>
<td>ObjectWaitForRetryMax</td>
<td>S3オブジェクトのアクセス可否を何回待機するかを設定する。平常時なら2～3回で十分、運用に耐えるハズである。極まれにあるS3の障害時などは、回数を増やすのもアリ。</td>
</tr>
<tr>
<td>TableName</td>
<td>読み込んだデータを登録するDynamoDBのテーブル名</td>
</tr>
<tr>
<td>PrimaryKey</td>
<td>DynamoDBのキー名</td>
</tr>
<tr>
<td>SortKey</td>
<td>DynamoDBのソートキー名</td>
</tr>
<tr>
<td>DynamoPutForRetryMax</td>
<td> <a href="https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html#batchWriteItem-property">batchWriteItem</a>でデータ登録する際に、一度に処理しきれない事があるので、再起呼び出しでリトライする処理が組み込んである。リトライ上限を設定する。<br />DynamoDBのテーブルのキャパシティにもよるが、回数がかかっても3～4回の間位で大体処理できる（と思われる）<br />「BatchPutSize」と「テーブルのキャパシティ」の兼ね合いになる。</td>
</tr>
</tbody>
</table>
</figure>

<h2>概要</h2>
<p>今回も組み上げには、<a href="http://awsblog.physalisgp02.com/2020/06/26/%e5%ae%9f%e6%88%a6%e7%9a%84%e3%81%aalambda%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9-%e3%81%9d%e3%81%ae%ef%bc%92/">サンプル２</a>を利用しました。<br />サンプル集として、<span class="st-mymarker-s">「S3からファイルを読み込んで正常に処理できたらオブジェクトを削除する」</span>と<span class="st-mymarker-s">「読み込んだデータを受け取って処理する（今回はDynamoDBへ登録する）」</span>が<span class="st-mymarker-s">別クラス</span>になっていた方が別用途での使い回しが効きやすいし、コードが読める人には読みやすいという理由からの選択です。</p>
<p>DynamoDBの書き込みキャパシティは<span class="st-mymarker-s">大量に増やす</span>とAWS利用料の<span class="st-mymarker-s">課金が増える</span>ので注意してくださいね。</p>
<p>書き込みキャパシティにデカい数字を割り当てられる程、お財布事情に余裕があるのであれば、存分に<span class="st-mymarker-s">多重非同期の効果</span>を確認してみてください。</p>
<h2>主要な基底処理（S3のデータ読み込み～オブジェクト削除）</h2>
<p>まずはS3からのトリガーを処理している方の簡単な流れから説明します。</p>
<p><strong>AbstractS3PutTriggerCommon　　540行目近辺</strong></p>
<pre><code class="language-js">  AbstractS3PutTriggerCommon.prototype.AbstractBaseCommon.getTasks = function (
    event,
    context
  ) {
    var base = AbstractS3PutTriggerCommon.prototype.AbstractBaseCommon;
    try {
      base.writeLogTrace("AbstractS3PutTriggerCommon# getTasks :start");

      return [
        this.initS3PutTriggerParameter,
        this.waitExistsS3Object,
        this.beforeMainExecute,
        this.businessMainExecute,
        this.afterUnProcessedItemCheck,
        this.afterMainExecute,
      ];
    } catch (err) {
      base.printStackTrace(err);
      throw err;
    } finally {
      base.writeLogTrace("AbstractS3PutTriggerCommon# getTasks :end");
    }
  };</code></pre>
<ul>
<li>initS3PutTriggerParameter　・・・　AWS SDK で S3 の各APIで使う汎用引数を生成</li>
<li>waitExistsS3Object　・・・　putトリガーで対象となったS3オブジェクトのアクセス待機</li>
<li>beforeMainExecute　・・・　S3オブジェクトからファイル読み込み、処理データ整形</li>
<li>businessMainExecute　・・・　非同期多重実行の制御</li>
<li>afterUnProcessedItemCheck　・・・　DynamoDBへの登録残件の有無判定</li>
<li>afterMainExecute　・・・　S3のオブジェクト削除</li>
</ul>
<p>それぞれの関数の詳細は、実際の関数を見てもらうとして、、、「やってみた系」では、よく省略されている、「<span class="st-mymarker-s">～S3.waitFor(&#8220;objectExists&#8221;～</span>」の必要性について訴えていきたいと思います。</p>
<p>S3の<span class="hutoaka"><span class="huto">putトリガー</span></span>はLambdaで、すぐにアクセスすると<span class="st-mymarker-s">「オブジェクトが存在しない！」というエラー</span>でErrorをスローする事があります。</p>
<p><span class="hutoaka"><span class="huto">Errorをスローする事があります。</span></span>（大事な事なので2回書きます）</p>
<p>もう１つ、紛らわしい事があってS3の障害時や、ちょっとだけ調子が悪くなった時（ネットワーク遅延）などに、<span class="st-mymarker-s">1回のS3オブジェクト保存</span>で、putトリガーが<span class="st-mymarker-s">同じ内容で２～３回起動</span>される事があります。</p>
<p>後続の処理では、<span class="st-mymarker-s">リトライ＆再実行が行われても問題ないような連携仕様</span>にしておくと幸せになれる。と<span class="st-mymarker-s">留意が必要</span>です。</p>
<p>その点、DynamoDBへの連携は上書きされるだけなので、選択肢としては申し分なしですね。</p>
<h2>主要なワーカー処理（DynamoDBへの一括登録）</h2>
<p>制御側から受け取ったデータをDynamoDBへ一括登録する処理になります。</p>
<p><strong>AbstractWorkerDynamoDbBatchPutCommon　・・・490行付近</strong></p>
<pre><code class="language-js"> AbstractWorkerDynamoDbBatchPutCommon.prototype.AbstractBaseCommon.getTasks = function (
    event,
    context
  ) {
    var base =
      AbstractWorkerDynamoDbBatchPutCommon.prototype.AbstractBaseCommon;
    try {
      base.writeLogTrace(
        "AbstractWorkerDynamoDbBatchPutCommon# getTasks :start"
      );

      return [
        this.beforeMainExecute,
        this.transformRecordInfos,
        this.businessMainExecute,
      ];
    } catch (err) {
      base.printStackTrace(err);
      throw err;
    } finally {
      base.writeLogTrace("AbstractWorkerDynamoDbBatchPutCommon# getTasks :end");
    }
  };
</code></pre>
<ul>
<li>beforeMainExecute　・・・　制御側から受け取ったデータを返却</li>
<li>transformRecordInfos　・・・　オーバライド用関数の呼び出しとデータ重複排除処理</li>
<li>businessMainExecute　・・・　DynamoDBへの登録実行＆リトライ</li>
</ul>
<p>DynamoDBには、<a href="https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html#batchWriteItem-property">batchWriteItem</a>という複数データを一度に登録するAPIがありますが、<span class="st-mymarker-s">データを渡しても必ずしも登録される訳ではない。</span>というのが注意点になりますかね。<br />APIのレスポンス情報の、<span class="st-mymarker-s">UnprocessedItems</span>に登録されなかった情報が返却されるので、<span class="st-mymarker-s">登録されなかった分は使い手側でハンドリングしろよ。</span>という仕様です。<br />サンプルはリトライ上限（環境変数で設定）を設けて、処理して貰えるまで何度かリトライ（1秒待機）するという感じにしてあります。</p>
<h2>主要なカスタマイズ（読み込み行データからテーブル項目への変換）</h2>
<p><strong>SampleWorkerDynamoDbBatchPutModule　・・・　30行目付近</strong></p>
<pre><code class="language-js">      var argLine = String(record);
      base.writeLogTrace(
        "SampleWorkerDynamoDbBatchPutModule# argLine" + argLine
      );
      var values = argLine.split(",");

      var primaryKey = base.getPrimaryKey();
      var sortKey = base.getSortKey();

      var rtnObj = {};
      rtnObj[primaryKey] = { S: values[0] };
      rtnObj[sortKey] = { S: values[1] };
      rtnObj.ColumnB = { S: values[2] };

      base.writeLogTrace(
        "SampleWorkerDynamoDbBatchPutModule# JSON :" + JSON.stringify(rtnObj)
      );

      return rtnObj;
</code></pre>
<p><br />ファイルから読み込んだ1行のデータを引数で受けて、<span class="st-mymarker-s">DynamoDBに登録する為の項目マッピング</span>する部分は、末端のクラスに<span class="st-mymarker-s">関数を切り出し</span>てあるので、<span class="st-mymarker-s">DynamoDBのカラム＆設計に合わせて書き直すだけで流用できる</span>ようにしてあります。</p>
<p>SortKeyをテーブルに定義していない場合は、基底側（AbstractBaseCommon.transformRecordInfos）の一括登録データ内の<span class="st-mymarker-s">重複データを排除する処理に修正</span>が必要です。</p><p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></content:encoded>
					
					<wfw:commentRss>https://awsblog.physalisgp02.com/2020/07/08/s3-put%e3%83%88%e3%83%aa%e3%82%ac%e3%83%bc-lambda-dynamodb-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>DynamoDB Stream + Lambda + SNS(Simple Notification Service) の連携処理をやってみた</title>
		<link>https://awsblog.physalisgp02.com/2020/07/03/dynamodb-stream-lambda-snssimple-notification-service-%e3%81%ae%e9%80%a3%e6%90%ba%e5%87%a6%e7%90%86%e3%82%92%e3%82%84%e3%81%a3%e3%81%a6%e3%81%bf%e3%81%9f/</link>
					<comments>https://awsblog.physalisgp02.com/2020/07/03/dynamodb-stream-lambda-snssimple-notification-service-%e3%81%ae%e9%80%a3%e6%90%ba%e5%87%a6%e7%90%86%e3%82%92%e3%82%84%e3%81%a3%e3%81%a6%e3%81%bf%e3%81%9f/#respond</comments>
		
		<dc:creator><![CDATA[syo]]></dc:creator>
		<pubDate>Fri, 03 Jul 2020 07:41:58 +0000</pubDate>
				<category><![CDATA[設計思想とプログラム]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[DynamoDB]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[Sample]]></category>
		<category><![CDATA[SNS]]></category>
		<category><![CDATA[SQS]]></category>
		<category><![CDATA[やってみた]]></category>
		<category><![CDATA[サンプル]]></category>
		<guid isPermaLink="false">https://awsblog.physalisgp02.com/?p=163</guid>

					<description><![CDATA[前説 前回の投稿でサンプルソースを掲載しましたが、いわゆる「やってみた系記事」のように、関連AWSサービスを、どう設定するか簡単に説明していきたいと思います。 Lambdaの関数登録手順は、今回は省い ... <p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<h2>前説</h2>
<p><a href="https://awsblog.physalisgp02.com/2020/07/02/dynamodb-stream-lambda-snssimple-notification-service-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/">前回の投稿</a>でサンプルソースを掲載しましたが、いわゆる「<span class="st-mymarker-s">やってみた系記事</span>」のように、関連AWSサービスを、どう設定するか簡単に説明していきたいと思います。<br />
Lambdaの関数登録手順は、今回は省いて、<span class="st-mymarker-s">周辺AWSサービスの設定</span>に焦点をあてて記事を書いていきます。</p>
<h2>DynamoDBの設定</h2>
<p>まずは、DynamoDBのテーブルのプロパティで「概要」タブの中から「ストリーム管理」をクリックして、<span class="st-mymarker-s">ストリーム管理の有効化</span>を行います。下記図</p>
<p><img class="aligncenter wp-image-164 size-large" src="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/DynamoDBストリーム有効-1024x521.jpg" alt="" width="920" height="468" srcset="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/DynamoDBストリーム有効-1024x521.jpg 1024w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/DynamoDBストリーム有効-300x153.jpg 300w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/DynamoDBストリーム有効-768x391.jpg 768w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/DynamoDBストリーム有効.jpg 1172w" sizes="(max-width: 920px) 100vw, 920px" /></p>
<p>次に、DynamoDBのテーブルからトリガーとして、登録したLambdaを指定します。</p>
<p><img class="aligncenter size-large wp-image-165" src="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/DynamoDBトリガー登録-1024x431.jpg" alt="" width="920" height="387" srcset="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/DynamoDBトリガー登録-1024x431.jpg 1024w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/DynamoDBトリガー登録-300x126.jpg 300w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/DynamoDBトリガー登録-768x323.jpg 768w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/DynamoDBトリガー登録.jpg 1441w" sizes="(max-width: 920px) 100vw, 920px" /></p>
<p>&nbsp;</p>
<p>この設定だけで、テーブルのデータに変更があった際に、DynamoDB Streamから変更データを供って、Lambdaを起動するように準備ができました。</p>
<h2>SQS（Simple Queue Service）の設定</h2>
<p>SNS（Simple Notification Service）のトピックが実行できているか確認する為に、SQS（Simple Queue Service）も併せて設定しておくと良いでしょう。</p>
<p>キューの作成は下記の通り、クイック作成で構いません。</p>
<p><img class="aligncenter size-full wp-image-166" src="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SQSキュー作成.jpg" alt="" width="883" height="699" srcset="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SQSキュー作成.jpg 883w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SQSキュー作成-300x237.jpg 300w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SQSキュー作成-768x608.jpg 768w" sizes="(max-width: 883px) 100vw, 883px" /></p>
<p>SNSからSQSに情報連携する際には、<span class="st-mymarker-s">SQS側にアクセス許可を与える必要</span>があります。<br />
<span class="st-mymarker-s"><strong>※忘れがちですが、注意しましょう！</strong></span></p>
<p><img class="aligncenter size-large wp-image-168" src="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SQSアクセス制限の許可-1-1024x584.jpg" alt="" width="920" height="525" srcset="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SQSアクセス制限の許可-1-1024x584.jpg 1024w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SQSアクセス制限の許可-1-300x171.jpg 300w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SQSアクセス制限の許可-1-768x438.jpg 768w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SQSアクセス制限の許可-1.jpg 1189w" sizes="(max-width: 920px) 100vw, 920px" /></p>
<ul>
<li>条件：ArnLike</li>
<li>キー：aws:SourceArn</li>
<li>値：arn:aws:sns:リージョン名:AWSアカウントID:*</li>
</ul>
<p>で、発信元を自AWSアカウントのSNSからのアクセスのみ受け付けるように限定できます。</p>
<p>サブスクリプション登録用に、SQSのARNをメモしておく。</p>
<p><img class="aligncenter size-large wp-image-170" src="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SQSのARN確認-1024x386.jpg" alt="" width="920" height="347" srcset="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SQSのARN確認-1024x386.jpg 1024w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SQSのARN確認-300x113.jpg 300w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SQSのARN確認-768x289.jpg 768w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SQSのARN確認.jpg 1396w" sizes="(max-width: 920px) 100vw, 920px" /></p>
<h2>SNS（Simple Notification Service）の設定</h2>
<p><img class="aligncenter size-full wp-image-169" src="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SNS新規作成.jpg" alt="" width="933" height="720" srcset="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SNS新規作成.jpg 933w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SNS新規作成-300x232.jpg 300w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SNS新規作成-768x593.jpg 768w" sizes="(max-width: 933px) 100vw, 933px" /></p>
<p>トピックを作成したら、トピックの詳細画面からSQSをサブスクリプションとして追加する。</p>
<p><img class="aligncenter size-full wp-image-171" src="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/サブスクリプションの作成.jpg" alt="" width="940" height="729" srcset="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/サブスクリプションの作成.jpg 940w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/サブスクリプションの作成-300x233.jpg 300w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/サブスクリプションの作成-768x596.jpg 768w" sizes="(max-width: 940px) 100vw, 940px" /></p>
<p>後は、SNSのARNをメモします。</p>
<p><img class="aligncenter size-large wp-image-172" src="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SNSのARN-1024x370.jpg" alt="" width="920" height="332" srcset="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SNSのARN-1024x370.jpg 1024w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SNSのARN-300x108.jpg 300w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SNSのARN-768x277.jpg 768w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/SNSのARN.jpg 1359w" sizes="(max-width: 920px) 100vw, 920px" /></p>
<h2>Lambdaの環境変数設定</h2>
<p><img class="aligncenter size-large wp-image-173" src="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/Lambdaの環境変数-1024x309.jpg" alt="" width="920" height="278" srcset="https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/Lambdaの環境変数-1024x309.jpg 1024w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/Lambdaの環境変数-300x91.jpg 300w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/Lambdaの環境変数-768x232.jpg 768w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/07/Lambdaの環境変数.jpg 1318w" sizes="(max-width: 920px) 100vw, 920px" /></p>
<p>Lambdaの環境変数：<span class="st-mymarker-s">TargetSnsTopicArn</span>に、前手順でメモした<span class="st-mymarker-s">SNSのARNを設定</span>します。</p>
<p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></content:encoded>
					
					<wfw:commentRss>https://awsblog.physalisgp02.com/2020/07/03/dynamodb-stream-lambda-snssimple-notification-service-%e3%81%ae%e9%80%a3%e6%90%ba%e5%87%a6%e7%90%86%e3%82%92%e3%82%84%e3%81%a3%e3%81%a6%e3%81%bf%e3%81%9f/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>DynamoDB Stream + Lambda + SNS(Simple Notification Service) のサンプルソース</title>
		<link>https://awsblog.physalisgp02.com/2020/07/02/dynamodb-stream-lambda-snssimple-notification-service-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/</link>
					<comments>https://awsblog.physalisgp02.com/2020/07/02/dynamodb-stream-lambda-snssimple-notification-service-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/#respond</comments>
		
		<dc:creator><![CDATA[syo]]></dc:creator>
		<pubDate>Thu, 02 Jul 2020 04:37:35 +0000</pubDate>
				<category><![CDATA[Lambdaサンプルソース]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[Sample]]></category>
		<category><![CDATA[サンプル]]></category>
		<guid isPermaLink="false">http://awsblog.physalisgp02.com/?p=156</guid>

					<description><![CDATA[前説 次は、どの組み合わせのサンプルにしようか、若干迷ったのですが、DynamoDBへの登録処理のサンプルソースを掲載したので、DynamoDBに絡めて DynamoDB Stream からトリガーで ... <p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<h2>前説</h2>
<p>次は、どの組み合わせのサンプルにしようか、若干迷ったのですが、DynamoDBへの登録処理のサンプルソースを掲載したので、DynamoDBに絡めて <a href="https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Streams.html">DynamoDB Stream</a> からトリガーでLambdaを実行して、AWS SNSに通知するサンプルソースを選択してみました。 せっかくなので<a href="http://awsblog.physalisgp02.com/2020/06/26/%e5%ae%9f%e6%88%a6%e7%9a%84%e3%81%aalambda%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9-%e3%81%9d%e3%81%ae%ef%bc%92/">サンプル２</a>の多重度指定つき並行処理を雛形に組み上げしています。</p>
<h2>githubにて公開</h2>
<p>DynamoDB Stream + Lambda + SNS(Simple Notification Service) のサンプルソースです。</p>
<p>ダウンロードは下記より <br /><a href="https://github.com/SyoAwsBlog/ShoLambdaSample04">https://github.com/SyoAwsBlog/ShoLambdaSample04</a></p>
<p>・Dynamo Streamから<span class="st-mymarker-s">新規登録（INSERT）のレコードのみ</span>を<span class="st-mymarker-s">SNSに通知</span>する</p>

<h2>利用可能な環境変数</h2>

<figure class="wp-block-table">
<table>
<thead>
<tr>
<th>変数名</th>
<th>変数値</th>
</tr>
</thead>
<tbody>
<tr>
<td>LogLevel</td>
<td>ログの出力レベルを(0～4）までの間で設定する</td>
</tr>
<tr>
<td>LogLevelForWorker</td>
<td>ログの出力レベルを(0～4）までの間で設定する(ワーカー処理（疑似スレッド処理）)</td>
</tr>
<tr>
<td>ExecutorsThreadsNum</td>
<td>並行処理の多重度を数字で指定</td>
</tr>
<tr>
<td>ExecutorsThreadsWait</td>
<td>ワーカー処理（疑似スレッド処理）毎に Sleepを入れられる（ミリ秒指定）</td>
</tr>
<tr>
<td>TargetSnsTopicArn</td>
<td>通知先のSNS TopicのARNを指定する</td>
</tr>
<tr>
<td>autoFunctionRetry</td>
<td>省略したらエラー時再実行はしない。0より大きい値（数字）を設定すると、その回数、再実行を行う</td>
</tr>
</tbody>
</table>
</figure>

<h2>概要</h2>
<p>組み上げには、<a href="http://awsblog.physalisgp02.com/2020/06/26/%e5%ae%9f%e6%88%a6%e7%9a%84%e3%81%aalambda%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9-%e3%81%9d%e3%81%ae%ef%bc%92/">サンプル２</a>を利用してみました。転用して実装すると、こんなイメージになります。<br />動作確認にも、特にコードを変更せずに、関連サービスの設定とLambda環境変数指定で動くようにしてあります。</p>
<h2>主要な基底処理</h2>
<p><strong>AbstractDynamoDbStreamCommon　120行目近辺</strong></p>
<pre><code class="language-js">     return new Promise(function (resolve, reject) {
        if (event &amp;&amp; event.Records) {
          resolve(event.Records);
        } else {
          reject("event.Records Not Exists");
        }
      });
</code></pre>
<p>がポイントになるでしょう。DynamoDB Streamからの引数の中身は、下記のようなイメージです。</p>
<p>Records配下に DynamoDB Stream で連携されてきた各行の変更内容が連携されてくるので、そのデータを取得します。</p>
<pre><code class="language-jsonp">{
    "Records": [
        {
            "eventID": "0123456789XXXXXXXXXXXXXXXX",
            "eventName": "INSERT",
            "eventVersion": "1.1",
            "eventSource": "aws:dynamodb",
            "awsRegion": "リージョン名",
            "dynamodb": {
                "ApproximateCreationDateTime": 1600000000,
                "Keys": {
                    "PrimaryKey": {
                        "S": "XXXXX"
                    }
                },
                "NewImage": {
                    "ColumnB": {
                        "S": "YYYYY"
                    },
                    "ColumnC": {
                        "S": "ZZZZZ"
                    },
                    "SortKey": {
                        "S": "2020-07-01T00:00:00.000+0900"
                    },
                    "PrimaryKey": {
                        "S": "XXXXX"
                    }
                },
                "SequenceNumber": "0123456789XXXXXXXXXXXXXXXX",
                "SizeBytes": 88,
                "StreamViewType": "NEW_AND_OLD_IMAGES"
            },
            "eventSourceARN": "arn:aws:dynamodb:リージョン:AWSアカウントID:table/テーブル名/stream/2020-07-01T00:00:00.000"
        }
    ]
}
</code></pre>
<p>&nbsp;</p>
<p><strong>AbstractWorkerSnsCallTopicCommon</strong></p>
<pre><code class="language-js">
  AbstractWorkerSnsCallTopicCommon.prototype.AbstractBaseCommon.getTasks = function (
    event,
    context
  ) {
    var base = AbstractWorkerSnsCallTopicCommon.prototype.AbstractBaseCommon;
    try {
      base.writeLogTrace("AbstractWorkerSnsCallTopicCommon# getTasks : start");
      return [
        this.beforeMainExecute,
        this.extractBizInfos,
        this.transformRecordInfos,
        this.businessMainExecute,
        this.afterMainExecute,
      ];
    } catch (err) {
      base.printStackTrace(err);
      throw err;
    } finally {
      base.writeLogTrace("AbstractWorkerSnsCallTopicCommon# getTasks : end");
    }
  };
</code></pre>
<ul>
<li>beforeMainExecute  ・・・ DynamoDB Streamの1行データを返却</li>
<li>extractBizInfos　・・・ 新規登録行のみを連携データとする判定</li>
<li>transformRecordInfos　・・・  AWS SDKのAPI利用用にパラメータ組み立て</li>
<li>businessMainExecute　・・・　API実行</li>
<li>afterMainExecute　・・・　API実行後のログ出力</li>
</ul>
<p>といった処理の流れになっています。</p>
<p>動作させる為のAWS設定手順は、別記事にて掲載予定。</p><p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></content:encoded>
					
					<wfw:commentRss>https://awsblog.physalisgp02.com/2020/07/02/dynamodb-stream-lambda-snssimple-notification-service-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>サンプルソースの流用方法について</title>
		<link>https://awsblog.physalisgp02.com/2020/06/30/%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9%e3%81%ae%e6%b5%81%e7%94%a8%e6%96%b9%e6%b3%95%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6/</link>
					<comments>https://awsblog.physalisgp02.com/2020/06/30/%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9%e3%81%ae%e6%b5%81%e7%94%a8%e6%96%b9%e6%b3%95%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6/#respond</comments>
		
		<dc:creator><![CDATA[syo]]></dc:creator>
		<pubDate>Tue, 30 Jun 2020 08:08:15 +0000</pubDate>
				<category><![CDATA[Lambdaサンプルソース]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[Sample]]></category>
		<category><![CDATA[サンプル]]></category>
		<guid isPermaLink="false">http://awsblog.physalisgp02.com/?p=128</guid>

					<description><![CDATA[前説 あらためてサンプルソースを使って、前回のようなDynamoDBへのアクセスをするLambdaを実装する場合を例として、手順・ポイントを説明したいと思います。 自分流のお作法的な所もありますが、慣 ... <p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<h2>前説</h2>
<p>あらためてサンプルソースを使って、前回のようなDynamoDBへのアクセスをするLambdaを実装する場合を例として、手順・ポイントを説明したいと思います。<br />
自分流のお作法的な所もありますが、慣れるとログが読みやすい・デバックしやすいなどのテクニックもあるので、このサイトの雛形を使ってLambdaを実装してみよう。と思う方は、簡単に目を通してください。</p>
<h2>開発環境</h2>
<p>筆者の<span class="st-mymarker-s">開発環境</span>について掲載しておきます。</p>
<ul>
<li><strong>ソース管理</strong>：Git</li>
<li><strong>ソース管理</strong>：TortoiseGit + TortoiseGit-LanguagePack</li>
<li><strong>開発環境</strong>：VSCode</li>
<li><strong>テキストエディタ</strong>：さくらエディタ</li>
</ul>
<p>VSCodeのプラグインは、ほとんど入れてない状況です。<br />
自分は、古風？人間なので、<span class="st-mymarker-s">さくらエディタのみ</span>の<span class="st-mymarker-s">エディタ開発</span>でLambdaを制作する事が、<span class="st-mymarker-s">苦でもなかったり</span>ます。<br />
なのですがブログ掲載するにあたり、流石にフォーマッターで整形したソースにしないとお目汚しがヒドイかな。。。と思い、VSCodeを使い始めました。</p>
<p>githubで公開しているソースは、VSCodeの<span class="st-mymarker-s">デフォルトフォーマッターで整形したソース</span>になっています。</p>
<h2>手順１．githubからソースを取得</h2>
<p><div id="attachment_131" style="width: 930px" class="wp-caption aligncenter"><img aria-describedby="caption-attachment-131" class="wp-image-131 size-large" src="http://awsblog.physalisgp02.com/wp-content/uploads/2020/06/githubからのダウンロード-1024x629.jpg" alt="Github画面からのダウンロード" width="920" height="565" srcset="https://awsblog.physalisgp02.com/wp-content/uploads/2020/06/githubからのダウンロード-1024x629.jpg 1024w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/06/githubからのダウンロード-300x184.jpg 300w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/06/githubからのダウンロード-768x472.jpg 768w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/06/githubからのダウンロード.jpg 1149w" sizes="(max-width: 920px) 100vw, 920px" /><p id="caption-attachment-131" class="wp-caption-text">Githubからのダウンロード操作</p></div></p>
<p>ダウンロードした Zipファイルを解凍したら、サンプルソースの開発用フォルダが展開されます。<br />
<a href="http://awsblog.physalisgp02.com/2020/06/23/%e5%ae%9f%e6%88%a6%e7%9a%84%e3%81%aalambda%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9/">サンプル１</a>、<a href="http://awsblog.physalisgp02.com/2020/06/26/%e5%ae%9f%e6%88%a6%e7%9a%84%e3%81%aalambda%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9-%e3%81%9d%e3%81%ae%ef%bc%92/">サンプル２</a>、のソースなどは、展開して出てきたZipファイル（ShoLambdaSample.zip、ShoLambdaSample02.zip）を、そのままAWS Lambdaに登録して動かす事も可能です。（CloudWatchへのログ出力のみ）</p>
<h2>手順２．VSCodeへの登録</h2>
<p><div id="attachment_135" style="width: 930px" class="wp-caption aligncenter"><img aria-describedby="caption-attachment-135" class="wp-image-135 size-large" src="http://awsblog.physalisgp02.com/wp-content/uploads/2020/06/VSCodeで開く-1024x522.jpg" alt="VSCode画面" width="920" height="469" srcset="https://awsblog.physalisgp02.com/wp-content/uploads/2020/06/VSCodeで開く-1024x522.jpg 1024w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/06/VSCodeで開く-300x153.jpg 300w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/06/VSCodeで開く-768x391.jpg 768w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/06/VSCodeで開く.jpg 1176w" sizes="(max-width: 920px) 100vw, 920px" /><p id="caption-attachment-135" class="wp-caption-text">VSCodeでフォルダを開く</p></div></p>
<p>細かい業務処理を実装・編集する場合には、VSCodeの方が良いでしょう。</p>
<h2>手順３．ファイル名・クラス名の変更（命名のリファクタリング）</h2>
<p>継承ツリー上、雛形から転用する際に個人で命名して欲しい階層は、２つです。</p>
<ul>
<li><strong>機能共通：</strong>AbstractBizUnitCommon　　<strong>→</strong>　<span class="st-mymarker-s">DynamoDBに登録する為の共通処理だと分かる名前</span>へ変更する</li>
<li><strong>業務名：</strong>SampleBIzModule　→　ユーザ登録機能・グループ登録機能など、<span class="st-mymarker-s">業務に由来する名前</span>へ変更する</li>
</ul>
<p>先日の<a href="http://awsblog.physalisgp02.com/2020/06/29/api-gateway-lambda-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9%ef%bc%88%e7%99%bb%e9%8c%b2%e3%83%bb%e6%9b%b4%e6%96%b0%ef%bc%89putite/">サンプルソース</a>では、</p>
<ul>
<li>機能共通：AbstractBizDynamoPutCommon</li>
<li>業務名：SampleBizDynamoPutModule</li>
</ul>
<p>と変更しました。</p>
<p>まではエクスプローラーなどで、それぞれのファイル名を<br />
<strong>変更前：</strong>AbstractBizUnitCommon.js　→　<strong>変更後：</strong>AbstractBizDynamoPutCommon.js<br />
<strong>変更前：</strong>SampleBIzModule.js　→　<strong>変更後：</strong>SampleBIzDynamoPutModule.js<br />
に変更します。</p>
<p>ファイル名の変更に伴って、それぞれ（AbstractBizDynamoPutCommon.js、SampleBIzModule.js）のファイルの中身も、さくらエディタの<span class="st-mymarker-s">一括置換機能</span>を使って置き換えます。</p>
<p><strong>置換前：</strong>AbstractBizUnitCommon　→　<strong>置換後：</strong>AbstractBizDynamoPutCommon<br />
<strong>置換前：</strong>SampleBIzModule　→　<strong>置換後：</strong>SampleBIzDynamoPutModule</p>
<p><div id="attachment_137" style="width: 930px" class="wp-caption aligncenter"><img aria-describedby="caption-attachment-137" class="wp-image-137 size-large" src="http://awsblog.physalisgp02.com/wp-content/uploads/2020/06/一括置換-1024x546.jpg" alt="さくらエディタ" width="920" height="491" srcset="https://awsblog.physalisgp02.com/wp-content/uploads/2020/06/一括置換-1024x546.jpg 1024w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/06/一括置換-300x160.jpg 300w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/06/一括置換-768x410.jpg 768w, https://awsblog.physalisgp02.com/wp-content/uploads/2020/06/一括置換.jpg 1207w" sizes="(max-width: 920px) 100vw, 920px" /><p id="caption-attachment-137" class="wp-caption-text">一括置換機能の使い方</p></div></p>
<h2>手順４．継承関係の整備</h2>
<p>前手順でファイル名を変更しているので、読み込むファイル名を変更後のファイル名に変更する必要があります。</p>
<p>SampleBIzDynamoPutModule.js は、AbstractBizDynamoPutCommon.jsを読み込むように変更します。</p>
<p>index.jsは、SampleBIzDynamoPutModule.js を読み込むように変更します。</p>
<p><strong>SampleBIzDynamoPutModule.js</strong></p>
<pre><code class="language-js">module.exports = function SampleBizDynamoPutModule() {
  // 疑似的な継承関係として親モジュールを読み込む
  var superClazzFunc = new require("./AbstractBizDynamoPutCommon.js");
  // prototypeにセットする事で継承関係のように挙動させる
  SampleBizDynamoPutModule.prototype = new superClazzFunc();
</code></pre>
<p>&nbsp;</p>
<p><strong>index.js</strong></p>
<pre><code class="language-js">  // 非同期実行関数の宣言
  function* main() {
    try {
      // 業務用の処理を書いたモジュールを読み込む
      var executeBizModule = require("./SampleBizDynamoPutModule");
      var executeBizObject = new executeBizModule();
</code></pre>
<p>具体的には、上記の require で、ファイルを読み込んでいるのでファイル名の変更に合わせて名称変更をします。</p>
<h2>業務共通処理の実装</h2>
<p><a href="http://awsblog.physalisgp02.com/2020/06/29/api-gateway-lambda-%e3%81%ae%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9%ef%bc%88%e7%99%bb%e9%8c%b2%e3%83%bb%e6%9b%b4%e6%96%b0%ef%bc%89putite/">前回の投稿</a>でも書きましたが、処理の構造を設計して、直列処理の単位で割り当てます。</p>
<ul>
<li>initEventParameter    ・・・   API Gatewayから起動引数の取り扱い（おまじない）とブラウザへの戻り値初期化</li>
<li>beforeMainExecute　・・・　DynamoDBへの登録情報を生成する処理</li>
<li>businessMainExecute　・・・　DynamoDBへの putItem処理を実行</li>
<li>afterMainExecute　・・・　ブラウザへの戻り値を成功で上書き</li>
</ul>
<p>DynamoDBへの登録の共通処理としては、上記の4処理を組み込むと設計しました。</p>
<p><strong>AbstractBizDynamoPutCommon</strong></p>
<pre><code class="language-js">  AbstractBizDynamoPutCommon.prototype.AbstractBaseCommon.getTasks = function (
    event,
    context
  ) {
    var base = AbstractBizDynamoPutCommon.prototype.AbstractBaseCommon;
    try {
      base.writeLogTrace("AbstractBizDynamoPutCommon# getTasks :start");

      return [
        base.initEventParameter,
        base.beforeMainExecute,
        base.businessMainExecute,
        base.afterMainExecute,
      ];
    } catch (err) {
      base.printStackTrace(err);
      throw err;
    } finally {
      base.writeLogTrace("AbstractBizDynamoPutCommon# getTasks :end");
    }
  };</code></pre>
<p>のように、<span class="st-mymarker-s">getTasks をオーバーライド</span>する事で、直列処理を追加できるので、上記のように業務共通処理層（AbstractBizDynamoPutCommon）に記述することで直列処理を４つにできます。</p>
<p><strong>AbstractBizDynamoPutCommon</strong></p>
<pre><code class="language-js">  AbstractBizDynamoPutCommon.prototype.AbstractBaseCommon.関数名= function (
    args
  ) {
    var base = AbstractBizDynamoPutCommon.prototype.AbstractBaseCommon;
    try {
      base.writeLogTrace(
        "AbstractBizDynamoPutCommon# 関数名 : start"
      );
      
      // ～～　ここに実装する　～～

    } catch (err) {
      base.printStackTrace(err);
      throw err;
    } finally {
      base.writeLogTrace("AbstractBizDynamoPutCommon# 関数名: end");
    }
  }.bind(AbstractBizDynamoPutCommon.prototype.AbstractBaseCommon);
</code></pre>
<p>直列処理を追加する場合は、<span class="st-mymarker-s">上記をコピペして、関数名を好きな名前に変更</span>して、ご利用ください。<br />
※ <span class="st-mymarker-s">追加したら <span class="huto">getTasks</span>への追加を忘れずに！</span></p>
<p>Copyright &copy; 2026 <a href="https://awsblog.physalisgp02.com">とあるAWSエンジニアの戯言</a> All Rights Reserved.</p>]]></content:encoded>
					
					<wfw:commentRss>https://awsblog.physalisgp02.com/2020/06/30/%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%82%bd%e3%83%bc%e3%82%b9%e3%81%ae%e6%b5%81%e7%94%a8%e6%96%b9%e6%b3%95%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
