commit
c032e1f872
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.springframework.boot.logging.structured;
|
||||
|
||||
import org.springframework.boot.context.properties.bind.BindableRuntimeHintsRegistrar;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.boot.json.JsonWriter;
|
||||
import org.springframework.boot.json.JsonWriter.Members;
|
||||
|
@ -91,4 +92,12 @@ public record ElasticCommonSchemaProperties(Service service) {
|
|||
|
||||
}
|
||||
|
||||
static class ElasticCommonSchemaPropertiesRuntimeHints extends BindableRuntimeHintsRegistrar {
|
||||
|
||||
ElasticCommonSchemaPropertiesRuntimeHints() {
|
||||
super(ElasticCommonSchemaProperties.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.springframework.boot.logging.structured;
|
||||
|
||||
import org.springframework.boot.context.properties.bind.BindableRuntimeHintsRegistrar;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.boot.json.JsonWriter;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
@ -91,4 +92,12 @@ public record GraylogExtendedLogFormatProperties(String host, Service service) {
|
|||
|
||||
}
|
||||
|
||||
static class GraylogExtendedLogFormatPropertiesRuntimeHints extends BindableRuntimeHintsRegistrar {
|
||||
|
||||
GraylogExtendedLogFormatPropertiesRuntimeHints() {
|
||||
super(GraylogExtendedLogFormatProperties.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright 2012-2025 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.logging.structured;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.aot.generate.GenerationContext;
|
||||
import org.springframework.aot.hint.MemberCategory;
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotContribution;
|
||||
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor;
|
||||
import org.springframework.beans.factory.aot.BeanFactoryInitializationCode;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* {@link BeanFactoryInitializationAotProcessor} that registers {@link RuntimeHints} for
|
||||
* {@link StructuredLoggingJsonPropertiesJsonMembersCustomizer}.
|
||||
*
|
||||
* @author Dmytro Nosan
|
||||
*/
|
||||
class StructuredLoggingJsonMembersCustomizerBeanFactoryInitializationAotProcessor
|
||||
implements BeanFactoryInitializationAotProcessor {
|
||||
|
||||
private static final String ENVIRONMENT_BEAN_NAME = "environment";
|
||||
|
||||
@Override
|
||||
public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {
|
||||
Environment environment = beanFactory.getBean(ENVIRONMENT_BEAN_NAME, Environment.class);
|
||||
return Optional.ofNullable(StructuredLoggingJsonProperties.get(environment))
|
||||
.map(StructuredLoggingJsonProperties::customizer)
|
||||
.map(AotContribution::new)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private static final class AotContribution implements BeanFactoryInitializationAotContribution {
|
||||
|
||||
private final Class<? extends StructuredLoggingJsonMembersCustomizer<?>> customizer;
|
||||
|
||||
private AotContribution(Class<? extends StructuredLoggingJsonMembersCustomizer<?>> customizer) {
|
||||
this.customizer = customizer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(GenerationContext generationContext,
|
||||
BeanFactoryInitializationCode beanFactoryInitializationCode) {
|
||||
generationContext.getRuntimeHints()
|
||||
.reflection()
|
||||
.registerType(this.customizer, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 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,6 +19,7 @@ package org.springframework.boot.logging.structured;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.boot.context.properties.bind.BindableRuntimeHintsRegistrar;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
|
@ -42,4 +43,12 @@ record StructuredLoggingJsonProperties(Set<String> include, Set<String> exclude,
|
|||
.orElse(null);
|
||||
}
|
||||
|
||||
static class StructuredLoggingJsonPropertiesRuntimeHints extends BindableRuntimeHintsRegistrar {
|
||||
|
||||
StructuredLoggingJsonPropertiesRuntimeHints() {
|
||||
super(StructuredLoggingJsonProperties.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,13 +10,17 @@ org.springframework.boot.jdbc.DataSourceBuilderRuntimeHints,\
|
|||
org.springframework.boot.json.JacksonRuntimeHints,\
|
||||
org.springframework.boot.logging.java.JavaLoggingSystemRuntimeHints,\
|
||||
org.springframework.boot.logging.logback.LogbackRuntimeHints,\
|
||||
org.springframework.boot.logging.structured.ElasticCommonSchemaProperties.ElasticCommonSchemaPropertiesRuntimeHints,\
|
||||
org.springframework.boot.logging.structured.GraylogExtendedLogFormatProperties.GraylogExtendedLogFormatPropertiesRuntimeHints,\
|
||||
org.springframework.boot.logging.structured.StructuredLoggingJsonProperties.StructuredLoggingJsonPropertiesRuntimeHints,\
|
||||
org.springframework.boot.web.embedded.undertow.UndertowWebServer.UndertowWebServerRuntimeHints,\
|
||||
org.springframework.boot.web.server.MimeMappings.MimeMappingsRuntimeHints
|
||||
|
||||
org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor=\
|
||||
org.springframework.boot.context.properties.ConfigurationPropertiesBeanFactoryInitializationAotProcessor,\
|
||||
org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.EnvironmentBeanFactoryInitializationAotProcessor,\
|
||||
org.springframework.boot.jackson.JsonComponentModule.JsonComponentBeanFactoryInitializationAotProcessor
|
||||
org.springframework.boot.jackson.JsonComponentModule.JsonComponentBeanFactoryInitializationAotProcessor,\
|
||||
org.springframework.boot.logging.structured.StructuredLoggingJsonMembersCustomizerBeanFactoryInitializationAotProcessor
|
||||
|
||||
org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\
|
||||
org.springframework.boot.context.properties.ConfigurationPropertiesBeanRegistrationAotProcessor,\
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
|
@ -18,7 +18,12 @@ package org.springframework.boot.logging.structured;
|
|||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.RuntimeHintsRegistrar;
|
||||
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
|
||||
import org.springframework.beans.factory.aot.AotServices;
|
||||
import org.springframework.boot.json.JsonWriter;
|
||||
import org.springframework.boot.logging.structured.ElasticCommonSchemaProperties.ElasticCommonSchemaPropertiesRuntimeHints;
|
||||
import org.springframework.boot.logging.structured.ElasticCommonSchemaProperties.Service;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
|
@ -77,4 +82,24 @@ class ElasticCommonSchemaPropertiesTests {
|
|||
+ "\"service.environment\":\"prod\",\"service.node.name\":\"boot\"}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRegisterRuntimeHints() throws Exception {
|
||||
RuntimeHints hints = new RuntimeHints();
|
||||
new ElasticCommonSchemaPropertiesRuntimeHints().registerHints(hints, getClass().getClassLoader());
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(ElasticCommonSchemaProperties.class)).accepts(hints);
|
||||
assertThat(RuntimeHintsPredicates.reflection()
|
||||
.onConstructor(ElasticCommonSchemaProperties.class.getConstructor(Service.class))
|
||||
.invoke()).accepts(hints);
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(Service.class)).accepts(hints);
|
||||
assertThat(RuntimeHintsPredicates.reflection()
|
||||
.onConstructor(Service.class.getConstructor(String.class, String.class, String.class, String.class))
|
||||
.invoke()).accepts(hints);
|
||||
}
|
||||
|
||||
@Test
|
||||
void elasticCommonSchemaPropertiesRuntimeHintsIsRegistered() {
|
||||
assertThat(AotServices.factories().load(RuntimeHintsRegistrar.class))
|
||||
.anyMatch(ElasticCommonSchemaPropertiesRuntimeHints.class::isInstance);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,12 @@ package org.springframework.boot.logging.structured;
|
|||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.RuntimeHintsRegistrar;
|
||||
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
|
||||
import org.springframework.beans.factory.aot.AotServices;
|
||||
import org.springframework.boot.json.JsonWriter;
|
||||
import org.springframework.boot.logging.structured.GraylogExtendedLogFormatProperties.GraylogExtendedLogFormatPropertiesRuntimeHints;
|
||||
import org.springframework.boot.logging.structured.GraylogExtendedLogFormatProperties.Service;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
|
@ -98,4 +103,24 @@ class GraylogExtendedLogFormatPropertiesTests {
|
|||
assertThat(writer.writeToString(properties)).isEqualTo("{\"host\":\"spring\",\"_service_version\":\"1.2.3\"}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRegisterRuntimeHints() throws Exception {
|
||||
RuntimeHints hints = new RuntimeHints();
|
||||
new GraylogExtendedLogFormatPropertiesRuntimeHints().registerHints(hints, getClass().getClassLoader());
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(GraylogExtendedLogFormatProperties.class)).accepts(hints);
|
||||
assertThat(RuntimeHintsPredicates.reflection()
|
||||
.onConstructor(GraylogExtendedLogFormatProperties.class.getConstructor(String.class, Service.class))
|
||||
.invoke()).accepts(hints);
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(Service.class)).accepts(hints);
|
||||
assertThat(RuntimeHintsPredicates.reflection()
|
||||
.onConstructor(GraylogExtendedLogFormatProperties.Service.class.getConstructor(String.class))
|
||||
.invoke()).accepts(hints);
|
||||
}
|
||||
|
||||
@Test
|
||||
void graylogExtendedLogFormatPropertiesRuntimeHintsIsRegistered() {
|
||||
assertThat(AotServices.factories().load(RuntimeHintsRegistrar.class))
|
||||
.anyMatch(GraylogExtendedLogFormatPropertiesRuntimeHints.class::isInstance);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright 2012-2025 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.logging.structured;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aot.hint.MemberCategory;
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
|
||||
import org.springframework.aot.test.generate.TestGenerationContext;
|
||||
import org.springframework.beans.factory.aot.AotServices;
|
||||
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotContribution;
|
||||
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor;
|
||||
import org.springframework.boot.json.JsonWriter.Members;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for
|
||||
* {@link StructuredLoggingJsonMembersCustomizerBeanFactoryInitializationAotProcessor}.
|
||||
*
|
||||
* @author Dmytro Nosan
|
||||
*/
|
||||
class StructuredLoggingJsonMembersCustomizerBeanFactoryInitializationAotProcessorTests {
|
||||
|
||||
@Test
|
||||
void structuredLoggingJsonMembersCustomizerBeanFactoryInitializationAotProcessorIsRegistered() {
|
||||
assertThat(AotServices.factories().load(BeanFactoryInitializationAotProcessor.class))
|
||||
.anyMatch(StructuredLoggingJsonMembersCustomizerBeanFactoryInitializationAotProcessor.class::isInstance);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRegisterStructuredLoggingJsonMembersCustomizerRuntimeHints() {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
environment.setProperty("logging.structured.json.customizer", TestCustomizer.class.getName());
|
||||
|
||||
BeanFactoryInitializationAotContribution contribution = getContribution(environment);
|
||||
assertThat(contribution).isNotNull();
|
||||
|
||||
RuntimeHints hints = getRuntimeHints(contribution);
|
||||
assertThat(RuntimeHintsPredicates.reflection()
|
||||
.onType(TestCustomizer.class)
|
||||
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS))
|
||||
.accepts(hints);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotRegisterStructuredLoggingJsonMembersCustomizerRuntimeHints() {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
BeanFactoryInitializationAotContribution contribution = getContribution(environment);
|
||||
assertThat(contribution).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotRegisterStructuredLoggingJsonMembersCustomizerRuntimeHintsWhenCustomizerIsNotSet() {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
environment.setProperty("logging.structured.json.exclude", "something");
|
||||
BeanFactoryInitializationAotContribution contribution = getContribution(environment);
|
||||
assertThat(contribution).isNull();
|
||||
}
|
||||
|
||||
private BeanFactoryInitializationAotContribution getContribution(ConfigurableEnvironment environment) {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
|
||||
context.setEnvironment(environment);
|
||||
context.refresh();
|
||||
return new StructuredLoggingJsonMembersCustomizerBeanFactoryInitializationAotProcessor()
|
||||
.processAheadOfTime(context.getBeanFactory());
|
||||
}
|
||||
}
|
||||
|
||||
private RuntimeHints getRuntimeHints(BeanFactoryInitializationAotContribution contribution) {
|
||||
TestGenerationContext generationContext = new TestGenerationContext();
|
||||
contribution.applyTo(generationContext, null);
|
||||
return generationContext.getRuntimeHints();
|
||||
}
|
||||
|
||||
static class TestCustomizer implements StructuredLoggingJsonMembersCustomizer<String> {
|
||||
|
||||
@Override
|
||||
public void customize(Members<String> members) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
|
@ -21,7 +21,12 @@ import java.util.Set;
|
|||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.RuntimeHintsRegistrar;
|
||||
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
|
||||
import org.springframework.beans.factory.aot.AotServices;
|
||||
import org.springframework.boot.json.JsonWriter.Members;
|
||||
import org.springframework.boot.logging.structured.StructuredLoggingJsonProperties.StructuredLoggingJsonPropertiesRuntimeHints;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
@ -52,6 +57,23 @@ class StructuredLoggingJsonPropertiesTests {
|
|||
StructuredLoggingJsonProperties.get(environment);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRegisterRuntimeHints() throws Exception {
|
||||
RuntimeHints hints = new RuntimeHints();
|
||||
new StructuredLoggingJsonPropertiesRuntimeHints().registerHints(hints, getClass().getClassLoader());
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(StructuredLoggingJsonProperties.class)).accepts(hints);
|
||||
assertThat(RuntimeHintsPredicates.reflection()
|
||||
.onConstructor(StructuredLoggingJsonProperties.class.getDeclaredConstructor(Set.class, Set.class, Map.class,
|
||||
Map.class, Class.class))
|
||||
.invoke()).accepts(hints);
|
||||
}
|
||||
|
||||
@Test
|
||||
void structuredLoggingJsonPropertiesRuntimeHintsRuntimeHintsIsRegistered() {
|
||||
assertThat(AotServices.factories().load(RuntimeHintsRegistrar.class))
|
||||
.anyMatch(StructuredLoggingJsonPropertiesRuntimeHints.class::isInstance);
|
||||
}
|
||||
|
||||
static class TestCustomizer implements StructuredLoggingJsonMembersCustomizer<String> {
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue