1
0

More than 1 year has passed since last update.

JavaプロジェクトからSQSにキューを送信してlambdaをキックする

Posted at

前提

業務でこんな処理を実装する気がするので、簡単に予習してみます。
今回は動くか検証のみなので、ローカルで起動したJavaアプリケーション(Spring Boot)からSQSにメッセージを送信してみます。

本当はlambdaからrdsへ登録・更新する処理を実装したかったのですが、それはまた別の機会に。(なのでSQSやlambdaの名前がmergeXXXXみたいになってます。)

lambda-sqs.drawio.png

環境

  • macOS: 12.6
  • IntelliJ IDEA: 2022.2.3 (Community Edition)
  • Gradle: 7.5
  • Java: temurin 17.0.3

手順

プロジェクトの作成

spring initializrでプロジェクト作成

https://start.spring.io/でプロジェクトの雛形を作成します。
以下の画像のような構成にしています。

GENERATEボタンを押してダウンロードしてきます。それをIDEツールで開きます。

build.gradleの設定

com.amazonaws:aws-java-sdk-bomcom.amazonaws:aws-java-sdk-sqsを設定します。
この時点ではどちらも1.12.320が最新でした。

build.gradle
plugins {
	id 'org.springframework.boot' version '2.7.5-SNAPSHOT'
	id 'io.spring.dependency-management' version '1.0.14.RELEASE'
	id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
	maven { url 'https://repo.spring.io/milestone' }
	maven { url 'https://repo.spring.io/snapshot' }
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'com.amazonaws:aws-java-sdk-bom:1.12.320'
	implementation 'com.amazonaws:aws-java-sdk-sqs:1.12.320'
	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
	useJUnitPlatform()
}

AWS側の設定

IAMユーザーの作成

事前にJavaからアクセスするためのIAMユーザーを作成し、アクセスキーとシークレットキーをダウンロードしておきます。
そのIAMユーザーを使用してコンロールでSQS等を作成します。

SQSのキューを作成

コンソールでSQSのキューを作成します

lambdaを作成

IAMロールを作成する

lambdaからSQSを読み取りするのでIAMロールを作成します。
こちらを参考にさせていただきました。
https://www.stsd.co.jp/dev-blog/send_and_receive_amazon_sqs_messages_from_java.html#:~:text=SQS%E3%81%AB%E3%81%AFJava%E3%81%A7,%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%80%8D%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%97%E3%81%BE%E3%81%99%E3%80%82

  • ロール名:for-sqs
  • ポリシー名:sqs-policy
  • ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "sqs:DeleteMessage",
                "sqs:ReceiveMessage",
                "sqs:GetQueueAttributes"
            ],
            "Resource": "*"
        }
    ]
}

またロールにAWSLambdaBasicExecutionRoleをアタッチしておくと、CloudWatchログにログを書き込めます。

lambdaにIAMロールの設定

コンロールのlambdaのページを開き、設定タブ > アクセス権限 > 実行ロール > 編集ボタンで設定します。

SQSでLambdaトリガーを設定

SQSのページで作成したキューを選択し、Lambdaトリガータブからlambdaを設定します。

これでaws側の設定は完了です。

実装

SqsClient

こちらを参考にしました。
https://docs.aws.amazon.com/ja_jp/sdk-for-java/v1/developer-guide/examples-sqs-messages.html

SqsClient.java
package com.example.lambdasqssample.aws;

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.AmazonSQSException;
import com.amazonaws.services.sqs.model.CreateQueueRequest;
import com.amazonaws.services.sqs.model.SendMessageRequest;
import org.springframework.stereotype.Component;

@Component
public class SqsClient {

    private static final String QUEUE_NAME = "merge-data-sqs";

    public String getQueueUrl() {
        var sqs = getSqs();
        var create_request = new CreateQueueRequest(QUEUE_NAME)
                .addAttributesEntry("DelaySeconds", "60")
                .addAttributesEntry("MessageRetentionPeriod", "86400");

        try {
            sqs.createQueue(create_request);
        } catch (AmazonSQSException e) {
            if (!e.getErrorCode().equals("QueueAlreadyExists")) {
                throw e;
            }
        }
        return sqs.getQueueUrl(QUEUE_NAME).getQueueUrl();
    }

    public void sendMessage(String queueUrl) {
        var sqs = getSqs();
        var send_msg_request = new SendMessageRequest()
                .withQueueUrl(queueUrl)
                .withMessageBody("hello world")
                .withDelaySeconds(5);
        sqs.sendMessage(send_msg_request);
    }

    private AmazonSQS getSqs() {
        return AmazonSQSClientBuilder
                .standard()
                .withCredentials(new AWSStaticCredentialsProvider(Credentials.get()))
                .withRegion(Regions.AP_NORTHEAST_1.getName())
                .build();
    }
}
Credentials.java
package com.example.lambdasqssample.aws;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class Credentials {

    private static String ACCESS_KEY;

    private static String SECRET_KEY;

    @Value("${aws.access-key}")
    public void setAccessKey(String accessKey) {
        this.ACCESS_KEY = accessKey;
    }

    @Value("${aws.secret-key}")
    public void setSecretKey(String secretKey) {
        this.SECRET_KEY = secretKey;
    }

    public static AWSCredentials get() {
        return new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY);
    }
}

ACCESS_KEYとSECRET_KEYはapplication.ymlで設定しておきます。

実行クラス

QueueのUrlを受け取り、メッセージを送信します。

SampleController.java
package com.example.lambdasqssample.Controller;

import com.example.lambdasqssample.aws.SqsClient;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/v1/sample")
@RequiredArgsConstructor
public class SampleController {

    private final SqsClient sqsClient;

    @GetMapping("/result")
    public boolean getResult() {
        var queue = sqsClient.getQueueUrl();
        sqsClient.sendMessage(queue);
        return true;
    }

}

これで実装は完了です。

実行

アプリケーションをビルド・実行します。
今回はpostmanを使用してhttp://localhost:8080/api/v1/sample/resultにGETします。

CloudWatchログを見ると、アクセスするたびに実行されていることがわかります。

さいごに

まだlambdaで具体的な処理を実行していないですが、とりあえず動くことを確認できた第一歩でした。

1
0
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
1
0