Improve EndpointHandlerMapping subclassing support
Update EndpointHandlerMapping so that it can be subclasses easily. Subclasses can override the `path` that is used to map the endpoint, allowing different mapping strategies to be used. See gh-7108
This commit is contained in:
		
							parent
							
								
									0be8a30276
								
							
						
					
					
						commit
						7352d8e303
					
				| 
						 | 
				
			
			@ -27,6 +27,7 @@ import java.util.Set;
 | 
			
		|||
import org.springframework.boot.actuate.endpoint.Endpoint;
 | 
			
		||||
import org.springframework.context.ApplicationContext;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
import org.springframework.util.ObjectUtils;
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
import org.springframework.web.cors.CorsConfiguration;
 | 
			
		||||
import org.springframework.web.servlet.HandlerMapping;
 | 
			
		||||
| 
						 | 
				
			
			@ -114,31 +115,42 @@ public class EndpointHandlerMapping extends RequestMappingHandlerMapping {
 | 
			
		|||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		String[] patterns = getPatterns(handler, mapping);
 | 
			
		||||
		super.registerHandlerMethod(handler, method, withNewPatterns(mapping, patterns));
 | 
			
		||||
		if (!ObjectUtils.isEmpty(patterns)) {
 | 
			
		||||
			super.registerHandlerMethod(handler, method,
 | 
			
		||||
					withNewPatterns(mapping, patterns));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private String[] getPatterns(Object handler, RequestMappingInfo mapping) {
 | 
			
		||||
		String path = getPath(handler);
 | 
			
		||||
		String prefix = StringUtils.hasText(this.prefix) ? this.prefix + path : path;
 | 
			
		||||
		Set<String> defaultPatterns = mapping.getPatternsCondition().getPatterns();
 | 
			
		||||
		if (defaultPatterns.isEmpty()) {
 | 
			
		||||
			return new String[] { prefix, prefix + ".json" };
 | 
			
		||||
		}
 | 
			
		||||
		List<String> patterns = new ArrayList<String>(defaultPatterns);
 | 
			
		||||
		for (int i = 0; i < patterns.size(); i++) {
 | 
			
		||||
			patterns.set(i, prefix + patterns.get(i));
 | 
			
		||||
		}
 | 
			
		||||
		return patterns.toArray(new String[patterns.size()]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private String getPath(Object handler) {
 | 
			
		||||
		if (handler instanceof String) {
 | 
			
		||||
			handler = getApplicationContext().getBean((String) handler);
 | 
			
		||||
		}
 | 
			
		||||
		if (handler instanceof MvcEndpoint) {
 | 
			
		||||
			return ((MvcEndpoint) handler).getPath();
 | 
			
		||||
		Assert.state(handler instanceof MvcEndpoint, "Only MvcEndpoints are supported");
 | 
			
		||||
		String path = getPath((MvcEndpoint) handler);
 | 
			
		||||
		return (path == null ? null : getEndpointPatterns(path, mapping));
 | 
			
		||||
	}
 | 
			
		||||
		return "";
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the path that should be used to map the given {@link MvcEndpoint}.
 | 
			
		||||
	 * @param endpoint the endpoint to map
 | 
			
		||||
	 * @return the path to use for the endpoint or {@code null} if no mapping is required
 | 
			
		||||
	 */
 | 
			
		||||
	protected String getPath(MvcEndpoint endpoint) {
 | 
			
		||||
		return endpoint.getPath();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private String[] getEndpointPatterns(String path, RequestMappingInfo mapping) {
 | 
			
		||||
		String patternPrefix = StringUtils.hasText(this.prefix) ? this.prefix + path
 | 
			
		||||
				: path;
 | 
			
		||||
		Set<String> defaultPatterns = mapping.getPatternsCondition().getPatterns();
 | 
			
		||||
		if (defaultPatterns.isEmpty()) {
 | 
			
		||||
			return new String[] { patternPrefix, patternPrefix + ".json" };
 | 
			
		||||
		}
 | 
			
		||||
		List<String> patterns = new ArrayList<String>(defaultPatterns);
 | 
			
		||||
		for (int i = 0; i < patterns.size(); i++) {
 | 
			
		||||
			patterns.set(i, patternPrefix + patterns.get(i));
 | 
			
		||||
		}
 | 
			
		||||
		return patterns.toArray(new String[patterns.size()]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private RequestMappingInfo withNewPatterns(RequestMappingInfo mapping,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@ package org.springframework.boot.actuate.endpoint.mvc;
 | 
			
		|||
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
import org.junit.Before;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
| 
						 | 
				
			
			@ -145,6 +146,19 @@ public class EndpointHandlerMappingTests {
 | 
			
		|||
		assertThat(mapping.getEndpoints(TestMvcEndpoint.class)).containsExactly(endpoint);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void pathNotMappedWhenGetPathReturnsNull() throws Exception {
 | 
			
		||||
		TestMvcEndpoint endpoint = new TestMvcEndpoint(new TestEndpoint("a"));
 | 
			
		||||
		TestActionEndpoint other = new TestActionEndpoint(new TestEndpoint("b"));
 | 
			
		||||
		EndpointHandlerMapping mapping = new TestEndpointHandlerMapping(
 | 
			
		||||
				Arrays.asList(endpoint, other));
 | 
			
		||||
		mapping.setApplicationContext(this.context);
 | 
			
		||||
		mapping.afterPropertiesSet();
 | 
			
		||||
		assertThat(mapping.getHandlerMethods()).hasSize(1);
 | 
			
		||||
		assertThat(mapping.getHandler(request("GET", "/a"))).isNull();
 | 
			
		||||
		assertThat(mapping.getHandler(request("POST", "/b"))).isNotNull();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private MockHttpServletRequest request(String method, String requestURI) {
 | 
			
		||||
		return new MockHttpServletRequest(method, requestURI);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -184,4 +198,20 @@ public class EndpointHandlerMappingTests {
 | 
			
		|||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static class TestEndpointHandlerMapping extends EndpointHandlerMapping {
 | 
			
		||||
 | 
			
		||||
		TestEndpointHandlerMapping(Collection<? extends MvcEndpoint> endpoints) {
 | 
			
		||||
			super(endpoints);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		protected String getPath(MvcEndpoint endpoint) {
 | 
			
		||||
			if (endpoint instanceof TestActionEndpoint) {
 | 
			
		||||
				return super.getPath(endpoint);
 | 
			
		||||
			}
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue