App Engineerの開発ノート

AWS、Flutterや開発活動に役立つツール作りなど

AWS入門~とりあえずWebアプリケーションが公開されるまで

f:id:Simoroid:20210818013157p:plain
AWSを勉強したい・導入したいという場合の
とりあえず最初のWebアプリが公開されるまでの手順です。
所要時間は最速だと20分くらいです。

◇アカウント作成
まずは下記でアカウントを作成します。
https://aws.amazon.com/jp/try-cloud/

個人情報として住所や携帯電話番号、
クレジットカードを差し出す必要があります。
ただし利用に必ずお金が掛かるという訳ではありません。
無料でどこまで使用できるかという情報は下記のサイトにて公開されています。
AWS クラウド無料利用枠 | AWS

あとは住所が英語表記で記載しなければなりませんので、下記のサイトなどを利用すれば楽です。
https://kimini.jp/

◇EC2を起動
AWS マネジメントコンソール(ログイン後のトップページ)から
"仮想マシンの起動"をクリック
基本的には"無料利用枠の対象"の記載がある項目を選択して次へと設定を進めていけば問題無いかと思います。
※本格的にサービスを立ち上げる際は目的に応じたインスタンスタイプの選定が必要です。
f:id:Simoroid:20210818004831p:plainf:id:Simoroid:20210818004835p:plain

◇Elastic Beanstalkを起動
前段と同様にAWS マネジメントコンソールから
"ウェブアプリケーションの構築"をクリック。
任意のアプリケーション名、プラットフォーム情報を入れて、
アプリケーションコードを"サンプルアプリケーション"に設定して、
「アプリケーションの作成」をクリック。
f:id:Simoroid:20210819003013p:plainf:id:Simoroid:20210819003009p:plain

ちなみにEC2などの環境のお金が掛かるため、
Elastic Beanstalk自体にはお金が掛からないようです。
https://aws.amazon.com/jp/elasticbeanstalk/pricing/

その後、Elastic Beanstalk -> アプリケーションから
URLをクリックします。
f:id:Simoroid:20210819003309p:plain
無事にサーバーにアプリが公開されていることが確認できます。
f:id:Simoroid:20210818013400p:plain
以上でAWSを始めてとりあえずアプリを公開になります。
これ以降は独自のアプリ開発やサーバーレスコンピューティングに触れていきたいと思います。
まだAWSの1000分の1も機能を利用してませんが、これだけで何かやった気になる笑

ここまで 読んで頂きありがとうございました。
よければフォローお願いします!

DynamoDBへのデータ登録を楽にする2~データ削除編

f:id:Simoroid:20211014013907p:plain
f:id:Simoroid:20210928002145p:plain
以前、エクセルファイルをインプットとしたDynamoDBへのデータ登録のツールを作りました。今回はその削除版の一括削除のツールを作成します。
ちなみ登録のツール作成方法は下記です。
ikoda.shop

削除ツールも登録ツール同様、Powershellを使用します。

■ツールの概要
削除するには削除対象テーブルのキーの情報が必要になります。
エクセルファイルを元データとして、シート単位にテーブルの削除したいキー情報を記載しておけば、削除用インプットデータが生成できるツールとします。

■前提条件

登録のツールと同様になりますが、
Excelがインストールされている環境である必要があります。
また現状の仕様ではサポートしている型はBOOLとS(文字列)、N(数値)のみになります。

■実装方法

任意ファイル名でps1ファイルを作成します。

gista6418282318a401aeb9fcb7c171e83f1

■使用方法

1.ツールと"data"フォルダを任意フォルダに配置します。
f:id:Simoroid:20211014011539p:plain

2."data"フォルダに下記のようなエクセルファイルを配置します。
めんどくさいのですが、1行目に"PatitionKey"、"RangeKey"を記載しておく必要があります。
※形式を変えると動かなくなるので要注意
f:id:Simoroid:20211014013010p:plain

3.ツールを右クリック->「PowerShellで実行」をクリックで実行
⇒下記のようにA列で指定したデータセットID名でjsonファイルが出来上がる。

f:id:Simoroid:20211014011522p:plainf:id:Simoroid:20211014011608p:plain
出来上がったファイルにはキーの情報のみが記載されています。
f:id:Simoroid:20211014012045p:plain

4.aws cliでデータ削除
ツールで出力されたjsonファイルをbatch-write-itemのパラメータに渡します。
batch-write-item — AWS CLI 1.20.48 Command Reference

aws dynamodb batch-write-item  --request-items  file://del_data_set1.json --endpoint-url http://localhost:4566

ここまで 読んで頂きありがとうございました。
よければフォローお願いします!

DynamoDBへアクセスを行うJavaのLambda関数の単体テスト実施方法

f:id:Simoroid:20211011015609p:plain
DynamoDBへ書き込み・読み込みを行う関数を効率良く単体テストする方法です。
テストデータの事前投入を簡易化することが今回のメインです。

データ投入に今回はエクセルファイル(拡張子がxlsx)を使用します。
エクセルファイルを使用するメリットとして、その試験に使用したデータがブックでまとめられて分かりやすいという点があると思います。
CSVXMLを使用するとファイルサイズが軽量だと思いますがファイルが分散されて割りと探すのが面倒だということがありました。
テストケースとテストデータ(エクセルファイル)が1対1になっていて欲しいという思いです。
f:id:Simoroid:20211011235230p:plain:w240

■事前準備

全体のソースコードは下記で取得可能です。
ソースコードaws公式が公開しているシンプルなlambdaアプリの
プロジェクトであるjava-basicをべースにして改良しています。

git clone https://github.com/YasuoFromDeadScream/lambda_java_unittest.git

また今回DynamoDBへのアクセスは全てローカル環境で実施する必要であるため、Localstackを使用します。
ikoda.shop

■実装ポイント

1.テスト実施クラスの親クラス - DynamoDBTestBase
エクセルファイルに基づいたデータ投入を行う処理を行うベースとなるクラス。
WorkbookFactoryクラスを使用してエクセルファイルを読み込みます。

    String path = "/data/" + excelFileName;
    try {
      in = getClass().getResourceAsStream(path);
      wb = WorkbookFactory.create(in);

テーブルとGSIを作成します。

    CreateTableRequest createTableRequest = dynamoDBMapper.generateCreateTableRequest(pojoClass);
    createTableRequest.setProvisionedThroughput(new ProvisionedThroughput(5L, 1L));
    // GSIの作成
    if (CollectionUtils.isNotEmpty(createTableRequest.getGlobalSecondaryIndexes())) {
      createTableRequest
          .getGlobalSecondaryIndexes()
          .forEach(
              globalSecondaryIndex -> {
                globalSecondaryIndex.setProvisionedThroughput(new ProvisionedThroughput(1L, 1L));
                globalSecondaryIndex.setProjection(
                    new Projection().withProjectionType(ProjectionType.KEYS_ONLY));
              });
    }
    // テーブル作成
    try {
      amazonDynamoDB.createTable(createTableRequest);

テーブルにレコードを詰め込んでいきます。

      Table table = dynamoDB.getTable(sheet.getSheetName());
      table.putItem(item);

2.テスト実施クラス - InvokeTest
DynamoDBTestBaseを継承します。
junitのバージョンに応じてアノテーションは変わってきますが、
junit5では@BeforeEachと@AfterEach使用して試験実施の前後でDBにデータを入れたり消したりします。

  @BeforeEach
  protected void init() {
    super.init();
  }

  @AfterEach
  protected void tearDown()  {
    try {

テストメソッドの適当なタイミングでデータ投入メソッドを呼び出します。
引数はファイル名を指定するのみです。

  @Test
  void invokeTest() throws IOException, ClassNotFoundException {
    logger.info("Invoke TEST");

    insertTestData("sample.xlsx");

3.Model(POJO)クラス
各テーブルのデータを紐づけるためのModelクラスを作成します。
アノテーションを使用してDynamoDBのキーや項目を設定します。

@DynamoDBTable(tableName = "UserInfo")
public class UserInfo {

    @DynamoDBHashKey(attributeName = "UserId")
    @DynamoDBIndexRangeKey(
            globalSecondaryIndexName = "UserInfoIndex1")
    private String userId;

    @DynamoDBRangeKey(attributeName = "UserName")
    private String userName;
■使用方法

投入するエクセルファイルを下記ディレクトリに配置します。
f:id:Simoroid:20211011012724p:plain
各シート名が作成した前述のpojoクラス名と一致している必要があります。
f:id:Simoroid:20211011013004p:plain
あとはjunitに基づいたテストを実施します。

下記のようにscanを使用してDBに登録されたレコードを参照します。

    String result = handler.handleRequest(event, context);

    List<UserInfo> UserInfoList = new ArrayList<>();
    Map<String, AttributeValue> lastKeyEvaluated = null;
    do {
      DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()
              .withExclusiveStartKey(lastKeyEvaluated);
      ScanResultPage<UserInfo> resultResult = dynamoDBMapper.scanPage(UserInfo.class,scanExpression);
      if(resultResult.getCount() > 0){
        UserInfoList.addAll(resultResult.getResults());
      }
      lastKeyEvaluated = resultResult.getLastEvaluatedKey();
    } while (lastKeyEvaluated != null);

   logger.info(UserInfoList.stream().findFirst().toString());
   assertEquals(UserInfoList.get(0).getAge(),22);

f:id:Simoroid:20211011013514p:plain
コンソールにテーブルの内容が表示されて、
処理結果と期待動作の突合せを行い、処理対象が上手くいっているかを確認します。

以上でDynamoDBにアクセスする関数の単体テスト方法を確立できました。
今後はS3やAuroraなどAWSの色々なサービスをテストできるよう拡張できればいいな。

ここまで 読んで頂きありがとうございました。
よければフォローお願いします!

Indexing APIではてなブログ記事のインデックス登録を自動化

f:id:Simoroid:20211001014154p:plain
自動でGoogle Search Consoleはてなブログ記事をインデックス登録する方法です。
インデックス登録が行われなければGoogle 検索によってブログが表示されません。

インデックスの登録はサイトマップを送信することでGoogleにより実施される仕様とのことですが、はてなブログではそのクロールが中々されずインデックス登録されないことがあるらしいです。

簡単な対応方法はSearch Console(Google Search Console)
でブログ記事のURLを直接入力し、インデックス登録をリクエストすることです。
ただ、記事を書くたびにそんな作業を毎回やりたくないのでツールを作って自動化します。

■ツール概要

1.まず始めに記事のURLを取得します。
先日作成した記事の一覧を抽出するツールを使用します。
ikoda.shop
2.Indexing APIを使用して1.で取得したURLに対してインデックス登録リクエストします。

今回ツールはpython(anacondaを使用)で実装します。

■ツール実装

0.下記よりIndexing APIを使用するための準備を行います。
https://developers.google.com/search/apis/indexing-api/v3/prereqs?hl=ja

1.先日作成した記事の一覧を抽出するツール(ps1ファイル)を用意します。

2.同フォルダに下記のpythonファイルを下記で作成します。
尚、必要なモジュールは下記辺りでダウンロード可能です。
https://anaconda.org/conda-forge/google-auth
https://anaconda.org/conda-forge/google-api-python-client
https://anaconda.org/conda-forge/httplib2

from google.oauth2 import service_account
from googleapiclient.http import BatchHttpRequest
from googleapiclient.discovery import build 
import httplib2
import os

# 0.で取得できるjsonファイルです。
JSON_KEY_FILE = "XXXX.json"
SCOPES = [ "https://www.googleapis.com/auth/indexing" ]

credentials = service_account.Credentials.from_service_account_file(
    JSON_KEY_FILE, scopes=SCOPES)

service = build('indexing', 'v3', credentials=credentials)

def insert_event(request_id, response, exception):
    print(response	)
    print(request_id)
    if exception is not None:
       # Do something with the exception
       pass
    else:
       # Do something with the response
       pass

# "output_articles.ps1"は1.で用意したps1ファイルです。
os.system('powershell -Command' + ' ' +\
          'powershell -ExecutionPolicy RemoteSigned .\\output_articles.ps1 > articles.txt')
articles_list = [] 
with open('./articles.txt') as f:
    for line in f:
       res_list.append(line.replace("\n",""))

batch = service.new_batch_http_request(callback=insert_event)

for item in res_list:
	batch.add(service.urlNotifications().publish(
    body={"url": item , "type": "URL_UPDATED"}))

batch.execute()
■ツール実行

pythonファイルを実行
f:id:Simoroid:20211001011812p:plain
⇒リクエストが完了しました。
尚、リクエストなので即時反映される訳ではありません。
翌日あたりにSearch Consoleを覗きにいくと下記のように登録に成功しています!
f:id:Simoroid:20211001011803p:plain

ここまで 読んで頂きありがとうございました。
よければフォローお願いします!

はてなブログの記事一覧をPowerShellだけでお手軽に抽出

f:id:Simoroid:20210929002308p:plain
自分がはてなブログ作成した記事の一覧を抽出するための方法です。
スクレイピングするやり方も一つの手だと思いますが、PowerShellだけでサクッとやることが出来ました。

記事の一覧はブログに紐づくサイトマップを参照することで参照可能です。
自分のはてなブログサイトマップは「https://ikoda.shop/sitemap.xml」のような形式でアクセス可能です。
※100記事以上ある場合にurlの形式が変わってくるようなのですが、とりあえず無視します。

■ツール実装
下記を張り付けて任意のファイル名(拡張子がps1)で保存。

# サイトマップのURLを指定
$url = 'https://ikoda.shop/sitemap.xml'
$res = Invoke-WebRequest $url
$xmlObj = [xml]$res.Content

foreach($sitemap in $xmlObj.sitemapindex.sitemap){
	$res = Invoke-WebRequest $sitemap.loc
	$locObj = [xml]$res.Content
	
	foreach($urlset in $locObj.urlset){
		# 静的ページを省くためフィルタを適用
		if($urlset.url.loc -like "*/entry/*"){
			echo $urlset.url.loc
		}
	}
}
pause

■実行
ツールを右クリック->「PowerShellで実行」をクリックで実行

f:id:Simoroid:20210929001413p:plain
f:id:Simoroid:20210929001422p:plain

こんな感じでとれましたー

ここまで 読んで頂きありがとうございました。
よければフォローお願いします!

DynamoDBへのデータ登録を楽にする

f:id:Simoroid:20210928002145p:plain
DynamoDBへのデータ登録を簡易化するためのツールを作ります。
BatchWriteItemというcommandを使用することで一括のデータ登録ができます。
batch-write-item — AWS CLI 1.20.48 Command Reference

今回は上記commandに使用するインプットデータ(jsonファイル)を自動生成します。
ツールはPowershellを使用します。

■ツールの概要
ツールでインプットデータを生成する元データは出来れば設計書を流用し、
新たな加工の手間が無く、そのまま使用できれば理想的かと思います。
f:id:Simoroid:20210928000012p:plain

今回はエクセルファイルを元データとして、
シート単位にテーブルの登録したい情報を記載しておけば、
インプットデータが生成できるツールとします。

■前提条件

PowershellExcelオブジェクトを使用する為、
Excelがインストールされている環境である必要があります。
ExcelがインストールされていなくてもClosedXMLという代替えのモジュールが
ありますが、それはまた別途記載します。

また、現状の仕様ではサポートしている型はBOOLとS(文字列)、N(数値)のみになります。※将来的には全ての型をサポートしたいが一旦上記の型のみで個人的には満足しています。

■実装方法

ソースコードのボリュームが結構おおきくなったので、
実装方法の説明は省略します。とりあえずコピペでps1ファイルで保存します。

■使用方法

1.ツールと"data"フォルダを任意フォルダに配置します。
f:id:Simoroid:20210928000039p:plain

2."data"フォルダに下記のようなエクセルファイルを配置します。
※形式を変えると動かなくなるので要注意
f:id:Simoroid:20210928000118p:plain

3.ツールを右クリック->「PowerShellで実行」をクリックで実行
⇒下記のようにA列で指定したデータセットID名でjsonファイルが出来上がる。

f:id:Simoroid:20210928000129p:plainf:id:Simoroid:20210928000139p:plain

4.下記aws cliを使用してデータ登録
一番最後の引数にツールで出力されたjsonファイルを指定します。

aws dynamodb batch-write-item --request-items file://Dataset-001.json

f:id:Simoroid:20210928000157p:plain

AWSコンソール上で結果を表示します。
f:id:Simoroid:20210928000206p:plain

エクセルファイルのシート名にしたテーブルにデータがちゃんとデータ登録されています!

ここまで 読んで頂きありがとうございました。
よければフォローお願いします!

AWS入門~CLIで使用してDynamoDBを操作する

f:id:Simoroid:20210916230834p:plain
CLIコマンドラインインターフェース)を使用してDynamoDBのテーブルを作成・削除・更新や項目(RDBでいうレコード)
の登録方法のTipsです。CLI自体の導入は下記から行います。
ikoda.shop

また、今回の手順はlocalstackを使用したローカル環境に向けてのものになります。
localstackの導入は下記から行います。
【AWS入門】Javaで始めてのLambdaアプリ開発 - App Engineerの開発ノート

■プロファイルを作成

事前の準備でプロファイルを作ります。
localstackで使用する場合においては"Default output format"以外は任意の値で大丈夫です。
※default以外で認証情報を使いたい場合、profileオプションを使用します

aws configure

AWS Access Key ID [None]: xxx
AWS Secret Access Key [None]: xxx
Default region name [None]: xxx
Default output format [None]: json
■テーブルを作成

※Patition Key、Sort Key以外の項目は作成時には指定できません、非キー属性の項目は項目登録のタイミングで行います。
aws dynamodb create-table --table テーブル名 --attribute-definitions AttributeName=属性名,AttributeType=属性の型 --key-schema AttributeName=Patition Key or
Sort Keyに指定する属性名,KeyType=HASH or Range --provisioned-throughput ReadCapacityUnits=任意の数値,WriteCapacityUnits=任意の数値 --endpoint-url=http://localhost:4566

下記は例です。※ポート番号に注意

aws dynamodb create-table --table-name test --attribute-definitions AttributeName=testId,AttributeType=S --key-schema AttributeName=testId,KeyType=HASH --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1 --endpoint-url=http://localhost:4566
■テーブルに項目を登録

aws dynamodb put-item --table-name テーブル名 --endpoint-url http://localhost:4566 --item 項目情報

下記は例です。

aws dynamodb put-item --table-name "test" --endpoint-url http://localhost:4566 --item '{\"testId\" : {\"S\" : \"test\"},\"name\" : {\"S\" : \"taro\"}}'
■テーブル情報を確認

aws dynamodb scan --table-name テーブル名 --endpoint-url http://localhost:4566

下記は例です。

aws dynamodb scan --table-name "test" --endpoint-url http://localhost:4566

※プロファイルをローカル用などで別途用意してる場合はオプションをつける

aws dynamodb scan --table-name "test" --endpoint-url http://localhost:4566 --profile=xxx
■テーブルにある項目を削除

aws dynamodb delete-item --table-name テーブル名 --endpoint-url http://localhost:4566 --key キー属性

下記は例です。

aws dynamodb delete-item --table-name "test" --endpoint-url http://localhost:4566 --key '{\"testId\" : {\"S\" : \"test\"}}'
■テーブルの一覧を確認

aws dynamodb list-tables --endpoint-url=http://localhost:4566

下記は例です。

aws dynamodb list-tables --endpoint-url=http://localhost:4566

ここまで 読んで頂きありがとうございました。
よければフォローお願いします!

【AWS便利ツール】DynamoDBのテーブルをCSVでエクスポートする

f:id:Simoroid:20210906012742p:plain
DynamoDBの内容をエクスポートしたい場合、テーブルの中身を簡易的にエクスポートする方法です。
ツールの開発にはPowerShell を使用します。
DynamoDBの管理コンソールからでもエクスポートは可能ですが、
わざわざログインしたくないときなどに便利です。

■前提条件

AWS CLI が使用できる必要があります。
下記手順からインストールが可能です。
AWS入門~CLIを使用してAWSにアクセス - App Engineerの開発ノート

PowerShellスクリプトファイルを実行できる権限が振られている必要があります。

■ツール準備

下記のソースをコピーして任意のps1ファイルを作成します。
※例:「output-csv.ps1」

# 接続先は適宜切り替え
$ENDPOINT_URL = "http://localhost:4566"
$OUTPUT_FORMAT = "json"

$tableName = Read-Host “テーブル名を入力してください。”
$jsonObj = aws dynamodb scan --table-name "$tableName" --endpoint-url $ENDPOINT_URL --output $OUTPUT_FORMAT
$obj = ($jsonObj | ConvertFrom-Json)
$obj.items | convertto-csv -NoTypeInformation -Delimiter "," | % {$_ -replace '"',''} | out-file "dump_$tableName.csv" -Encoding default

上記ファイルを任意ディレクトリに配置します。

■ツール実行

ツールのテスト用にデータを準備します。
今回は雑に"test"というテーブルに1レコードだけputしてます。
f:id:Simoroid:20210916004706p:plain

準備ができたら、配置したps1ファイルを右クリック -> "Powershellで実行"をクリック
で簡単に実行できます。
実行後はテーブルを名を入力します。
f:id:Simoroid:20210916003952p:plain
f:id:Simoroid:20210916004121p:plain
下記のようにエクスポートできました!
f:id:Simoroid:20210916004231p:plain

ここまで 読んで頂きありがとうございました。
よければフォローお願いします!