LoginSignup
5
5

More than 5 years have passed since last update.

dockerでDynamoDB LocalとAWS SDK for C++の開発環境を動かす

Last updated at Posted at 2016-02-20

前々回はAWS SDK for C++を使ってS3をいじってみました。今回はDynamoDBで試してみます。せっかくなのでDynamoDB Localをdockerで動かし、それを操作します。

準備

まずはdockerでDynamoDB Localを動かします。

dockerでDynamoDB Localを動かす

丁度よさげなイメージがこちらにありましたので、これを使って動かします。その際に-sharedDbを指定し、リージョン区分のエミュレート機能を無効にします。個人的にはこの機能はハマりポイントだと思うので(というかハマりました)無効にして単一のDBが作られるようにします。

$ sudo docker run -d \
                  -p 8000:8000 \
                  -v /var/dynamodblocal:/var/dynamodblocal \
                  --name localdynamodb \
                  -t tray/dynamodb-local -sharedDb -dbPath /var/dynamodblocal

DynamoDB Localにテーブルを作成

動かしたら次はaws cliでテーブルを作ります。
開発者ガイドをパクって、Music という名前のテーブルを作成します。パーティションキーは Artist で、ソートキーは SongTitle です。
DynamoDB Localに作るので--endpoint-url http://localhost:8000を指定しています。

$ aws dynamodb create-table --endpoint-url http://localhost:8000 \
                            --table-name Music \
                            --attribute-definitions AttributeName=Artist,AttributeType=S \
                                                    AttributeName=SongTitle,AttributeType=S \
                            --key-schema AttributeName=Artist,KeyType=HASH AttributeName=SongTitle,KeyType=RANGE \
                            --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1 

DynamoDB JavaScript Shellを使って見てみる

http://localhost:8000/shell/ を開いてDynamoDB JavaScript ShellでDBにテーブルが作られたことを確認します。
こちらがテーブルの一覧を表示させるAPIです。

dynamodb.listTables(params, function(err, data) {
    if (err) console.log(err, err.stack); // an error occurred
    else     console.log(data);           // successful response
});

実行するとこのように表示されて、Musicテーブルが作られたことが確認できます。

{"TableNames":["Music"]}

また、こちらのAPIを実行するとMusicテーブルの中身を覗けます。

var params = {
    TableName: 'Music',
};
dynamodb.scan(params, function(err, data) {
    if (err) print(err); // an error occurred
    else print(data); // successful response
});

まだ何もありません。

{
  "Items": [],
  "Count": 0,
  "ScannedCount": 0
}

AWS SDK for C++を使ってDynamoDB Localにputする

さて、AWS SDK for C++を使ってputしようと思いますが、そのための実行環境として拙作のこちらのイメージを使おうと思います。
※余談
このイメージをDocker Hubでビルドしますと現状、必ず失敗します。ライブラリをmakeするときにメモリを使い過ぎるのが原因かな、と思ってます。1ヶ月くらい前の時点では失敗したり成功したりでしたが、今は何回ビルドしても成功しません。なんとかして解決したいものです。

コンテナを起動してプログラムを実行

まずはコンテナを起動します。

$ sudo docker run -i --link localdynamodb:localdynamodb -t d9magai/awssdkcpp bash

コンテナを起動したらprog.cppを書きます。Musicテーブルに歌手名と曲名と再生回数をputするプログラムです。

prog.cpp
#include <aws/core/Aws.h>
#include <aws/dynamodb/DynamoDBClient.h>
#include <aws/dynamodb/model/PutItemRequest.h>
#include <aws/dynamodb/model/AttributeValueValue.h>
#include <aws/core/auth/AWSCredentialsProvider.h>
#include <aws/core/utils/Outcome.h>

const Aws::String AWS_ACCESS_KEY_ID = "XXXXXXXXXXXXXXXXXXXX";
const Aws::String AWS_SECRET_ACCESS_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

int main(int argc, char** argv) {

    try {
        Aws::SDKOptions  options;
        Aws::InitAPI(options);

        Aws::Client::ClientConfiguration config;
        config.scheme = Aws::Http::Scheme::HTTP;
        config.connectTimeoutMs = 1000;
        config.requestTimeoutMs = 1000;
        config.endpointOverride = "localdynamodb:8000";
        config.region = Aws::Region::AP_NORTHEAST_1;
        auto dynamoDbClient = Aws::DynamoDB::DynamoDBClient(Aws::Auth::AWSCredentials(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY), config);

        Aws::DynamoDB::Model::PutItemRequest putItemRequest = Aws::DynamoDB::Model::PutItemRequest()
        .WithTableName("Music")
        .AddItem("Artist", Aws::DynamoDB::Model::AttributeValue().SetS("aiko"))
        .AddItem("SongTitle", Aws::DynamoDB::Model::AttributeValue().SetS("アンドロメダ"))
        .AddItem("Views", Aws::DynamoDB::Model::AttributeValue().SetN("3002"));

        auto putItemOutcome = dynamoDbClient.PutItem(putItemRequest);
        if(!putItemOutcome.IsSuccess()) {
            std::stringstream ss;
            ss << "PutItem failed with error: " << putItemOutcome.GetError().GetMessage() << std::endl;
            throw std::runtime_error(ss.str());
        }
        std::cout << "PutItem Success" << std::endl;
        Aws::ShutdownAPI(options);
    } catch (const std::exception &e) {
        std::cerr << e.what();
        return 1;
    }

    return 0;
}

接続先がDynamoDB Localなので、アクセスキーもシークレットキーもダミーで構いません。
コンパイルして実行してPutItem Successと表示されれば成功です。

$ g++ -DAWS_CUSTOM_MEMORY_MANAGEMENT -std=c++11 prog.cpp -I/opt/aws-sdk-cpp/include -L/opt/aws-sdk-cpp/lib/linux/intel64/ -laws-cpp-sdk-core -laws-cpp-sdk-dynamodb
$ ./a.out
PutItem Success

DynamoDB JavaScript ShellでMusicテーブルの中を見てみる

Musicテーブルの中身を確認し、ちゃんとデータがputされてるか見てみます。
http://localhost:8000/shell/ をもう一度開き、こちらのAPIでMusicテーブルをscanします。

var params = {
    TableName: 'Music',
};
dynamodb.scan(params, function(err, data) {
    if (err) print(err); // an error occurred
    else print(data); // successful response
});

ちゃんと登録されていたら、こんな感じで表示されます。

{
  "Items": [
    {
      "Artist": "aiko",
      "SongTitle": "アンドロメダ",
      "Views": 3002
    }
  ],
  "Count": 1,
  "ScannedCount": 1
}

DynamoDB LocalとAWS SDK for C++をdockerで動かせた

無事に動かせました。
ちなみにアクセスキー、シークレットキーとAws::Client::ClientConfiguration config;の値を正しく設定すればLocalではないほうのDynamoDBにも接続できます。今のところ私がAWS SDK for C++で使ったことがあるのはS3,DynamoDBくらいなので、もっと勉強していろいろ使ってみようと思います。

参考
https://aws.amazon.com/jp/blogs/aws/introducing-the-aws-sdk-for-c/

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5