com4dc’s blog

Javaプログラマーのはずだけど運用してます

麻婆豆腐

「広告会社、男子寮のおかずくん」に掲載されてたレシピを少しアレンジして作ったのだが、おいしかったのでメモっとく

材料

大体二人分とのこと。

  • 豚ひき肉:150gくらい。適当
  • 豆腐:量適当。冷凍サイコロ豆腐(めちゃくちゃ便利)
  • ネギ:1/3くらいをみじん切り
  • お肉調味料
    • 豆板醤:大匙1
    • 甜麺醤:大匙1(なかったので味噌大匙1+砂糖大匙3/4くらいで代用)
    • 一味唐辛子:適当
    • しょうが、にんにくチューブ:適当
    • 酒:大匙1
    • 醤油:大匙1
    • オイスターソース:大匙1くらい
  • スープ
    • お湯:150CC
    • 中華スープの素:小匙1
  • 水溶き片栗粉:片栗粉、水ともに大匙1
  • ラー油:適当

手順

  1. お肉調味料を合わせておく。ネギはみじん切りにしておく。お豆腐もサイコロ状に切っておく
  2. ごま油をしいたフライパンでひき肉をしっかり炒める
  3. お肉調味料を入れて弱火で炒める
  4. 赤い油が浮いてきたら、スープを入れてコトコト煮込む
  5. さいころ状の豆腐をお湯とひとつまみの塩で湯がく(冷凍サイコロ豆腐の場合はこの手順スキップ)。沸騰したらOK
  6. コトコト煮込んでるお肉にお湯を切ったお豆腐を入れる
  7. お豆腐がいい感じになるまで煮る
  8. いったん火を止めて、水溶き片栗粉を回しかける
  9. 再度弱火をつける
  10. ネギを入れる
  11. 最後にラー油を適当に回しかけて完成

アレンジ箇所

  • 甜麺醤がなかったので味噌と砂糖で代用
  • オイスターソースを加えた(理由はなんとく美味しいかなと)

反省点

  • 花椒がなかったのでしびれ0。カルディで買っておくべきだった

美味しかったのでまた作りたい。

GithubのRepositoryをmavenリポジトリとして使う

なんで今さら

  • 数年前に開発が停止してしまっているコードをフォークして利用したい
  • 元のソースのApache License 2.0。フォークしたコードはOSSとして公開しないといけない?(うろ覚え・・・)
    • ソースコードをそのまま組み込むのはNGそうな気がする?
    • 修正と再頒布そのものは禁止されていない(はず
  • maven のローカルリポジトリとして修正したコードを公開する
  • 実際のコードにはこれを取り込んで使う

手順

maven の deploy タスクの実行によって生成物を Github Respositry へアップロードする。生成物はブランチで管理、構成。 Version はタグによって管理する。

環境

maven の Version は以下の通り。

$ mvn --version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /usr/local/Cellar/maven/3.6.3_1/libexec
Java version: 11.0.6, vendor: Amazon.com Inc., runtime: /Users/com4dc/.sdkman/candidates/java/11.0.6-amzn
Default locale: ja_JP, platform encoding: UTF-8
OS name: "mac os x", version: "10.14.6", arch: "x86_64", family: "mac"

Github AccessToken の生成

password の代わりに Github の Personal AccessToken を生成する。 参照した URL では repo:* 権限のみで良いとあったが、実際には user:email の read 権限も必要だった。

f:id:com4dc:20200330224807j:plain

以下のIssueコメントで見つけた。

github.com

~/.m2/settings.xml

settings.xml には Github Repository の認証情報を記述する。

<settings>
  <servers>
    <server>
      <id>github</id>
      <username>USERNAME</username>
      <password>PERSONAL-ACCESSTOKEN</password>
    </server>
  </servers>
</settings>

これらの情報は当然 push しない(してしまったら、速攻でAccessTokenをRevokeする)

pom.xml

pom.xml に以下の情報を記述する。まずは project.properties

project.properties

Dependency で必要なライブラリの Version 情報、文字コード情報や Java のバージョン指定等のメタデータを入れる。

<project>
    <properties>
        <!-- 文字コード -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- コードと生成クラスのバージョン情報 -->
        <java.version>1.8</java.version>
        <!-- 認証情報を読み込む(settings.xml) -->
        <github.global.server>github</github.global.server>
    </properties>

<github.global.server>github</github.global.server>  には前出の settings.xml で作成した Id を指定することで、Github の認証情報を取り込んでいるっぽい。

project.distributionManagement

project.distributionManagement は Upload 元となる生成物を指定する。

<project>
    <!-- Local の target/mvn-repo フォルダをリポジトリとして宣言 -->
    <distributionManagement>
        <repository>
            <id>internal.repos</id>
            <name>Sample Maven Repository</name>
            <url>file://${project.build.directory}/mvn-repo</url>
        </repository>
    </distributionManagement>
</project>

project.build

 続いて project.build 以下を見ていく。基本的に利用する plugin の指定が記述されている。

maven-compiler-plugin

何も指定しないで実行したところ、5, 6 あたりがターゲットになってしまった。さすがに古すぎる。

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>

site-maven-plugin

Github Officialmaven-plugin

github.com

userName, password 等も設定できるので、CI等の動作を考えると環境変数に値を埋め込む方が都合が良いかもしれない。今回はすでに認証情報が読み込まれている状況なので特に何も設定しなくてもOK。

            <plugin>
                <groupId>com.github.github</groupId>
                <artifactId>site-maven-plugin</artifactId>
                <version>0.12</version>
                <configuration>
                    <!-- Git commit message -->
                    <message>Maven artifacts for ${project.version}</message>
                    <noJekyll>true</noJekyll>

                    <!-- distributionManagement の url と一致させる -->
                    <outputDirectory>${project.build.directory}/mvn-repo</outputDirectory>
                    <branch>refs/heads/mvn-repo</branch>
                    <includes><include>**/*</include></includes>

                    <!-- Github リポジトリ名 -->
                    <repositoryName>sample-project</repositoryName>
                    <repositoryOwner>com4dc</repositoryOwner>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>site</goal>
                        </goals>
                        <phase>deploy</phase>
                    </execution>
                </executions>
            </plugin>

基本的に素直に設定しているだけなのだが noJekyll だけよくわからなかった。OfficialページのREADMEを確認すると以下とある。

Whether to always create a .nojekyll file at the root of the site if one doesn't already exist. This setting should be enabled if your site contains any folders that begin with an underscore.

アンダースコアを含むディレクトリがあるかどうかで変わるらしい。 どうやらこれはGithub Pagesの機能Jekyllという処理エンジンを利用しているのだが、それを利用しない場合に配置するファイルらしい。ふーむ。なるほど

最終形

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>com.github.github</groupId>
                <artifactId>site-maven-plugin</artifactId>
                <version>0.12</version>
                <configuration>
                    <!-- Git commit message -->
                    <message>Maven artifacts for ${project.version}</message>
                    <noJekyll>true</noJekyll>

                    <!-- distributionManagement の url と一致させる -->
                    <outputDirectory>${project.build.directory}/mvn-repo</outputDirectory>
                    <branch>refs/heads/mvn-repo</branch>
                    <includes><include>**/*</include></includes>

                    <!-- Github リポジトリ名 -->
                    <repositoryName>sample-project</repositoryName>
                    <repositoryOwner>com4dc</repositoryOwner>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>site</goal>
                        </goals>
                        <phase>deploy</phase>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

deploy

Deployするとみゃ~っとコンパイルからUploadまで実行される。

$ mvn clean deploy

....
[INFO] --- site-maven-plugin:0.12:site (default) @ sample-project ---
[INFO] Creating 9 blobs
[INFO] Creating tree with 10 blob entries
[INFO] Creating commit with SHA-1: aaaaaaaa
[INFO] Updating reference refs/heads/mvn-repo from xxxxxxx to bc9947dbd112e7298bf82eb4214860b99999ede9
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  42.236 s
[INFO] Finished at: 2020-03-30T22:42:39+09:00
[INFO] ------------------------------------------------------------------------

Deploy後に出力されたハッシュ bc9947dbd112e7298bf82eb4214860b99999ede9 をタグに記録。

事前にPullしないと fatal: cannot update ref 'refs/tags/0.0.2': trying to write ref 'refs/tags/0.0.2' with nonexistent object 6d4XXXXX と出る可能性がある

$ git tag 0.0.1 bc9947dbd112e7298bf82eb4214860b99999ede9
$ git push origin 0.0.1

使い方

gradle プロジェクトでは build.gradle に以下を記述。

repositories {
    mavenCentral()

    // for sample-project
    maven { url "https://raw.github.com/com4dc/sample-project/mvn-repo"}
}

dependencies {
    compileOnly "com.github.com4dc:sample-project:0.0.1"
}

repositories には次のフォーマットで url を記述する。 https://raw.github.com/OWNER_NAME/REPOSITORY_NAME/BRANCH_NAME 今回は BRANCH_NAMEmvn_repo としているので、変更がある場合は別途変更すれば良さそう。

version 情報は前の手順で打った Tag と同じ。

参照

AWS SDK for Java V2

雑に調べたメモ

普通にググるとv1に行き着いてしまう。 mavenは以下らへん。

mvnrepository.com

GradleでSDKの組み込みは以下参照

https://docs.aws.amazon.com/ja_jp/sdk-for-java/v2/developer-guide/setup-project-gradle.htmldocs.aws.amazon.com

implementation platform('software.amazon.awssdk:bom:2.5.29')

これをdependencyに書いておかないと依存解決できない。

S3だけ使う場合は以下

implementation 'software.amazon.awssdk:s3'

Version指定はいらないらしい。 当然パッケージも変わってるので色々変えないとダメ。

maven リポジトリのサンプルだと testCompile しか書いてないんだけどなんでだろ。

S3Client

めちゃくちゃ安易にAccessKey, SecretKeyを明示的に指定するなら以下(当然あんまり推奨されてないが)

AwsBasicCredentials awsCreds = AwsBasicCredentials.create(getAccessKey(), getSecretKey());
var s3Client = S3Client.builder().credentialsProvider(StaticCredentialsProvider.create(awsCreds))
                        .build();

AccessKey, SecretKey を必要とする AwsCredentials の実装は以下

sdk.amazonaws.com

まあ、Profile指定したいときはこの辺を変えてあげれば良さそう。比較的直感的だと思うけど、v1 系の知識でそのまま書けないので色々書き直さないとダメそう。

Spring Security 5で OAuth2 Login

背景

業務で Spring Security を使っているのだが、まだ古いバージョンを利用していてこれを Migration する気配がない。

さすがに最後発で新しく作るサービスはそちらに合わせるわけには行かないので、 Java バージョン(これは11だけど)、Spring バージョンを最新にすると同時に Spring Security のバージョンも 5.X 系に変更させたい。それのために色々調べている。

そしてバージョンアップの一番のモチベーションがこちら。

github.com

今まで利用していた OAuth2RestTemplate が Deprecated にマークされており、今後使ってくれるなとのこと。メンテナンスもされないのでこれは厳しい。

そしてこの Migration ガイドがまだ WIP な模様。 途中の Examples Matrix を見ると、それぞれのGrant Flowごとにサンプルがあるように見えるのだが、リンクはすべて同じという(何のためにわけてあるんだ・・?)

OAuth 2.0 Migration Guide · spring-projects/spring-security Wiki · GitHub

最小限で使ってみる

公式 Reference を読むべきなのだがなかなか膨大。Migration ガイドがうーんという感じで困っていたところ kazuki43zoo さんの Qiita 記事が一番まとまっていてとても助かった。動かしながら確認できそうなのでこちらをガイドに使わせていただく。

qiita.com

こちらの Qiita 記事と公式 Reference を参照しながらすすめていく。

環境

  • macOS Mojave 10.14.6
  • openjdk version "11.0.6" 2020-01-14 LTS
  • IntelliJ IDEA 2019.3.3 Ultimate

IdProvider

現在所属しているクラスメソッドでは、OpenId Connect 1.0 準拠の IdProvider アプリケーションを提供している。自分も少しだけ開発に噛んでいたためこちらを利用することにした。

classmethod.jp

build.gradle

最近、Spring Initializr を使わない謎ブームが来てるのでぬくもりある手作りでやっていき。

https://start.spring.io/

plugins {
    id 'org.springframework.boot' version '2.2.5.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
    id 'java'
}

group = 'com.github.com4dc.sample'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
    testImplementation 'org.springframework.security:spring-security-test'
}

test {
    useJUnitPlatform()
}

Gradleプロジェクトの初期記述から最低限必要なのだけ追加した。

DemoController

Qiita の記事のコードをほぼ丸パクリ。Java11だから var をちょっと使ってみたかった程度しか手を入れていない。

@Controller
@RequiredArgsConstructor
public class DemoController {

    private RestOperations restOperations = new RestTemplate();

    // 認可済みのクライアント情報は OAuth2AuthorizedClientService経由で取得できる
    private final OAuth2AuthorizedClientService authorizedClientService;

    @GetMapping("/")
    public String index(OAuth2AuthenticationToken authentication, Model model) {
        model.addAttribute("authorizedClient", getAuthorizedClient(authentication));
        return "index";
    }

    @GetMapping("/attributes")
    public String userAttributeAtLogin(@AuthenticationPrincipal OAuth2User oAuth2User, Model model) {
        // 認証時点のユーザー情報。あくまでスナップショット。時間が経てば更新されている可能性
        model.addAttribute("attributes", oAuth2User.getAttributes());
        return "userinfo";
    }

    @GetMapping("/attributes/latest")
    public String userLatestAttribute(OAuth2AuthenticationToken authenticationToken, Model model) {
        // 最新のユーザー情報を取って表示する

        // 認可済みClientを返す
        var client = this.getAuthorizedClient(authenticationToken);

        // Client情報からUserinfo Endpointを探す
        var userInfoUri = client.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri();

        // AccessTokenをAuthorizationヘッダにBearerで指定してUserInfoエンドポイントから最新の情報を引っ張ってくる
        var requestEntity = RequestEntity.get(URI.create(userInfoUri))
                .header(HttpHeaders.AUTHORIZATION, "Bearer " + client.getAccessToken().getTokenValue())
                .build();
        model.addAttribute("attributes", restOperations.exchange(requestEntity, Map.class).getBody());
        return "userinfo";
    }

    private OAuth2AuthorizedClient getAuthorizedClient(OAuth2AuthenticationToken authentication) {
        // 認証済みのClient情報を取得
        return this.authorizedClientService.loadAuthorizedClient(
                authentication.getAuthorizedClientRegistrationId(), authentication.getName()
        );
    }
}

Application Class

SpringBoot Applicationのエントリポイント

@SpringBootApplication
public class SampleOAuth2Application {

    public static void main(String... args) {
        SpringApplication.run(SampleOAuth2Application.class, args);
    }
}

application.yaml

src/main/resources 配下に application.yaml を作成。

spring:
  security:
    oauth2:
      client:
        registration:
          barista:
            client-id: CLIENT_SAMPLE
            client-secret: 'CLIENT_SECRET'
            redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
            authorization-grant-type: authorization_code
            scope:
              - openid
            client-name: Barista
        provider:
          barista:
            authorization-uri: https://example.com/oauth/authorize
            token-uri: https://example.com/oauth/token
            jwk-set-uri: https://example.com/jwk
            user-info-uri: https://example.com/userinfo
            user-name-attribute: sub

logging:
  level:
    org:
      springframework:
        security: debug

Google, Facebook などの一般的なIdProviderはCommonとして定義されており、エンドポイント情報等が予め記述されているため、provider情報を自分で設定する必要がない。

spring-security/CommonOAuth2Provider.java at master · spring-projects/spring-security · GitHub

仕様に準拠していれば独自の IdProvider でも定義さえすれば問題なく動作するようだ。ログレベルに関しては何がどう動いてるかを確認するためにつけてる。

HTML Template

index.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
    <title>Demo Application OAuth 2.0 Login with Spring Security 5</title>
    <meta charset="utf-8"/>
</head>
<body>
<div style="float: right" th:fragment="logout" sec:authorize="isAuthenticated()">
    <div style="float:left">
        <span style="font-weight:bold">User Id:</span>
        <span sec:authentication="name">1000000</span>
        <span style="font-weight:bold">User Name:</span>
        <span sec:authentication="principal.attributes['name']">Taro Yamada</span>
    </div>
    <div style="float:none">&nbsp;</div>
    <div style="float:right">
        <form action="#" th:action="@{/logout}" method="post">
            <input type="submit" value="Logout"/>
        </form>
    </div>
</div>
<h1>Welcome Demo Application OAuth 2.0 Login with Spring Security 5 !!</h1>
<div>
    You are successfully logged in via the OAuth 2.0 Client
    -<span style="font-weight:bold" th:text="${authorizedClient.clientRegistration.clientName}">Demo Client</span>-
</div>
<div>&nbsp;</div>
<div>
    <ul>
        <li>
            <a href="/templates/userinfo.html" th:href="@{/attributes}">Display User Attributes at login</a>
        </li>
        <li>
            <a href="/templates/userinfo.html" th:href="@{/attributes/latest}">Display latest User Attributes</a>
        </li>
    </ul>
</div>
</body>
</html>

userinfo.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Demo Application OAuth 2.0 Login with Spring Security 5 - User Attributes -</title>
    <meta charset="utf-8"/>
</head>

<body>
<div th:replace="index::logout"></div> <!-- 認証ユーザの名前、ログアウトボタン -->
<h1>Demo Application OAuth 2.0 Login with Spring Security 5 - User Attributes -</h1>
<div>
    <span style="font-weight:bold">User Attributes:</span>
    <!-- ユーザ属性の一覧 -->
    <ul>
        <li th:each="attribute : ${attributes}">
            <span style="font-weight:bold" th:text="${attribute.key}"></span>: <span th:text="${attribute.value}"></span>
        </li>
    </ul>
</div>
</body>
</html>

ひとまずこれで起動する。本当に何も書いてないのだが、これでつながるのだろうか・・・。 今までのいろいろな面倒な設定を思い出すと何も書いてないに等しい。

....
2020-03-23 23:12:34.515  INFO 50010 --- [           main] o.s.s.web.DefaultSecurityFilterChain     : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@794366a5, org.springframework.security.web.context.SecurityContextPersistenceFilter@6e3ecf5c, org.springframework.security.web.header.HeaderWriterFilter@73809e7, org.springframework.security.web.csrf.CsrfFilter@67f77f6e, org.springframework.security.web.authentication.logout.LogoutFilter@49d30c6f, org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter@5d1e0fbb, org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter@127705e4, org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter@3fb9a67f, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@35c9a231, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@480b57e2, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@341b13a8, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@462abec3, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@40f35e52, org.springframework.security.oauth2.client.web.OAuth2AuthorizationCodeGrantFilter@3f36e8d1, org.springframework.security.web.session.SessionManagementFilter@48df4071, org.springframework.security.web.access.ExceptionTranslationFilter@30c4e352, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@6bccd036]
2020-03-23 23:12:34.585  INFO 50010 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2020-03-23 23:12:34.590  INFO 50010 --- [           main] j.c.k.sample.SampleOAuth2Application     : Started SampleOAuth2Application in 2.085 seconds (JVM running for 8.001)

なんかめちゃくちゃFilterが定義されてるのが見える。 ブラウザで http://localhost:8080/ にアクセスしてみると

f:id:com4dc:20200323231520p:plain

認証されていないため、AuthorizeエンドポイントへRedirectされ、最終的に IdProvider のログイン画面が GET しているのがわかる。ログインして正常に認証されると以下のページが表示される。

f:id:com4dc:20200323232115j:plain

ひとまず単純な正常動作はOK。動作が色々気になるので Qiitaの記事をガイドに読んでいく。

エラー

scopeに openid がない

clientのscopeに openid がない場合以下のエラー画面が表示される。

f:id:com4dc:20200323232552p:plain

client の scope に定義されていても承認画面で scope を拒否した場合も同様にエラー画面が表示される。

Java12でLombok

Lombokが動かない

普段、Spring系のプロジェクトは Spring Initializr のお世話になっているのだが、はて?すべてを理解して使っているだろうかと、素のGradleプロジェクトからシコシコ構築していた。

いつも通り Lombok を導入して Compile したところこんなエラーが。

エラー: 変数nameは、デフォルト・コンストラクタで初期化されていません

おや?

環境

検証した環境は以下の通り。 普段との違いは、Windows環境であることとJavaのバージョンが結構上がってることくらい。

コード

エラー対象のコードはこちら。

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public class GreetingResponse {

    private final String name;
    private final String message;
}

Gradleはこちら。

dependencies {
    implementation "org.springframework.boot:spring-boot-starter-webflux:$springWebfluxVersion"
    compileOnly "org.projectlombok:lombok:$lombokVersion"

    testImplementation "org.springframework.boot:spring-boot-starter-test:$springWebfluxVersion"
    testImplementation 'io.projectreactor:reactor-test'
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

Version情報は以下の通り

springWebfluxVersion = 2.2.5.RELEASE
lombokVersion = 1.18.12

Lombok Pluginは導入済み。 Enable annotation processing は有効済み。

はて?おかしいところはないはずなんだが・・・。

Java12 + Lombok

そういえばJavaのあるバージョン以降(詳しい分岐点を忘れた)、既存のLombok導入ではダメだったのをふと思い出した。 Java12は無罪でした。すいません。追記参照

ざっと検索したところ以下を見つけた。

stackoverflow.com

あたり。 annotationProcessor にも Lombok を指定してやる必要があった。以下で解決。

dependencies {
    implementation "org.springframework.boot:spring-boot-starter-webflux:$springWebfluxVersion"
    compileOnly "org.projectlombok:lombok:$lombokVersion"
    annotationProcessor "org.projectlombok:lombok:$lombokVersion" // Add
    ...
}

Compile 成功。この辺り細かい違いがあって Migration が面倒そう。

追記

Twitterで「それJava関係ないやで。Gradleの問題やで」と教えてもらった。

qiita.com

Gradle 5.0 からはアノテーションプロセッサをコンパイル時のクラスパスから取得する方法がサポートされなくなるらしい。

なるほど。これですな。

#Mon Mar 09 22:44:33 JST 2020
distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

5.2.1 を利用していた。

Java12は無罪でした。ごめんなさい。

aws-cdkのマルチスタックのDeploy

Multi Stack の Deploy

複数の Stack を Deploy しようとしたら怒られた。

$ cdk deploy
Since this app includes more than a single stack, specify which stacks to use (wildcards are supported)
Stacks: NetworkStack DataStoreStack

「Stack を指定しないと駄目だよ。ワイルドカード使えるぜ」とのメッセージ。

$ cdk deploy *
No stack found matching 'README.md'. Use "list" to print manifest

バカ正直にやったら怒れられた。以下が正しいらしい。

$ cdk deploy '*'
NetworkStack
This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:

Security Group Changes
...

'' で囲うという発想がなかった。

参照

blog.youyo.io

aws-cdkでAurora Postgresqlを起動するために試行錯誤した結果

概要

諸事情あってAurora postgresqlを起動する必要があった。折角なのでCDKで試した結果。

エラー

Cluster requires at least 2 subnets, got 0

Subnetを2つ以上指定しないとダメ。vpcをIDから解決しているので vpc.privateSubnets とかで取れる。

vpcSubnets: {
           subnets: vpc.privateSubnets
        },

MasterUsername admin cannot be used as it is a reserved word used by the engine

db-aurora (dbaurora55E909B7) MasterUsername admin cannot be used as it is a reserved word used by the engine (Service: AmazonRDS; Status Code: 400; Error Code: InvalidParameterValue; Request ID: f8ff0919-c8ae-4809-a354-837a77311ca3)

Aurora MySQLのサンプルだと admin と書いてあったんだが? Postgresql だとどうもダメらしい。この辺はDatabase Engineの話なんだろうがよく分かっていない。 clusteradmin に変えたら問題なく通った。

DBClusterParameterGroup not found: default.aurora5.6

db-aurora (dbaurora55E909B7) DBClusterParameterGroup not found: default.aurora5.6 (Service: AmazonRDS; Status Code: 404; Error Code: DBClusterParameterGroupNotFound; Request ID: a2dd5963-3371-4a89-874c-a8e3a797415b)

parameterGroup指定してるのになんでや!と思ったら instanceProps の方に指定していた。Clusterの方の parameterGroup を指定するのが正解。

const rdsClusterPrameterGroup = new ClusterParameterGroup(this, 'DBClusterPArameterGroup', {
        family: 'aurora-postgresql10',
        parameters: {
            application_name: 'db-gateway',
        }
    });

const cluster = new DatabaseCluster(this, "db-aurora", {
    engine: DatabaseClusterEngine.AURORA_POSTGRESQL,
    removalPolicy: RemovalPolicy.DESTROY,
    masterUser: {
       username: "clusteradmin"
    },
    instanceProps: {
       // TODO: ここもパラメータ化した方が良い?
       instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL),
        vpcSubnets: {
           subnets: vpc.privateSubnets
        },
        vpc: vpc,
        securityGroup: props.dbSg,
         parameterGroup: rdsClusterPrameterGroup // ← ここじゃない
    }
    // ← ここが正しい
});

RDS does not support creating a DB instance with the following combination:

db-aurora/Instance1 (dbauroraInstance11F6C709C) RDS does not support creating a DB instance with the following combination: DBInstanceClass=db.t2.small, Engine=aurora-postgresql, EngineVersion=10.7, LicenseModel=postgresql-license. For supported combinations of instance class and database engine version, see the documentation. (Service: AmazonRDS; Status Code: 400; Error Code: InvalidParameterCombination; Request ID: 853d8c16-c07b-400c-abfe-b518675f18d3)

Instanceのタイプとサイズが起動しようとするDBでサポートしていないらしい。ごめんなさい。ケチりすぎた。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Concepts.DBInstanceClass.html