Allow management endpoints to express what http methods they support

Previously a management endpoint was either GET or POST. That requirement seems limited.
pull/132/head
Christian Dupuis 11 years ago
parent 845aeecbad
commit 405c9d5593

@ -19,17 +19,28 @@ package org.springframework.boot.actuate.endpoint;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
/**
* Abstract base for {@link Endpoint} implementations.
* <p>
* {@link Endpoint}s that support other {@link HttpMethod}s than {@link HttpMethod#GET}
* should override {@link #methods()} and provide a list of supported methods.
*
* @author Phillip Webb
* @author Christian Dupuis
*/
public abstract class AbstractEndpoint<T> implements Endpoint<T> {
private static final MediaType[] NO_MEDIA_TYPES = new MediaType[0];
protected static final HttpMethod[] NO_HTTP_METHOD = new HttpMethod[0];
protected static final HttpMethod[] GET_HTTP_METHOD = new HttpMethod[] { HttpMethod.GET };
protected static final HttpMethod[] POST_HTTP_METHOD = new HttpMethod[] { HttpMethod.POST };
@NotNull
@Pattern(regexp = "/[^/]*", message = "Path must start with /")
private String path;
@ -64,8 +75,12 @@ public abstract class AbstractEndpoint<T> implements Endpoint<T> {
}
@Override
public MediaType[] getProduces() {
public MediaType[] produces() {
return NO_MEDIA_TYPES;
}
@Override
public HttpMethod[] methods() {
return GET_HTTP_METHOD;
}
}

@ -1,27 +0,0 @@
/*
* Copyright 2012-2013 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
*
* http://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.endpoint;
/**
* Tagging interface used to indicate that {@link Endpoint} that performs some action.
* Allows mappings to refine the types of request supported.
*
* @author Phillip Webb
*/
public interface ActionEndpoint<T> extends Endpoint<T> {
}

@ -51,7 +51,7 @@ public class BeansEndpoint extends AbstractEndpoint<String> implements
}
@Override
public MediaType[] getProduces() {
public MediaType[] produces() {
return new MediaType[] { MediaType.APPLICATION_JSON };
}

@ -16,6 +16,7 @@
package org.springframework.boot.actuate.endpoint;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
/**
@ -24,6 +25,7 @@ import org.springframework.http.MediaType;
*
* @author Phillip Webb
* @author Dave Syer
* @author Christian Dupuis
*/
public interface Endpoint<T> {
@ -42,7 +44,12 @@ public interface Endpoint<T> {
/**
* Returns the {@link MediaType}s that this endpoint produces or {@code null}.
*/
MediaType[] getProduces();
MediaType[] produces();
/**
* Returns the {@link HttpMethod}s that this endpoint supports.
*/
HttpMethod[] methods();
/**
* Called to invoke the endpoint.

@ -26,15 +26,17 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpMethod;
/**
* {@link ActionEndpoint} to shutdown the {@link ApplicationContext}.
* {@link Endpoint} to shutdown the {@link ApplicationContext}.
*
* @author Dave Syer
* @author Christian Dupuis
*/
@ConfigurationProperties(name = "endpoints.shutdown", ignoreUnknownFields = false)
public class ShutdownEndpoint extends AbstractEndpoint<Map<String, Object>> implements
ApplicationContextAware, ActionEndpoint<Map<String, Object>> {
ApplicationContextAware {
private ConfigurableApplicationContext context;
@ -80,4 +82,9 @@ public class ShutdownEndpoint extends AbstractEndpoint<Map<String, Object>> impl
}
}
@Override
public HttpMethod[] methods() {
return POST_HTTP_METHOD;
}
}

@ -150,7 +150,7 @@ public final class EndpointHandlerAdapter implements HandlerAdapter {
private List<MediaType> getProducibleMediaTypes(Endpoint<?> endpoint,
Class<?> returnValueClass) {
MediaType[] mediaTypes = endpoint.getProduces();
MediaType[] mediaTypes = endpoint.produces();
if (mediaTypes != null && mediaTypes.length != 0) {
return Arrays.asList(mediaTypes);
}

@ -25,10 +25,10 @@ import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.actuate.endpoint.ActionEndpoint;
import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.http.HttpMethod;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerExecutionChain;
@ -37,10 +37,9 @@ import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;
/**
* {@link HandlerMapping} to map {@link Endpoint}s to URLs via {@link Endpoint#getPath()}.
* Standard {@link Endpoint}s are mapped to GET requests, {@link ActionEndpoint}s are
* mapped to POST requests.
*
* @author Phillip Webb
* @author Christian Dupuis
* @see EndpointHandlerAdapter
*/
public class EndpointHandlerMapping extends AbstractUrlHandlerMapping implements
@ -94,8 +93,9 @@ public class EndpointHandlerMapping extends AbstractUrlHandlerMapping implements
if (handler != null) {
Object endpoint = (handler instanceof HandlerExecutionChain ? ((HandlerExecutionChain) handler)
.getHandler() : handler);
String method = (endpoint instanceof ActionEndpoint<?> ? "POST" : "GET");
if (request.getMethod().equals(method)) {
HttpMethod method = HttpMethod.valueOf(request.getMethod());
if (endpoint instanceof Endpoint
&& supportsMethod(((Endpoint<?>) endpoint).methods(), method)) {
return endpoint;
}
}
@ -131,4 +131,16 @@ public class EndpointHandlerMapping extends AbstractUrlHandlerMapping implements
public List<Endpoint<?>> getEndpoints() {
return Collections.unmodifiableList(this.endpoints);
}
private boolean supportsMethod(HttpMethod[] supportedMethods,
HttpMethod requestedMethod) {
Assert.notNull(supportedMethods, "SupportMethods must not be null");
Assert.notNull(supportedMethods, "RequestedMethod must not be null");
for (HttpMethod supportedMethod : supportedMethods) {
if (supportedMethod.equals(requestedMethod)) {
return true;
}
}
return false;
}
}

Loading…
Cancel
Save