Polish "Add Java InfoContributor"

See gh-28136
This commit is contained in:
Stephane Nicoll
2021-10-01 15:42:59 +02:00
parent fc87da7ef3
commit 5d17257a52
11 changed files with 247 additions and 286 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@ import org.springframework.boot.actuate.info.BuildInfoContributor;
import org.springframework.boot.actuate.info.EnvironmentInfoContributor;
import org.springframework.boot.actuate.info.GitInfoContributor;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.boot.actuate.info.java.JavaInfoContributor;
import org.springframework.boot.actuate.info.JavaInfoContributor;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -82,7 +82,7 @@ public class InfoContributorAutoConfiguration {
@Bean
@ConditionalOnEnabledInfoContributor("java")
@Order(DEFAULT_ORDER)
public InfoContributor javaInfoContributor() {
public JavaInfoContributor javaInfoContributor() {
return new JavaInfoContributor();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@ package org.springframework.boot.actuate.autoconfigure.info;
import java.util.Map;
import java.util.Properties;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.info.BuildInfoContributor;
@@ -27,12 +26,12 @@ import org.springframework.boot.actuate.info.EnvironmentInfoContributor;
import org.springframework.boot.actuate.info.GitInfoContributor;
import org.springframework.boot.actuate.info.Info;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.boot.actuate.info.java.JavaInfo;
import org.springframework.boot.actuate.info.java.JavaInfoContributor;
import org.springframework.boot.actuate.info.JavaInfoContributor;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.info.BuildProperties;
import org.springframework.boot.info.GitProperties;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.boot.info.JavaInfo;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -46,121 +45,113 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class InfoContributorAutoConfigurationTests {
private AnnotationConfigApplicationContext context;
@AfterEach
void close() {
if (this.context != null) {
this.context.close();
}
}
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(InfoContributorAutoConfiguration.class));
@Test
void disableEnvContributor() {
load("management.info.env.enabled:false");
Map<String, InfoContributor> beans = this.context.getBeansOfType(InfoContributor.class);
assertThat(beans).extractingFromEntries(Map.Entry::getValue).allSatisfy(
(infoContributor) -> assertThat(infoContributor).isNotInstanceOf(EnvironmentInfoContributor.class));
this.contextRunner.withPropertyValues("management.info.env.enabled=false")
.run((context) -> assertThat(context).doesNotHaveBean(EnvironmentInfoContributor.class));
}
@Test
void disableJavaContributor() {
load("management.info.java.enabled:false");
Map<String, InfoContributor> beans = this.context.getBeansOfType(InfoContributor.class);
assertThat(beans).extractingFromEntries(Map.Entry::getValue).allSatisfy(
(infoContributor) -> assertThat(infoContributor).isNotInstanceOf(JavaInfoContributor.class));
this.contextRunner.withPropertyValues("management.info.java.enabled=false")
.run((context) -> assertThat(context).doesNotHaveBean(JavaInfoContributor.class));
}
@Test
void defaultInfoContributorsEnabled() {
load();
Map<String, InfoContributor> beans = this.context.getBeansOfType(InfoContributor.class);
assertThat(beans).hasSize(2).extractingFromEntries(Map.Entry::getValue)
.anySatisfy(
(infoContributor) -> assertThat(infoContributor).isInstanceOf(EnvironmentInfoContributor.class))
.anySatisfy((infoContributor) -> assertThat(infoContributor).isInstanceOf(JavaInfoContributor.class));
this.contextRunner.run((context) -> {
assertThat(context).hasSingleBean(EnvironmentInfoContributor.class)
.hasSingleBean(JavaInfoContributor.class);
assertThat(context.getBeansOfType(InfoContributor.class)).hasSize(2);
});
}
@Test
void defaultInfoContributorsDisabled() {
load("management.info.defaults.enabled:false");
Map<String, InfoContributor> beans = this.context.getBeansOfType(InfoContributor.class);
assertThat(beans).hasSize(0);
this.contextRunner.withPropertyValues("management.info.defaults.enabled=false")
.run((context) -> assertThat(context).doesNotHaveBean(InfoContributor.class));
}
@Test
void defaultInfoContributorsDisabledWithCustomOne() {
load(CustomInfoContributorConfiguration.class, "management.info.defaults.enabled:false");
Map<String, InfoContributor> beans = this.context.getBeansOfType(InfoContributor.class);
assertThat(beans).hasSize(1);
assertThat(this.context.getBean("customInfoContributor")).isSameAs(beans.values().iterator().next());
this.contextRunner.withPropertyValues("management.info.defaults.enabled=false")
.withUserConfiguration(CustomInfoContributorConfiguration.class).run((context) -> {
assertThat(context).hasSingleBean(InfoContributor.class);
assertThat(context.getBean(InfoContributor.class))
.isSameAs(context.getBean("customInfoContributor"));
});
}
@SuppressWarnings("unchecked")
@Test
void gitPropertiesDefaultMode() {
load(GitPropertiesConfiguration.class);
Map<String, InfoContributor> beans = this.context.getBeansOfType(InfoContributor.class);
assertThat(beans).containsKeys("gitInfoContributor");
Map<String, Object> content = invokeContributor(
this.context.getBean("gitInfoContributor", InfoContributor.class));
Object git = content.get("git");
assertThat(git).isInstanceOf(Map.class);
Map<String, Object> gitInfo = (Map<String, Object>) git;
assertThat(gitInfo).containsOnlyKeys("branch", "commit");
this.contextRunner.withUserConfiguration(GitPropertiesConfiguration.class).run((context) -> {
assertThat(context).hasSingleBean(GitInfoContributor.class);
Map<String, Object> content = invokeContributor(context.getBean(GitInfoContributor.class));
Object git = content.get("git");
assertThat(git).isInstanceOf(Map.class);
Map<String, Object> gitInfo = (Map<String, Object>) git;
assertThat(gitInfo).containsOnlyKeys("branch", "commit");
});
}
@SuppressWarnings("unchecked")
@Test
void gitPropertiesFullMode() {
load(GitPropertiesConfiguration.class, "management.info.git.mode=full");
Map<String, Object> content = invokeContributor(
this.context.getBean("gitInfoContributor", InfoContributor.class));
Object git = content.get("git");
assertThat(git).isInstanceOf(Map.class);
Map<String, Object> gitInfo = (Map<String, Object>) git;
assertThat(gitInfo).containsOnlyKeys("branch", "commit", "foo");
assertThat(gitInfo.get("foo")).isEqualTo("bar");
this.contextRunner.withPropertyValues("management.info.git.mode=full")
.withUserConfiguration(GitPropertiesConfiguration.class).run((context) -> {
assertThat(context).hasSingleBean(GitInfoContributor.class);
Map<String, Object> content = invokeContributor(context.getBean(GitInfoContributor.class));
Object git = content.get("git");
assertThat(git).isInstanceOf(Map.class);
Map<String, Object> gitInfo = (Map<String, Object>) git;
assertThat(gitInfo).containsOnlyKeys("branch", "commit", "foo");
assertThat(gitInfo.get("foo")).isEqualTo("bar");
});
}
@Test
void customGitInfoContributor() {
load(CustomGitInfoContributorConfiguration.class);
assertThat(this.context.getBean(GitInfoContributor.class))
.isSameAs(this.context.getBean("customGitInfoContributor"));
this.contextRunner.withUserConfiguration(CustomGitInfoContributorConfiguration.class).run((context) -> {
assertThat(context).hasSingleBean(GitInfoContributor.class);
assertThat(context.getBean(GitInfoContributor.class)).isSameAs(context.getBean("customGitInfoContributor"));
});
}
@SuppressWarnings("unchecked")
@Test
void buildProperties() {
load(BuildPropertiesConfiguration.class);
Map<String, InfoContributor> beans = this.context.getBeansOfType(InfoContributor.class);
assertThat(beans).containsKeys("buildInfoContributor");
Map<String, Object> content = invokeContributor(
this.context.getBean("buildInfoContributor", InfoContributor.class));
Object build = content.get("build");
assertThat(build).isInstanceOf(Map.class);
Map<String, Object> buildInfo = (Map<String, Object>) build;
assertThat(buildInfo).containsOnlyKeys("group", "artifact", "foo");
assertThat(buildInfo.get("foo")).isEqualTo("bar");
this.contextRunner.withUserConfiguration(BuildPropertiesConfiguration.class).run((context) -> {
assertThat(context).hasSingleBean(BuildInfoContributor.class);
Map<String, Object> content = invokeContributor(context.getBean(BuildInfoContributor.class));
Object build = content.get("build");
assertThat(build).isInstanceOf(Map.class);
Map<String, Object> buildInfo = (Map<String, Object>) build;
assertThat(buildInfo).containsOnlyKeys("group", "artifact", "foo");
assertThat(buildInfo.get("foo")).isEqualTo("bar");
});
}
@Test
void customBuildInfoContributor() {
load(CustomBuildInfoContributorConfiguration.class);
assertThat(this.context.getBean(BuildInfoContributor.class))
.isSameAs(this.context.getBean("customBuildInfoContributor"));
this.contextRunner.withUserConfiguration(CustomBuildInfoContributorConfiguration.class).run((context) -> {
assertThat(context).hasSingleBean(BuildInfoContributor.class);
assertThat(context.getBean(BuildInfoContributor.class))
.isSameAs(context.getBean("customBuildInfoContributor"));
});
}
@Test
void javaInfoContributor() {
load();
Map<String, InfoContributor> beans = this.context.getBeansOfType(InfoContributor.class);
assertThat(beans).containsKeys("javaInfoContributor");
Map<String, Object> content = invokeContributor(
this.context.getBean("javaInfoContributor", InfoContributor.class));
Object javaInfo = content.get("java");
assertThat(javaInfo).isInstanceOf(JavaInfo.class);
this.contextRunner.run((context) -> {
assertThat(context).hasSingleBean(JavaInfoContributor.class);
Map<String, Object> content = invokeContributor(context.getBean(JavaInfoContributor.class));
assertThat(content).containsKey("java");
assertThat(content.get("java")).isInstanceOf(JavaInfo.class);
});
}
private Map<String, Object> invokeContributor(InfoContributor contributor) {
@@ -169,21 +160,6 @@ class InfoContributorAutoConfigurationTests {
return builder.build().getDetails();
}
private void load(String... environment) {
load(null, environment);
}
private void load(Class<?> config, String... environment) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
if (config != null) {
context.register(config);
}
context.register(InfoContributorAutoConfiguration.class);
TestPropertyValues.of(environment).applyTo(context);
context.refresh();
this.context = context;
}
@Configuration(proxyBeanMethods = false)
static class GitPropertiesConfiguration {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2021-2021 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,10 +14,10 @@
* limitations under the License.
*/
package org.springframework.boot.actuate.info.java;
package org.springframework.boot.actuate.info;
import org.springframework.boot.actuate.info.Info.Builder;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.boot.info.JavaInfo;
/**
* An {@link InfoContributor} that exposes {@link JavaInfo}.

View File

@@ -1,59 +0,0 @@
/*
* Copyright 2021-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.info.java;
/**
* A simple DTO that holds information about the Java environment the application is
* running in.
*
* @author Jonatan Ivanov
* @since 2.6.0
*/
public class JavaInfo {
private final String vendor;
private final String version;
private final JreInfo runtime;
private final VmInfo vm;
public JavaInfo() {
this.vendor = System.getProperty("java.vendor");
this.version = System.getProperty("java.version");
this.runtime = new JreInfo();
this.vm = new VmInfo();
}
public String getVendor() {
return this.vendor;
}
public String getVersion() {
return this.version;
}
public JreInfo getRuntime() {
return this.runtime;
}
public VmInfo getVm() {
return this.vm;
}
}

View File

@@ -1,45 +0,0 @@
/*
* Copyright 2021-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.info.java;
/**
* A simple DTO that holds information about the JRE (Java Runtime Environment) the
* application is running in.
*
* @author Jonatan Ivanov
* @since 2.6.0
*/
public class JreInfo {
private final String name;
private final String version;
public JreInfo() {
this.name = System.getProperty("java.runtime.name");
this.version = System.getProperty("java.runtime.version");
}
public String getName() {
return this.name;
}
public String getVersion() {
return this.version;
}
}

View File

@@ -1,52 +0,0 @@
/*
* Copyright 2021-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.info.java;
/**
* A simple DTO that holds information about the JVM (Java Virtual Machine) the
* application is running in.
*
* @author Jonatan Ivanov
* @since 2.6.0
*/
public class VmInfo {
private final String name;
private final String vendor;
private final String version;
public VmInfo() {
this.name = System.getProperty("java.vm.name");
this.vendor = System.getProperty("java.vm.vendor");
this.version = System.getProperty("java.vm.version");
}
public String getName() {
return this.name;
}
public String getVendor() {
return this.vendor;
}
public String getVersion() {
return this.version;
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2021-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Classes for java info.
*/
package org.springframework.boot.actuate.info.java;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2021-2021 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,11 +14,11 @@
* limitations under the License.
*/
package org.springframework.boot.actuate.info.java;
package org.springframework.boot.actuate.info;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.info.Info;
import org.springframework.boot.info.JavaInfo;
import static org.assertj.core.api.Assertions.assertThat;
@@ -34,17 +34,8 @@ class JavaInfoContributorTests {
JavaInfoContributor javaInfoContributor = new JavaInfoContributor();
Info.Builder builder = new Info.Builder();
javaInfoContributor.contribute(builder);
assertThat(builder.build().getDetails().get("java")).isInstanceOf(JavaInfo.class);
JavaInfo javaInfo = (JavaInfo) builder.build().getDetails().get("java");
assertThat(javaInfo.getVendor()).isEqualTo(System.getProperty("java.vendor"));
assertThat(javaInfo.getVersion()).isEqualTo(System.getProperty("java.version"));
assertThat(javaInfo.getRuntime().getName()).isEqualTo(System.getProperty("java.runtime.name"));
assertThat(javaInfo.getRuntime().getVersion()).isEqualTo(System.getProperty("java.runtime.version"));
assertThat(javaInfo.getVm().getName()).isEqualTo(System.getProperty("java.vm.name"));
assertThat(javaInfo.getVm().getVendor()).isEqualTo(System.getProperty("java.vm.vendor"));
assertThat(javaInfo.getVm().getVersion()).isEqualTo(System.getProperty("java.vm.version"));
Info info = builder.build();
assertThat(info.getDetails().get("java")).isInstanceOf(JavaInfo.class);
}
}

View File

@@ -1157,6 +1157,9 @@ When appropriate, Spring auto-configures the following `InfoContributor` beans:
| {spring-boot-actuator-module-code}/info/BuildInfoContributor.java[`BuildInfoContributor`]
| Exposes build information if a `META-INF/build-info.properties` file is available.
| {spring-boot-actuator-module-code}/info/JavaInfoContributor.java[`JavaInfoContributor`]
| Exposes Java runtime information under the `java` key.
|===
TIP: You can disable them all by setting the configprop:management.info.defaults.enabled[] property.
@@ -1240,6 +1243,12 @@ See "<<howto#howto.build.generate-info,how to generate build information>>" for
[[actuator.endpoints.info.java-information]]
==== Java Information
The `info` endpoint publishes information about your Java runtime environment, see {spring-boot-module-api}/info/JavaInfo.html[`JavaInfo`] for more details.
[[actuator.endpoints.info.writing-custom-info-contributors]]
==== Writing Custom InfoContributors
To provide custom application information, you can register Spring beans that implement the {spring-boot-actuator-module-code}/info/InfoContributor.java[`InfoContributor`] interface.

View File

@@ -0,0 +1,114 @@
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.info;
/**
* Information about the Java environment the application is running in.
*
* @author Jonatan Ivanov
* @author Stephane Nicoll
* @since 2.6.0
*/
public class JavaInfo {
private final String vendor;
private final String version;
private final JavaRuntimeEnvironmentInfo runtime;
private final JavaVirtualMachineInfo jvm;
public JavaInfo() {
this.vendor = System.getProperty("java.vendor");
this.version = System.getProperty("java.version");
this.runtime = new JavaRuntimeEnvironmentInfo();
this.jvm = new JavaVirtualMachineInfo();
}
public String getVendor() {
return this.vendor;
}
public String getVersion() {
return this.version;
}
public JavaRuntimeEnvironmentInfo getRuntime() {
return this.runtime;
}
public JavaVirtualMachineInfo getJvm() {
return this.jvm;
}
/**
* Information about the Java Runtime Environment the application is running in.
*/
public static class JavaRuntimeEnvironmentInfo {
private final String name;
private final String version;
public JavaRuntimeEnvironmentInfo() {
this.name = System.getProperty("java.runtime.name");
this.version = System.getProperty("java.runtime.version");
}
public String getName() {
return this.name;
}
public String getVersion() {
return this.version;
}
}
/**
* Information about the Java Virtual Machine) the application is running in.
*/
public static class JavaVirtualMachineInfo {
private final String name;
private final String vendor;
private final String version;
public JavaVirtualMachineInfo() {
this.name = System.getProperty("java.vm.name");
this.vendor = System.getProperty("java.vm.vendor");
this.version = System.getProperty("java.vm.version");
}
public String getName() {
return this.name;
}
public String getVendor() {
return this.vendor;
}
public String getVersion() {
return this.version;
}
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.info;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link JavaInfo}.
*
* @author Jonatan Ivanov
* @author Stephane Nicoll
*/
class JavaInfoTests {
@Test
void javaInfoIsAvailable() {
JavaInfo javaInfo = new JavaInfo();
assertThat(javaInfo.getVendor()).isEqualTo(System.getProperty("java.vendor"));
assertThat(javaInfo.getVersion()).isEqualTo(System.getProperty("java.version"));
assertThat(javaInfo.getRuntime()).satisfies((jreInfo) -> {
assertThat(jreInfo.getName()).isEqualTo(System.getProperty("java.runtime.name"));
assertThat(jreInfo.getVersion()).isEqualTo(System.getProperty("java.runtime.version"));
});
assertThat(javaInfo.getJvm()).satisfies((jvmInfo) -> {
assertThat(jvmInfo.getName()).isEqualTo(System.getProperty("java.vm.name"));
assertThat(jvmInfo.getVendor()).isEqualTo(System.getProperty("java.vm.vendor"));
assertThat(jvmInfo.getVersion()).isEqualTo(System.getProperty("java.vm.version"));
});
}
}