概要
非推奨なpropertyの検知のためにspring-boot-properties-migrator
という便利なライブラリが用意されていますが、できればビルドを失敗させたい…!
→ 少し強引な方法ですが、ひとまず実現できたのでメモ代わりに残しておきます
spring-boot-properties-migrator
とは?
非推奨なpropertyの検知して、warnログやerrorログでお知らせしてくれるライブラリです。
(propertyの読み替えもやってくれているはず)
主にPropertiesMigrationListener
が頑張ってくれています。
準備
この記事を書いた際に手元で動かしていたソースの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クラスを作ってあげます。
その実装が↓こちら↓
@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());
}
}