From fc87da7ef30aa8737d901faf9cdaea83b9e6ca85 Mon Sep 17 00:00:00 2001 From: Jonatan Ivanov Date: Fri, 24 Sep 2021 15:33:14 -0700 Subject: [PATCH 1/2] Add Java InfoContributor See gh-28136 --- .../InfoContributorAutoConfiguration.java | 9 +++ ...InfoContributorAutoConfigurationTests.java | 36 ++++++++++- .../boot/actuate/info/java/JavaInfo.java | 59 +++++++++++++++++++ .../info/java/JavaInfoContributor.java | 41 +++++++++++++ .../boot/actuate/info/java/JreInfo.java | 45 ++++++++++++++ .../boot/actuate/info/java/VmInfo.java | 52 ++++++++++++++++ .../boot/actuate/info/java/package-info.java | 20 +++++++ .../info/java/JavaInfoContributorTests.java | 50 ++++++++++++++++ 8 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JavaInfo.java create mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JavaInfoContributor.java create mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JreInfo.java create mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/VmInfo.java create mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/package-info.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/java/JavaInfoContributorTests.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfiguration.java index 92ffca446b..f50f73f56c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfiguration.java @@ -20,6 +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.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -40,6 +41,7 @@ import org.springframework.core.env.ConfigurableEnvironment; * * @author Meang Akira Tanaka * @author Stephane Nicoll + * @author Jonatan Ivanov * @since 2.0.0 */ @Configuration(proxyBeanMethods = false) @@ -77,4 +79,11 @@ public class InfoContributorAutoConfiguration { return new BuildInfoContributor(buildProperties); } + @Bean + @ConditionalOnEnabledInfoContributor("java") + @Order(DEFAULT_ORDER) + public InfoContributor javaInfoContributor() { + return new JavaInfoContributor(); + } + } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfigurationTests.java index efa37a54b0..40b7390d40 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfigurationTests.java @@ -23,9 +23,12 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; 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.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.info.BuildProperties; import org.springframework.boot.info.GitProperties; import org.springframework.boot.test.util.TestPropertyValues; @@ -39,6 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for {@link InfoContributorAutoConfiguration}. * * @author Stephane Nicoll + * @author Jonatan Ivanov */ class InfoContributorAutoConfigurationTests { @@ -55,7 +59,26 @@ class InfoContributorAutoConfigurationTests { void disableEnvContributor() { load("management.info.env.enabled:false"); Map beans = this.context.getBeansOfType(InfoContributor.class); - assertThat(beans).hasSize(0); + assertThat(beans).extractingFromEntries(Map.Entry::getValue).allSatisfy( + (infoContributor) -> assertThat(infoContributor).isNotInstanceOf(EnvironmentInfoContributor.class)); + } + + @Test + void disableJavaContributor() { + load("management.info.java.enabled:false"); + Map beans = this.context.getBeansOfType(InfoContributor.class); + assertThat(beans).extractingFromEntries(Map.Entry::getValue).allSatisfy( + (infoContributor) -> assertThat(infoContributor).isNotInstanceOf(JavaInfoContributor.class)); + } + + @Test + void defaultInfoContributorsEnabled() { + load(); + Map 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)); } @Test @@ -129,6 +152,17 @@ class InfoContributorAutoConfigurationTests { .isSameAs(this.context.getBean("customBuildInfoContributor")); } + @Test + void javaInfoContributor() { + load(); + Map beans = this.context.getBeansOfType(InfoContributor.class); + assertThat(beans).containsKeys("javaInfoContributor"); + Map content = invokeContributor( + this.context.getBean("javaInfoContributor", InfoContributor.class)); + Object javaInfo = content.get("java"); + assertThat(javaInfo).isInstanceOf(JavaInfo.class); + } + private Map invokeContributor(InfoContributor contributor) { Info.Builder builder = new Info.Builder(); contributor.contribute(builder); diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JavaInfo.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JavaInfo.java new file mode 100644 index 0000000000..b9898f155b --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JavaInfo.java @@ -0,0 +1,59 @@ +/* + * 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; + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JavaInfoContributor.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JavaInfoContributor.java new file mode 100644 index 0000000000..5c44d9380c --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JavaInfoContributor.java @@ -0,0 +1,41 @@ +/* + * 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; + +import org.springframework.boot.actuate.info.Info.Builder; +import org.springframework.boot.actuate.info.InfoContributor; + +/** + * An {@link InfoContributor} that exposes {@link JavaInfo}. + * + * @author Jonatan Ivanov + * @since 2.6.0 + */ +public class JavaInfoContributor implements InfoContributor { + + private final JavaInfo javaInfo; + + public JavaInfoContributor() { + this.javaInfo = new JavaInfo(); + } + + @Override + public void contribute(Builder builder) { + builder.withDetail("java", this.javaInfo); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JreInfo.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JreInfo.java new file mode 100644 index 0000000000..1f8dd81320 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JreInfo.java @@ -0,0 +1,45 @@ +/* + * 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; + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/VmInfo.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/VmInfo.java new file mode 100644 index 0000000000..76be01f4c3 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/VmInfo.java @@ -0,0 +1,52 @@ +/* + * 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; + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/package-info.java new file mode 100644 index 0000000000..3d53a37834 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/package-info.java @@ -0,0 +1,20 @@ +/* + * 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; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/java/JavaInfoContributorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/java/JavaInfoContributorTests.java new file mode 100644 index 0000000000..f17638817c --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/java/JavaInfoContributorTests.java @@ -0,0 +1,50 @@ +/* + * 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; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.info.Info; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link JavaInfoContributor} + * + * @author Jonatan Ivanov + */ +class JavaInfoContributorTests { + + @Test + void javaInfoShouldBeAdded() { + 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")); + } + +} From 5d17257a525e1455835219a1a420e3b520b36805 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 1 Oct 2021 15:42:59 +0200 Subject: [PATCH 2/2] Polish "Add Java InfoContributor" See gh-28136 --- .../InfoContributorAutoConfiguration.java | 6 +- ...InfoContributorAutoConfigurationTests.java | 156 ++++++++---------- .../info/{java => }/JavaInfoContributor.java | 6 +- .../boot/actuate/info/java/JavaInfo.java | 59 ------- .../boot/actuate/info/java/JreInfo.java | 45 ----- .../boot/actuate/info/java/VmInfo.java | 52 ------ .../boot/actuate/info/java/package-info.java | 20 --- .../{java => }/JavaInfoContributorTests.java | 19 +-- .../src/docs/asciidoc/actuator/endpoints.adoc | 9 + .../springframework/boot/info/JavaInfo.java | 114 +++++++++++++ .../boot/info/JavaInfoTests.java | 47 ++++++ 11 files changed, 247 insertions(+), 286 deletions(-) rename spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/{java => }/JavaInfoContributor.java (85%) delete mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JavaInfo.java delete mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JreInfo.java delete mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/VmInfo.java delete mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/package-info.java rename spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/{java => }/JavaInfoContributorTests.java (50%) create mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/info/JavaInfo.java create mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/JavaInfoTests.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfiguration.java index f50f73f56c..cde1f0cf84 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfiguration.java @@ -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(); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfigurationTests.java index 40b7390d40..e4001ed7fb 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfigurationTests.java @@ -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 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 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 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 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 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 beans = this.context.getBeansOfType(InfoContributor.class); - assertThat(beans).containsKeys("gitInfoContributor"); - Map content = invokeContributor( - this.context.getBean("gitInfoContributor", InfoContributor.class)); - Object git = content.get("git"); - assertThat(git).isInstanceOf(Map.class); - Map gitInfo = (Map) git; - assertThat(gitInfo).containsOnlyKeys("branch", "commit"); + this.contextRunner.withUserConfiguration(GitPropertiesConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(GitInfoContributor.class); + Map content = invokeContributor(context.getBean(GitInfoContributor.class)); + Object git = content.get("git"); + assertThat(git).isInstanceOf(Map.class); + Map gitInfo = (Map) git; + assertThat(gitInfo).containsOnlyKeys("branch", "commit"); + }); } @SuppressWarnings("unchecked") @Test void gitPropertiesFullMode() { - load(GitPropertiesConfiguration.class, "management.info.git.mode=full"); - Map content = invokeContributor( - this.context.getBean("gitInfoContributor", InfoContributor.class)); - Object git = content.get("git"); - assertThat(git).isInstanceOf(Map.class); - Map gitInfo = (Map) 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 content = invokeContributor(context.getBean(GitInfoContributor.class)); + Object git = content.get("git"); + assertThat(git).isInstanceOf(Map.class); + Map gitInfo = (Map) 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 beans = this.context.getBeansOfType(InfoContributor.class); - assertThat(beans).containsKeys("buildInfoContributor"); - Map content = invokeContributor( - this.context.getBean("buildInfoContributor", InfoContributor.class)); - Object build = content.get("build"); - assertThat(build).isInstanceOf(Map.class); - Map buildInfo = (Map) 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 content = invokeContributor(context.getBean(BuildInfoContributor.class)); + Object build = content.get("build"); + assertThat(build).isInstanceOf(Map.class); + Map buildInfo = (Map) 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 beans = this.context.getBeansOfType(InfoContributor.class); - assertThat(beans).containsKeys("javaInfoContributor"); - Map 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 content = invokeContributor(context.getBean(JavaInfoContributor.class)); + assertThat(content).containsKey("java"); + assertThat(content.get("java")).isInstanceOf(JavaInfo.class); + }); } private Map 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 { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JavaInfoContributor.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/JavaInfoContributor.java similarity index 85% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JavaInfoContributor.java rename to spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/JavaInfoContributor.java index 5c44d9380c..480f05ff3e 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JavaInfoContributor.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/JavaInfoContributor.java @@ -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}. diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JavaInfo.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JavaInfo.java deleted file mode 100644 index b9898f155b..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JavaInfo.java +++ /dev/null @@ -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; - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JreInfo.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JreInfo.java deleted file mode 100644 index 1f8dd81320..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/JreInfo.java +++ /dev/null @@ -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; - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/VmInfo.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/VmInfo.java deleted file mode 100644 index 76be01f4c3..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/VmInfo.java +++ /dev/null @@ -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; - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/package-info.java deleted file mode 100644 index 3d53a37834..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/java/package-info.java +++ /dev/null @@ -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; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/java/JavaInfoContributorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/JavaInfoContributorTests.java similarity index 50% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/java/JavaInfoContributorTests.java rename to spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/JavaInfoContributorTests.java index f17638817c..f431ccd90e 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/java/JavaInfoContributorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/JavaInfoContributorTests.java @@ -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); } } diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/endpoints.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/endpoints.adoc index 488b212cfd..b193560506 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/endpoints.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/endpoints.adoc @@ -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 "<>" 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. diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/info/JavaInfo.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/info/JavaInfo.java new file mode 100644 index 0000000000..75851490f6 --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/info/JavaInfo.java @@ -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; + } + + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/JavaInfoTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/JavaInfoTests.java new file mode 100644 index 0000000000..421809c563 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/JavaInfoTests.java @@ -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")); + }); + } + +}