From e3058d849b21f704c177306c1cc213cac8d387ba Mon Sep 17 00:00:00 2001 From: Lee JiWon Date: Fri, 8 May 2026 16:26:53 +0900 Subject: [PATCH 1/2] Fix self-referential parentId in MappingsEndpoint The mappings endpoint reported the context's own id as `parentId` instead of the parent context's id, preventing clients from reconstructing the context hierarchy from the response. Align with sibling endpoints (`BeansEndpoint`, `ConfigurationPropertiesReportEndpoint`, `ConditionsReportEndpoint`) which already use `parent.getId()`. See gh-50373 Signed-off-by: Lee JiWon --- .../web/mappings/MappingsEndpointTests.java | 65 +++++++++++++++++++ .../web/mappings/MappingsEndpoint.java | 2 +- 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 module/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/MappingsEndpointTests.java diff --git a/module/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/MappingsEndpointTests.java b/module/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/MappingsEndpointTests.java new file mode 100644 index 000000000000..1f1522e62ebe --- /dev/null +++ b/module/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/MappingsEndpointTests.java @@ -0,0 +1,65 @@ +/* + * Copyright 2012-present 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.web.mappings; + +import java.util.Collections; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.web.mappings.MappingsEndpoint.ApplicationMappingsDescriptor; +import org.springframework.boot.actuate.web.mappings.MappingsEndpoint.ContextMappingsDescriptor; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link MappingsEndpoint}. + * + * @author Lee JiWon + */ +class MappingsEndpointTests { + + @Test + void mappingsParentIdMatchesParentContextId() { + ApplicationContextRunner parentRunner = new ApplicationContextRunner(); + parentRunner.run((parent) -> new ApplicationContextRunner().withUserConfiguration(EndpointConfiguration.class) + .withParent(parent) + .run((child) -> { + ApplicationMappingsDescriptor result = child.getBean(MappingsEndpoint.class).mappings(); + ContextMappingsDescriptor parentDescriptor = result.getContexts().get(parent.getId()); + ContextMappingsDescriptor childDescriptor = result.getContexts().get(child.getId()); + assertThat(parentDescriptor).isNotNull(); + assertThat(parentDescriptor.getParentId()).isNull(); + assertThat(childDescriptor).isNotNull(); + assertThat(childDescriptor.getParentId()).isEqualTo(parent.getId()); + })); + } + + @Configuration(proxyBeanMethods = false) + static class EndpointConfiguration { + + @Bean + MappingsEndpoint mappingsEndpoint(ConfigurableApplicationContext context) { + return new MappingsEndpoint(Collections.emptyList(), context); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/MappingsEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/MappingsEndpoint.java index 3cc5c7deeb5b..062b66c68e9b 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/MappingsEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/MappingsEndpoint.java @@ -59,7 +59,7 @@ private ContextMappingsDescriptor mappingsForContext(ApplicationContext applicat this.descriptionProviders.forEach( (provider) -> mappings.put(provider.getMappingName(), provider.describeMappings(applicationContext))); return new ContextMappingsDescriptor(mappings, - (applicationContext.getParent() != null) ? applicationContext.getId() : null); + (applicationContext.getParent() != null) ? applicationContext.getParent().getId() : null); } /** From ff0580ebb436ba64b7d5453ef77023a58d5c5ab4 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Tue, 12 May 2026 11:58:44 -0700 Subject: [PATCH 2/2] Polish "Fix self-referential parentId in MappingsEndpoint" See gh-50373 --- .../boot/actuate/web/mappings/MappingsEndpoint.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/MappingsEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/MappingsEndpoint.java index 062b66c68e9b..119c5a4b7cf3 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/MappingsEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/MappingsEndpoint.java @@ -29,6 +29,7 @@ * {@link Endpoint @Endpoint} to expose HTTP request mappings. * * @author Andy Wilkinson + * @author Lee JiWon * @since 2.0.0 */ @Endpoint(id = "mappings") @@ -58,8 +59,8 @@ private ContextMappingsDescriptor mappingsForContext(ApplicationContext applicat Map mappings = new HashMap<>(); this.descriptionProviders.forEach( (provider) -> mappings.put(provider.getMappingName(), provider.describeMappings(applicationContext))); - return new ContextMappingsDescriptor(mappings, - (applicationContext.getParent() != null) ? applicationContext.getParent().getId() : null); + ApplicationContext parent = applicationContext.getParent(); + return new ContextMappingsDescriptor(mappings, (parent != null) ? parent.getId() : null); } /**