1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【SpringBoot】非推奨なpropertyを使用していたらビルドを失敗させる

Posted at

概要

非推奨なpropertyの検知のためにspring-boot-properties-migratorという便利なライブラリが用意されていますが、できればビルドを失敗させたい…!

→ 少し強引な方法ですが、ひとまず実現できたのでメモ代わりに残しておきます

spring-boot-properties-migratorとは?

非推奨なpropertyの検知して、warnログやerrorログでお知らせしてくれるライブラリです。
(propertyの読み替えもやってくれているはず)

主にPropertiesMigrationListenerが頑張ってくれています。

準備

この記事を書いた際に手元で動かしていたソースのbuild.gradleの抜粋はこちらです

build.gradle
plugins {
    id 'org.springframework.boot' version "2.5.0"
    id 'io.spring.dependency-management' version "1.0.11.RELEASE"
    id 'java'
    id 'com.github.ben-manes.versions' version "0.36.0"
}

...

dependencies {
    ...
    testRuntimeOnly("org.springframework.boot:spring-boot-properties-migrator")
    testCompileOnly("org.springframework.boot:spring-boot-properties-migrator")
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

ビルドを失敗させる

PropertiesMigrationListenerなのですが、ログ出力のみでレポートの内容を取得するようなメソッドは用意されていないので、自分でwrapperクラスを作ってあげます。

その実装が↓こちら↓

org.springframework.boot.context.properties.migrator.PropertiesMigrationListenerWrapper
@Slf4j
public class PropertiesMigrationListenerWrapper
        implements ApplicationListener<SpringApplicationEvent> {

    private PropertiesMigrationReport report;

    @Override
    public void onApplicationEvent(SpringApplicationEvent event) {
        log.info("event class: {}", event.getClass());
        if (event instanceof ApplicationStartedEvent) {
            onApplicationPreparedEvent((ApplicationStartedEvent) event);
        }
    }

    @EventListener
    public void onApplicationPreparedEvent(ApplicationStartedEvent event) {
        ConfigurationMetadataRepository repository = loadRepository();
        PropertiesMigrationReporter reporter = new PropertiesMigrationReporter(repository,
                event.getApplicationContext().getEnvironment());
        this.report = reporter.getReport();
    }

    private ConfigurationMetadataRepository loadRepository() {
        try {
            return loadRepository(ConfigurationMetadataRepositoryJsonBuilder.create());
        }
        catch (IOException ex) {
            throw new IllegalStateException("Failed to load metadata", ex);
        }
    }

    private ConfigurationMetadataRepository loadRepository(ConfigurationMetadataRepositoryJsonBuilder builder)
            throws IOException {
        Resource[] resources = new PathMatchingResourcePatternResolver()
                .getResources("classpath*:/META-INF/spring-configuration-metadata.json");
        for (Resource resource : resources) {
            try (InputStream inputStream = resource.getInputStream()) {
                builder.withJsonResource(inputStream);
            }
        }
        return builder.build();
    }

    // 非推奨なpropertyが存在するか真偽値を返す
    public boolean existsDeprecatedProperty() {
        var result = false;
        String warningReport = this.report.getWarningReport();
        if (warningReport != null) {
            log.warn(warningReport);
            result = true;
        }

        String errorReport = this.report.getErrorReport();
        if (errorReport != null) {
            log.error(errorReport);
            result = false;
        }

        return result;
    }
}

ほぼPropertiesMigrationListenerのコピペなのですが、テストの検証用にexistsDeprecatedProperty()を用意しています。

また、packageはorg.springframework.boot.context.properties.migrator固定です。
(利用クラスがpackage privateなクラスなので…)
はい、これが強引と言ったいた理由ですmm

Wrapperクラスは用意できたので、SpringApplicationEventをlistenしてくれるようにBean登録しておきます。

@Configuration
public class TestAutoConfiguration {
    @Bean
    public PropertiesMigrationListenerWrapper propertiesMigrationListenerWrapper() {
        return new PropertiesMigrationListenerWrapper();
    }
}

最後にテストクラスです。

@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = {Application.class, TestAutoConfiguration.class})
class PropertyMigrateTest {

    @Autowired
    private PropertiesMigrationListenerWrapper migrationListener;

    @Test
    void test() {
        assertFalse(migrationListener.existsDeprecatedProperty());
    }
}
1
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?