This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push: new ed47a51 CAMEL-11598: camel-spring-boot - actuator endpoints - Make it read-only by default ed47a51 is described below commit ed47a5160c2136ff09eb591e387bbebdb8c41afe Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Mon Feb 26 15:21:48 2018 +0100 CAMEL-11598: camel-spring-boot - actuator endpoints - Make it read-only by default --- .../actuate/endpoint/AbstractCamelMvcEndpoint.java | 39 ++++++++++++++++++++++ .../actuate/endpoint/CamelRoutesMvcEndpoint.java | 10 +++--- .../additional-spring-configuration-metadata.json | 6 ++++ .../endpoint/CamelRoutesMvcEndpointTest.java | 15 ++++++++- .../src/main/resources/application.properties | 3 ++ 5 files changed, 67 insertions(+), 6 deletions(-) diff --git a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/AbstractCamelMvcEndpoint.java b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/AbstractCamelMvcEndpoint.java index 991c508..9f937a0 100644 --- a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/AbstractCamelMvcEndpoint.java +++ b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/AbstractCamelMvcEndpoint.java @@ -16,6 +16,8 @@ */ package org.apache.camel.spring.boot.actuate.endpoint; +import java.util.Collections; +import java.util.Map; import java.util.function.Function; import java.util.function.Supplier; @@ -23,13 +25,22 @@ import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter; import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ResponseStatus; /** * Adapter to expose {@link T} as an {@link MvcEndpoint}. */ abstract class AbstractCamelMvcEndpoint<T extends Endpoint> extends EndpointMvcAdapter { + /** + * A {@link ResponseEntity} returned for forbidden operations (such as trying to stop a route). + */ + private static final ResponseEntity<Map<String, String>> FORBIDDEN_RESPONSE = new ResponseEntity<Map<String, String>>( + Collections.singletonMap("message", "This operation is forbidden"), + HttpStatus.FORBIDDEN); + private final T delegate; + private boolean readOnly = true; protected AbstractCamelMvcEndpoint(String path, T delegate) { super(delegate); @@ -38,10 +49,27 @@ abstract class AbstractCamelMvcEndpoint<T extends Endpoint> extends EndpointMvcA setPath(path); } + /** + * Returns the response that should be returned when the operation is forbidden. + * @return The response to be returned when the operation is disabled + */ + protected ResponseEntity<?> getForbiddenResponse() { + return FORBIDDEN_RESPONSE; + } + + public boolean isReadOnly() { + return readOnly; + } + + public void setReadOnly(boolean readOnly) { + this.readOnly = readOnly; + } + // ******************************************** // Helpers // ******************************************** + protected T delegate() { return this.delegate; } @@ -62,6 +90,17 @@ abstract class AbstractCamelMvcEndpoint<T extends Endpoint> extends EndpointMvcA return supplier.apply(delegate); } + protected Object doIfEnabledAndNotReadOnly(Supplier<Object> supplier) { + if (!delegate.isEnabled()) { + return getDisabledResponse(); + } + if (isReadOnly()) { + return getForbiddenResponse(); + } + + return supplier.get(); + } + @SuppressWarnings("serial") @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) public static class GenericException extends RuntimeException { diff --git a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/CamelRoutesMvcEndpoint.java b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/CamelRoutesMvcEndpoint.java index ae1a11b..5e852be 100644 --- a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/CamelRoutesMvcEndpoint.java +++ b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/CamelRoutesMvcEndpoint.java @@ -101,7 +101,7 @@ public class CamelRoutesMvcEndpoint extends AbstractCamelMvcEndpoint<CamelRoutes @RequestAttribute(required = false) Long timeout, @RequestAttribute(required = false) Boolean abortAfterTimeout) { - return doIfEnabled(() -> { + return doIfEnabledAndNotReadOnly(() -> { try { delegate().stopRoute( id, @@ -128,7 +128,7 @@ public class CamelRoutesMvcEndpoint extends AbstractCamelMvcEndpoint<CamelRoutes public Object start( @PathVariable String id) { - return doIfEnabled(() -> { + return doIfEnabledAndNotReadOnly(() -> { try { delegate().startRoute(id); } catch (Exception e) { @@ -143,7 +143,7 @@ public class CamelRoutesMvcEndpoint extends AbstractCamelMvcEndpoint<CamelRoutes @PostMapping(value = "/{id}/reset", produces = {ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE}) public Object reset(@PathVariable String id) { - return doIfEnabled(() -> { + return doIfEnabledAndNotReadOnly(() -> { try { delegate().resetRoute(id); } catch (Exception e) { @@ -167,7 +167,7 @@ public class CamelRoutesMvcEndpoint extends AbstractCamelMvcEndpoint<CamelRoutes @PathVariable String id, @RequestAttribute(required = false) Long timeout) { - return doIfEnabled(() -> { + return doIfEnabledAndNotReadOnly(() -> { try { delegate().suspendRoute( id, @@ -193,7 +193,7 @@ public class CamelRoutesMvcEndpoint extends AbstractCamelMvcEndpoint<CamelRoutes public Object resume( @PathVariable String id) { - return doIfEnabled(() -> { + return doIfEnabledAndNotReadOnly(() -> { try { delegate().resumeRoute(id); } catch (Exception e) { diff --git a/components/camel-spring-boot/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/components/camel-spring-boot/src/main/resources/META-INF/additional-spring-configuration-metadata.json index f61650f..6074cb7 100644 --- a/components/camel-spring-boot/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/components/camel-spring-boot/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -7,6 +7,12 @@ "defaultValue": "/camel/routes" }, { + "name": "endpoints.camelroutes.read-only", + "type": "java.lang.Boolean", + "description": "Whether Camel Routes actuator is in read-only mode. If not in read-only mode then operations to start/stop routes would be enabled.", + "defaultValue": "true" + }, + { "name": "endpoints.camelroutes.enabled", "type": "java.lang.Boolean", "description": "To turn on or off information about Camel Routes via actuator endpoint.", diff --git a/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/actuate/endpoint/CamelRoutesMvcEndpointTest.java b/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/actuate/endpoint/CamelRoutesMvcEndpointTest.java index dcb0eda..ff9187b 100644 --- a/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/actuate/endpoint/CamelRoutesMvcEndpointTest.java +++ b/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/actuate/endpoint/CamelRoutesMvcEndpointTest.java @@ -29,6 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.ResponseEntity; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; @@ -39,7 +40,12 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @EnableAutoConfiguration @SpringBootApplication -@SpringBootTest(classes = {CamelAutoConfiguration.class, CamelRoutesEndpointAutoConfiguration.class, ActuatorTestRoute.class}) +@SpringBootTest(classes = {CamelAutoConfiguration.class, CamelRoutesEndpointAutoConfiguration.class, ActuatorTestRoute.class}, + properties = { + "endpoints.enabled = false", + "endpoints.camelroutes.enabled = true", + "endpoints.camelroutes.read-only = false" + }) public class CamelRoutesMvcEndpointTest extends Assert { @Autowired @@ -65,4 +71,11 @@ public class CamelRoutesMvcEndpointTest extends Assert { assertEquals("foo-route", ((RouteDetailsInfo)result).getId()); } + @Test + public void testMvcRoutesEndpointStop() throws Exception { + Object result = endpoint.stop("foo-route", null, null); + ResponseEntity ent = (ResponseEntity) result; + assertEquals(200, ent.getStatusCodeValue()); + } + } diff --git a/examples/camel-example-spring-boot-supervising-route-controller/src/main/resources/application.properties b/examples/camel-example-spring-boot-supervising-route-controller/src/main/resources/application.properties index ba6d516..c3a7f5b 100644 --- a/examples/camel-example-spring-boot-supervising-route-controller/src/main/resources/application.properties +++ b/examples/camel-example-spring-boot-supervising-route-controller/src/main/resources/application.properties @@ -33,6 +33,9 @@ endpoints.health.enabled = true # endpoints.camelroutes.path = /camel/routes # endpoints.camelroutes.enabled = true +# turn off read-only so we can stop/start the Camel routes +endpoints.camelroutes.read-only = false + management.security.enabled = false camel.springboot.name = SampleSupervisingRouteController -- To stop receiving notification emails like this one, please contact davscl...@apache.org.