DynamoDBをlocal環境で動かしてみる

#<i class="fa fa-database" aria-hidden="true"></i> Dynamodbをlocal環境で動かすメモ

AWS上で使っているDynamodbに対して色々開発段階でデバッグなどしたい！
でも、アクセスしまくって課金されるのは困る。
みたいな時、Dynamodbには「DynamoDB Local」という、ローカルマシン内で稼働する`downloadable version of DynamoDB`が公開されています。

[公式のドキュメント](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html)に詳しく書かれています。
[日本語版](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBLocal.html)もあります。

#<i class="fa fa-list" aria-hidden="true"></i> 環境
OSX 10.11.4
Java 1.8.0_101
IntelliJ IDEA 2016.1.4
Homebrew 1.0.8 もしくは pipとか(今回はHomebrewを使っています)

#<i class="fa fa-wrench" aria-hidden="true"></i> DynamodbLocalのセットアップ

##[Step1]DynamodbLocalをダウンロード
ドキュメントにもある通りいずれかからダウンロード。

|形式|URL|
|:-----------|:------------|
|tar.gz 形式|http://dynamodb-local.s3-website-us-west-2.amazonaws.com/dynamodb_local_latest.tar.gz|
|zip 形式|http://dynamodb-local.s3-website-us-west-2.amazonaws.com/dynamodb_local_latest.zip|

##[Step2]任意のディレクトリ下で展開し、そのディレクトリ下に移動
こんな感じです
![スクリーンショット 2016-10-27 8.33.10.png](https://qiita-image-store.s3.amazonaws.com/0/56510/03f8203a-3d72-b9a1-c6a2-03d34344eda3.png)


##[Step3]DynamodbLocalを起動

ここも、ドキュメントにあるようにまずはDynamodbLocalを起動してみます。

```bash
$ java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb
Initializing DynamoDB Local with the following configuration:
Port:	8000
InMemory:	false
DbPath:	null
SharedDb:	true
shouldDelayTransientStatuses:	false
CorsParams:	*
```

これで起動は完了です。終了する場合は`Ctrl+C `です。

#<i class="fa fa-cube" aria-hidden="true"></i> AWS コマンドラインインターフェイス (CLI)のインストール
##[Step1]インストールします
[公式ドキュメント](http://docs.aws.amazon.com/streams/latest/dev/kinesis-tutorial-cli-installation.html)ではpipでaws-cliをインストールしていますが、[homebrew](http://qiita.com/omega999/items/6f65217b81ad3fffe7e6)で今回はインストールします。
これによって、コマンドラインで、Dynamodbのテーブルを作成したり、確認したりいろいろできるようになります。

```bash
$ sudo brew install awscli
Password:
~~~~省略~~~~
==> Renamed Formulae
stash-cli -> atlassian-cli
==> Deleted Formulae
dwarf                       jsdoc-toolkit               puddletag                   sonar-runner
homebrew/science/minc       libmarisa                   qbzr                        treeline

==> Downloading https://homebrew.bintray.com/bottles/awscli-1.11.10.el_capitan.bottle.tar.gz
######################################################################## 100.0%
==> Pouring awscli-1.11.10.el_capitan.bottle.tar.gz
==> Caveats
The "examples" directory has been installed to:
  /usr/local/share/awscli/examples

Before using aws-cli, you need to tell it about your AWS credentials.
The quickest way to do this is to run:
  aws configure

More information:
  https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html
  https://pypi.python.org/pypi/awscli#getting-started

Bash completion has been installed to:
  /usr/local/etc/bash_completion.d

zsh completion has been installed to:
  /usr/local/share/zsh/site-functions
==> Summary
🍺  /usr/local/Cellar/awscli/1.11.10: 3,459 files, 28.4M

```

##[Step2]`aws configure`の設定
http://www.task-notes.com/entry/20141026/1414322858
などを参考に。

```bash
$aws configure
AWS Access Key ID [None]: accesskey
AWS Secret Access Key [None]: secretkey
Default region name [None]: localhost:8000
Default output format [None]: 
```

##[Step3]DynamoDB JavaScript consoleを立ち上げる
DynamodbLocalを起動している状態で、
http://localhost:8000/shell/
を開くと、以下のようなDynamoDB JavaScript consoleが開きます。
<img border="1" src="https://qiita-image-store.s3.amazonaws.com/0/56510/13a084ea-49f5-06ba-4f7f-5725ccea6e57.png" width="70%">
詳細な使い方についてはこちらがかなりわかりやすかったです。
http://dev.classmethod.jp/cloud/aws/dynamodb-local-shell-console/

##[Step4]DynamodbLocalのtableを`aws-cli`で出力

```bash
$ aws dynamodb list-tables --endpoint-url http://localhost:8000
{
    "TableNames": []
}
```

ここではまだ何もtableが登録されていないのでtableは空です

#<i class="fa fa-file-code-o" aria-hidden="true"></i> IntelliJ IDEAでDynamodbを触るプロジェクトを作ってみる(Java)

##[Step1]IntelliJをダウンロード・インストールします
Comunity(無償)でも問題ないと思いますが(使ったことないですが)学生はUltimateも無料なのでそちらを使いましょう！
https://www.jetbrains.com/idea/
違いについては[こちら](https://www.jetbrains.com/idea/features/editions_comparison_matrix.html)にまとまっています

##[Step2]IntelliJを起動
<img border="1" src="https://qiita-image-store.s3.amazonaws.com/0/56510/6fb8d24f-9a01-44a5-fdd4-8f2a8d918bdd.png" width="70%">

##[Step2]プロジェクトを作成(Create New Project)
`Maven`を選択しProjectSDKはJava1.8にしました。
<img border="1" src="https://qiita-image-store.s3.amazonaws.com/0/56510/31fec056-5d51-96a2-80b2-c07e537d426c.png" width="70%">
<img border="1" src="https://qiita-image-store.s3.amazonaws.com/0/56510/180e96c6-3674-42f1-92f2-919903295b45.png" width="70%">
<img border="1" src="https://qiita-image-store.s3.amazonaws.com/0/56510/6bc1debe-6e05-a82e-2061-7691a26e3d44.png" width="70%">

##[Step3]テーブル作成のプロジェクトを作る
以下のStepではこのGettingStartedを参考にしています。というかコードはそのままです。
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/gettingstartedguide/GettingStarted.Java.html

Javaファイルを作成します
<img border="1" src="https://qiita-image-store.s3.amazonaws.com/0/56510/5b0b3654-deb3-10fb-42aa-ea3c3110151c.png" width="70%">

作成先で以下のコードをコピペしてみましょう。

```MoviesCreateTable.java
import java.util.Arrays;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType;

public class MoviesCreateTable {

    public static void main(String[] args) throws Exception {

        AmazonDynamoDBClient client = new AmazonDynamoDBClient()
                .withEndpoint("http://localhost:8000");

        DynamoDB dynamoDB = new DynamoDB(client);

        String tableName = "Movies";

        try {
            System.out.println("Attempting to create table; please wait...");
            Table table = dynamoDB.createTable(tableName,
                    Arrays.asList(
                            new KeySchemaElement("year", KeyType.HASH),  //Partition key
                            new KeySchemaElement("title", KeyType.RANGE)), //Sort key
                    Arrays.asList(
                            new AttributeDefinition("year", ScalarAttributeType.N),
                            new AttributeDefinition("title", ScalarAttributeType.S)),
                    new ProvisionedThroughput(10L, 10L));
            table.waitForActive();
            System.out.println("Success.  Table status: " + table.getDescription().getTableStatus());

        } catch (Exception e) {
            System.err.println("Unable to create table: ");
            System.err.println(e.getMessage());
        }

    }
}
```

真っ赤になりました。
<img border="1" src="https://qiita-image-store.s3.amazonaws.com/0/56510/2d4674ad-3a65-4d70-f772-615ba1f0b64d.png" width="70%">

Add Maven Dependency... を行います
<img border="1" src="https://qiita-image-store.s3.amazonaws.com/0/56510/476d9125-6000-552c-f8da-cface560309c.png" width="70%">

全て選択しAddします
<img border="1" src="https://qiita-image-store.s3.amazonaws.com/0/56510/0bc86e96-99f2-46b0-4191-c3cc6160e734.png" width="70%">

右上にImport Changesとでてくるのでクリックすると
<img border="1" src="https://qiita-image-store.s3.amazonaws.com/0/56510/6ff4d538-180a-3f62-130a-fd7b373a7e63.png" width="70%">

赤いのが消えます！
<img border="1" src="https://qiita-image-store.s3.amazonaws.com/0/56510/b80065a8-4294-cd95-8348-23369011483c.png" width="70%">

これは`pom.xml`を確認してもらえれば分かりますが

```pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>hiroki11x</groupId>
    <artifactId>DynamodbSample</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-dynamodb</artifactId>
            <version>1.11.41</version>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-dynamodb</artifactId>
            <version>1.11.41</version>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-dynamodb</artifactId>
            <version>1.11.41</version>
        </dependency>
    </dependencies>
</project>
```

みたいにプロジェクトが依存するライブラリが指定されています。

現段階では`aws-cli`でテーブルのリストを出力すると

```bash
$ aws dynamodb list-tables --endpoint-url http://localhost:8000
{
    "TableNames": []
}
```

ですが、先ほどの`MoviesCreateTable.java`を実行すると

<img border="1" src="https://qiita-image-store.s3.amazonaws.com/0/56510/14e8bb05-523a-8308-07a6-4d0b34132aed.png" width="70%">

```bash
$ aws dynamodb list-tables --endpoint-url http://localhost:8000
{
    "TableNames": [
        "Movies"
    ]
}
```

Moviesが追加されました！
あとは[GettingStarted](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/gettingstartedguide/GettingStarted.Java.02.html)に色々あるので引き続きこの記事に追加していこうと思います。

#<i class="fa fa-book" style="font-size:1em;"></i>参考
- http://dev.classmethod.jp/cloud/aws/dynamodb-local-shell-console/
- http://www.cyberciti.biz/faq/osx-installing-the-aws-command-line-interface-using-brew/
- http://docs.aws.amazon.com/streams/latest/dev/kinesis-tutorial-cli-installation.html
- https://www.jetbrains.com/idea/features/editions_comparison_matrix.html
- http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html
- http://blog.dalt.me/301
- http://dev.classmethod.jp/cloud/aws/amazon-dynamodb-run-on-osx/


#<i class="fa fa-sticky-note" aria-hidden="true"></i> 追記(メモ)

別のローカル環境でgithub経由で環境(http://dynamodb-local.s3-website-us-west-2.amazonaws.com/dynamodb_local_latest.zip を展開したもの)をcloneして使おうとしたら、

```bash
$ aws dynamodb list-tables --endpoint-url http://localhost:8000
```

だとか

```MoviesCreateTable.java
//~(略)~
Table table = dynamoDB.createTable(tableName, //~(略)~
//~(略)~
```

みたいなことしても、反応がない、、
みたいなことがありました。その場合、環境のファイル郡やディレクトリ構成、gitignoreされたファイルがあるなどが原因だったのでメモ