📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

ページの作成:「== 概要 == <br><br> == サンプルコード == <br><br> __FORCETOC__ カテゴリ:Qt
 
4行目: 4行目:


== サンプルコード ==
== サンプルコード ==
以下の例では、AWS Lambdaの関数呼び出しとレスポンスの取得を行っている。<br>
全ての設定 (リージョン、関数名、ペイロード) を任意の設定ファイルから読み込んでいる。<br>
<br>
* 呼び出しタイプ
** RequestResponse
**: 同期呼び出し
**: 関数の実行結果を待ってレスポンスを返す。
** Event
**: 非同期呼び出し
**: 関数をキューに入れてすぐに制御を返す。
** DryRun
**: テスト呼び出し
**: 関数を実行せずにアクセス許可を検証する。
*: <br>
* ログタイプ
** Tail
**: 最後の4KBの実行ログをBase64エンコードして返す。
** None
**: ログを返さない。
*: <br>
* ペイロード形式
*: ペイロードは有効なJSON形式である必要がある。
*: <syntaxhighlight lang="json">
# 例 :
{
  "body": {
    "message": "Hello Lambda!"
  },
  "queryStringParameters": {
    "param1": "value1"
  }
}
</syntaxhighlight>
<br>
<syntaxhighlight lang="ini">
# config.iniファイル


[AWS]
# AWSリージョン (必須)
region=us-east-1
[Lambda]
# Lambda関数名 (必須)
function_name=my-lambda-function
# 呼び出しタイプ (RequestResponse, Event, DryRun)
invocation_type=RequestResponse
# ペイロード (JSON形式)
payload={"key1": "value1", "key2": "value2"}
# ログタイプ (None または Tail)
log_type=Tail
</syntaxhighlight>
<br>
<syntaxhighlight lang="cmake">
# CMakeLists.txtファイル
cmake_minimum_required(VERSION 3.16)
project(<プロジェクト名> VERSION 1.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Qt設定
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
# Qtの検索
find_package(Qt6 COMPONENTS Core QUIET)
if (NOT Qt6_FOUND)
    find_package(Qt5 5.15 REQUIRED COMPONENTS Core)
endif()
# AWS SDK for C++の検索
find_package(AWSSDK REQUIRED COMPONENTS lambda)
# 実行ファイル
add_executable(<プロジェクト名>
    main.cpp
)
# Qt6とQt5の両方に対応
if (Qt6_FOUND)
    target_link_libraries(<プロジェクト名>
      Qt6::Core
      ${AWSSDK_LINK_LIBRARIES}
    )
else()
    target_link_libraries(<プロジェクト名>
      Qt5::Core
      ${AWSSDK_LINK_LIBRARIES}
    )
endif()
# インストール
install(TARGETS <プロジェクト名>
    RUNTIME DESTINATION bin
)
</syntaxhighlight>
<br>
<syntaxhighlight lang="c++">
#include <QCoreApplication>
#include <QCommandLineParser>
#include <QSettings>
#include <QFileInfo>
#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <iostream>
#include <aws/core/Aws.h>
#include <aws/lambda/LambdaClient.h>
#include <aws/lambda/model/InvokeRequest.h>
#include <aws/lambda/model/ListFunctionsRequest.h>
// 設定情報を保持する構造体
struct LambdaConfig {
    QString region;
    QString functionName;
    QString invocationType;
    QString payload;
    QString logType;
};
// 設定ファイルを読み込む関数
bool loadConfig(const QString& configPath, LambdaConfig& config)
{
    QFileInfo fileInfo(configPath);
    if (!fileInfo.exists()) {
      std::cerr << "エラー: 設定ファイルが見つかりません: " << configPath.toStdString() << std::endl;
      return false;
    }
    QSettings settings(configPath, QSettings::IniFormat);
    settings.setIniCodec("UTF-8");
    // AWS設定
    settings.beginGroup("AWS");
    config.region = settings.value("region").toString();
    settings.endGroup();
    // Lambda設定
    settings.beginGroup("Lambda");
    config.functionName = settings.value("function_name").toString();
    config.invocationType = settings.value("invocation_type", "RequestResponse").toString();
    config.payload = settings.value("payload", "{}").toString();
    config.logType = settings.value("log_type", "None").toString();
    settings.endGroup();
    // 必須項目のチェック
    if (config.region.isEmpty()) {
      std::cerr << "エラー: [AWS] region が設定されていません" << std::endl;
      return false;
    }
    if (config.functionName.isEmpty()) {
      std::cerr << "エラー: [Lambda] function_name が設定されていません" << std::endl;
      return false;
    }
    std::cout << "設定ファイル読み込み完了: " << configPath.toStdString() << std::endl;
    std::cout << "  リージョン: " << config.region.toStdString() << std::endl;
    std::cout << "  関数名: " << config.functionName.toStdString() << std::endl;
    std::cout << "  呼び出しタイプ: " << config.invocationType.toStdString() << std::endl;
    return true;
}
class LambdaManager {
private:
    std::unique_ptr<Aws::Lambda::LambdaClient> m_lambdaClient;
public:
    LambdaManager(const QString& region)
    {
      Aws::Client::ClientConfiguration clientConfig;
      clientConfig.region = region.toStdString();
      m_lambdaClient = std::make_unique<Aws::Lambda::LambdaClient>(clientConfig);
      std::cout << "Lambdaクライアント初期化完了 (リージョン: " << region.toStdString() << ")" << std::endl;
    }
    bool invokeFunction(const QString& functionName, const QString& payload,
                      const QString& invocationType, const QString& logType)
    {
      std::cout << "\n=== Lambda関数呼び出し開始 ===" << std::endl;
      std::cout << "  関数名: " << functionName.toStdString() << std::endl;
      std::cout << "  ペイロード: " << payload.toStdString() << std::endl;
      // ペイロードのJSON検証
      QJsonParseError parseError;
      QJsonDocument jsonDoc = QJsonDocument::fromJson(payload.toUtf8(), &parseError);
      if (parseError.error != QJsonParseError::NoError) {
          std::cerr << "エラー: ペイロードが有効なJSONではありません: "
                    << parseError.errorString().toStdString() << std::endl;
          return false;
      }
      Aws::Lambda::Model::InvokeRequest request;
      request.SetFunctionName(functionName.toStdString());
      // 呼び出しタイプの設定
      if (invocationType == "RequestResponse") {
          request.SetInvocationType(Aws::Lambda::Model::InvocationType::RequestResponse);
      }
      else if (invocationType == "Event") {
          request.SetInvocationType(Aws::Lambda::Model::InvocationType::Event);
      }
      else if (invocationType == "DryRun") {
          request.SetInvocationType(Aws::Lambda::Model::InvocationType::DryRun);
      }
      // ログタイプの設定
      if (logType == "Tail") {
          request.SetLogType(Aws::Lambda::Model::LogType::Tail);
      }
      else {
          request.SetLogType(Aws::Lambda::Model::LogType::None);
      }
      // ペイロードの設定
      std::shared_ptr<Aws::IOStream> payload_stream =
          Aws::MakeShared<Aws::StringStream>("PayloadStream");
      *payload_stream << payload.toStdString();
      request.SetBody(payload_stream);
      auto outcome = m_lambdaClient->Invoke(request);
      if (outcome.IsSuccess()) {
          const auto& result = outcome.GetResult();
          std::cout << "✓ 呼び出し成功!" << std::endl;
          std::cout << "\n--- レスポンス ---" << std::endl;
          std::cout << "  ステータスコード: " << result.GetStatusCode() << std::endl;
          // 関数エラーの確認
          if (!result.GetFunctionError().empty()) {
            std::cout << "  関数エラー: " << result.GetFunctionError() << std::endl;
          }
          // レスポンスペイロードの取得
          auto& payload_stream = result.GetPayload();
          std::stringstream ss;
          ss << payload_stream.rdbuf();
          std::string response_payload = ss.str();
          if (!response_payload.empty()) {
            std::cout << "  ペイロード: " << response_payload << std::endl;
            // JSONの整形表示
            QJsonDocument responseDoc = QJsonDocument::fromJson(QString::fromStdString(response_payload).toUtf8());
            if (!responseDoc.isNull()) {
                std::cout << "  整形済みペイロード:\n"
                        << responseDoc.toJson(QJsonDocument::Indented).toStdString() << std::endl;
            }
          }
          // ログの表示 (LogType=Tailの場合)
          if (!result.GetLogResult().empty()) {
            std::cout << "\n--- 実行ログ (Base64デコード済み) ---" << std::endl;
            // Base64デコード
            QByteArray logData = QByteArray::fromBase64(QByteArray::fromStdString(result.GetLogResult()));
            std::cout << logData.toStdString() << std::endl;
          }
          return true;
      }
      else {
          std::cerr << "✗ 呼び出し失敗: " << outcome.GetError().GetMessage() << std::endl;
          return false;
      }
    }
    bool listFunctions()
    {
      std::cout << "\n=== Lambda関数一覧取得 ===" << std::endl;
      Aws::Lambda::Model::ListFunctionsRequest request;
      auto outcome = m_lambdaClient->ListFunctions(request);
      if (outcome.IsSuccess()) {
          const auto& result = outcome.GetResult();
          const auto& functions = result.GetFunctions();
          std::cout << "✓ 取得成功! (" << functions.size() << "個の関数)" << std::endl;
          if (functions.empty()) {
            std::cout << "  登録されている関数がありません" << std::endl;
          }
          else {
            std::cout << "\n--- 関数一覧 ---" << std::endl;
            for (const auto& func : functions) {
                std::cout << "  • " << func.GetFunctionName() << std::endl;
                std::cout << "    ランタイム: " << Aws::Lambda::Model::RuntimeMapper::GetNameForRuntime(func.GetRuntime()) << std::endl;
                std::cout << "    ハンドラ: " << func.GetHandler() << std::endl;
                std::cout << "    メモリ: " << func.GetMemorySize() << " MB" << std::endl;
                std::cout << "    タイムアウト: " << func.GetTimeout() << " 秒" << std::endl;
                std::cout << "    最終更新: " << func.GetLastModified() << std::endl;
                std::cout << std::endl;
            }
          }
          return true;
      }
      else {
          std::cerr << "✗ 取得失敗: " << outcome.GetError().GetMessage() << std::endl;
          return false;
      }
    }
};
int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    QCoreApplication::setApplicationName("AWS Lambda Manager");
    QCoreApplication::setApplicationVersion("1.0");
    // コマンドライン引数のパーサーを設定
    QCommandLineParser parser;
    parser.setApplicationDescription("AWS Lambda関数呼び出しツール (設定ファイルベース)");
    parser.addHelpOption();
    parser.addVersionOption();
    // オプション定義
    QCommandLineOption invokeOption(QStringList() << "i" << "invoke", "Lambda関数を呼び出し");
    parser.addOption(invokeOption);
    QCommandLineOption listOption(QStringList() << "l" << "list", "Lambda関数の一覧を取得");
    parser.addOption(listOption);
    QCommandLineOption configOption(QStringList() << "c" << "config", "設定ファイルのパス (デフォルト: config.ini)", "config", "config.ini");
    parser.addOption(configOption);
    parser.process(app);
    // AWS SDKの初期化
    Aws::SDKOptions options;
    Aws::InitAPI(options);
    int result = 0;
    {
      // 設定ファイルのパスを取得
      QString configPath = parser.value(configOption);
      // 設定を読み込む
      LambdaConfig config;
      if (!loadConfig(configPath, config)) {
          std::cerr << "\n設定ファイルの例:" << std::endl;
          std::cerr << "  [AWS]" << std::endl;
          std::cerr << "  region=ap-northeast-1" << std::endl;
          std::cerr << "  " << std::endl;
          std::cerr << "  [Lambda]" << std::endl;
          std::cerr << "  function_name=my-function" << std::endl;
          std::cerr << "  invocation_type=RequestResponse" << std::endl;
          std::cerr << "  payload={\"key\": \"value\"}" << std::endl;
          std::cerr << "  log_type=Tail" << std::endl;
          Aws::ShutdownAPI(options);
          return 1;
      }
      // Lambdaマネージャーを初期化
      LambdaManager lambdaManager(config.region);
      if (parser.isSet(invokeOption)) {
          // Lambda関数呼び出し
          if (!lambdaManager.invokeFunction(config.functionName, config.payload,
                                          config.invocationType, config.logType)) {
            result = 1;
          }
      }
      else if (parser.isSet(listOption)) {
          // Lambda関数一覧取得
          if (!lambdaManager.listFunctions()) {
            result = 1;
          }
      }
      else {
          std::cerr << "エラー: --invoke または --list を指定してください" << std::endl;
          parser.showHelp(1);
      }
    }
    // AWS SDKのクリーンアップ
    Aws::ShutdownAPI(options);
    return result;
}
</syntaxhighlight>
<br>
<syntaxhighlight lang="sh">
# 実行例
# Lambda関数を呼び出し
./lambda-manager --invoke --config config.ini
# Lambda関数の一覧を取得
./lambda-manager --list --config config.ini
# 別の設定ファイルを使用
./lambda-manager --invoke --config /path/to/custom-config.ini
</syntaxhighlight>
<br><br>
<br><br>