You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2018/02/26 14:25:25 UTC

[camel] branch master updated: CAMEL-11598: camel-spring-boot - actuator endpoints - Make it read-only by default

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 <cl...@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
davsclaus@apache.org.