CAMEL-11640: SupervisingRouteController : Add a SPI to filter routes to 
supervise


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/2b832e93
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/2b832e93
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/2b832e93

Branch: refs/heads/master
Commit: 2b832e937e0a1cdd3a8037880a90d0261b0f4804
Parents: ef5aa1f
Author: lburgazzoli <lburgazz...@gmail.com>
Authored: Mon Aug 7 12:04:27 2017 +0200
Committer: lburgazzoli <lburgazz...@gmail.com>
Committed: Tue Aug 8 13:29:29 2017 +0200

----------------------------------------------------------------------
 .../apache/camel/impl/DefaultCamelContext.java  |  2 +-
 .../camel/impl/DefaultRouteController.java      | 12 ++--
 .../camel/impl/SupervisingRouteController.java  | 75 +++++++++++++++++++-
 .../impl/SupervisingRouteControllerFilters.java | 51 +++++++++++++
 .../org/apache/camel/spi/RouteController.java   | 15 ++--
 ...rvisingRouteControllerAutoConfiguration.java | 25 +++++--
 ...SupervisingRouteControllerConfiguration.java | 13 ++++
 .../java/sample/camel/ApplicationRoutes.java    |  8 ++-
 .../src/main/resources/application.properties   |  4 +-
 9 files changed, 177 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/2b832e93/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java 
b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
index 1856ebd..61939b8 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
@@ -3171,7 +3171,7 @@ public class DefaultCamelContext extends ServiceSupport 
implements ModelCamelCon
                     }
                 }
 
-                final List<Route> controlledRoutes = 
getRouteController().getControlledRoutes();
+                final Collection<Route> controlledRoutes = 
getRouteController().getControlledRoutes();
 
                 if (controlledRoutes.isEmpty()) {
                     log.info("Total {} routes, of which {} are started",

http://git-wip-us.apache.org/repos/asf/camel/blob/2b832e93/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteController.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteController.java 
b/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteController.java
index db10a33..6d46adc 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteController.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteController.java
@@ -16,9 +16,8 @@
  */
 package org.apache.camel.impl;
 
-import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.camel.CamelContext;
@@ -28,16 +27,13 @@ import org.apache.camel.spi.RouteController;
 
 @Experimental
 public class DefaultRouteController extends 
org.apache.camel.support.ServiceSupport implements RouteController  {
-    private final List<Route> routes;
     private CamelContext camelContext;
-
     public DefaultRouteController() {
         this(null);
     }
 
     public DefaultRouteController(CamelContext camelContext) {
         this.camelContext = camelContext;
-        this.routes = new ArrayList<>();
     }
 
     // ***************************************************
@@ -105,8 +101,12 @@ public class DefaultRouteController extends 
org.apache.camel.support.ServiceSupp
         camelContext.resumeRoute(routeId);
     }
 
+    // ***************************************************
+    //
+    // ***************************************************
+
     @Override
-    public List<Route> getControlledRoutes() {
+    public Collection<Route> getControlledRoutes() {
         return Collections.emptyList();
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/2b832e93/camel-core/src/main/java/org/apache/camel/impl/SupervisingRouteController.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/SupervisingRouteController.java
 
b/camel-core/src/main/java/org/apache/camel/impl/SupervisingRouteController.java
index 8e5167e..3054ac4 100644
--- 
a/camel-core/src/main/java/org/apache/camel/impl/SupervisingRouteController.java
+++ 
b/camel-core/src/main/java/org/apache/camel/impl/SupervisingRouteController.java
@@ -17,6 +17,9 @@
 package org.apache.camel.impl;
 
 import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.EventObject;
 import java.util.HashMap;
 import java.util.List;
@@ -31,6 +34,7 @@ import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import org.apache.camel.CamelContext;
@@ -48,6 +52,7 @@ import org.apache.camel.spi.RouteController;
 import org.apache.camel.spi.RoutePolicy;
 import org.apache.camel.spi.RoutePolicyFactory;
 import org.apache.camel.support.EventNotifierSupport;
+import org.apache.camel.util.CamelContextHelper;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.backoff.BackOff;
 import org.apache.camel.util.backoff.BackOffContext;
@@ -68,6 +73,7 @@ public class SupervisingRouteController extends 
DefaultRouteController {
     private final Object lock;
     private final AtomicBoolean contextStarted;
     private final AtomicInteger routeCount;
+    private final List<Filter> filters;
     private final Set<RouteHolder> routes;
     private final CamelContextStartupListener listener;
     private final RouteManager routeManager;
@@ -80,6 +86,7 @@ public class SupervisingRouteController extends 
DefaultRouteController {
     public SupervisingRouteController() {
         this.lock = new Object();
         this.contextStarted = new AtomicBoolean(false);
+        this.filters = new ArrayList<>();
         this.routeCount = new AtomicInteger(0);
         this.routes = new TreeSet<>();
         this.routeManager = new RouteManager();
@@ -166,6 +173,25 @@ public class SupervisingRouteController extends 
DefaultRouteController {
         this.initialDelay = Duration.ofMillis(initialDelay);
     }
 
+    /**
+     * Add a filter used to determine the routes to supervise.
+     */
+    public void addFilter(Filter filter) {
+        this.filters.add(filter);
+    }
+
+    /**
+     * Sets the filters user to determine the routes to supervise.
+     */
+    public void setFilters(Collection<Filter> filters) {
+        this.filters.clear();
+        this.filters.addAll(filters);
+    }
+
+    public Collection<Filter> getFilters() {
+        return Collections.unmodifiableList(filters);
+    }
+
     // *********************************
     // Lifecycle
     // *********************************
@@ -298,7 +324,7 @@ public class SupervisingRouteController extends 
DefaultRouteController {
     }
 
     @Override
-    public List<Route> getControlledRoutes() {
+    public Collection<Route> getControlledRoutes() {
         return routes.stream()
             .map(RouteHolder::get)
             .collect(Collectors.toList());
@@ -596,11 +622,21 @@ public class SupervisingRouteController extends 
DefaultRouteController {
 
         @Override
         public void onInit(Route route) {
-            if 
("false".equals(route.getRouteContext().getRoute().getAutoStartup())) {
-                LOGGER.info("Route {} has explicit auto-startup flag set to 
false, ignore it", route.getId());
+            final String autoStartup = 
route.getRouteContext().getRoute().getAutoStartup();
+            if (ObjectHelper.equalIgnoreCase("false", autoStartup)) {
+                LOGGER.info("Route {} won't be supervised (reason: has 
explicit auto-startup flag set to false)", route.getId());
                 return;
             }
 
+            for (Filter filter : filters) {
+                FilterResult result = filter.apply(route);
+
+                if (!result.supervised()) {
+                    LOGGER.info("Route {} won't be supervised (reason: {})", 
route.getId(), result.reason());
+                    return;
+                }
+            }
+
             RouteHolder holder = new RouteHolder(route, 
routeCount.incrementAndGet());
             if (routes.add(holder)) {
                 
holder.getContext().setRouteController(SupervisingRouteController.this);
@@ -702,4 +738,37 @@ public class SupervisingRouteController extends 
DefaultRouteController {
             }
         }
     }
+
+    // *********************************
+    // Filter
+    // *********************************
+
+    @Experimental
+    public static class FilterResult {
+        public static final FilterResult SUPERVISED = new FilterResult(true, 
null);
+
+        private final boolean controlled;
+        private final String reason;
+
+        public FilterResult(boolean controlled, String reason) {
+            this.controlled = controlled;
+            this.reason = reason;
+        }
+
+        public FilterResult(boolean controlled, String format, Object... args) 
{
+            this(controlled, String.format(format, args));
+        }
+
+        public boolean supervised() {
+            return controlled;
+        }
+
+        public String reason() {
+            return reason;
+        }
+    }
+
+    @Experimental
+    public interface Filter extends Function<Route, FilterResult> {
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/2b832e93/camel-core/src/main/java/org/apache/camel/impl/SupervisingRouteControllerFilters.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/SupervisingRouteControllerFilters.java
 
b/camel-core/src/main/java/org/apache/camel/impl/SupervisingRouteControllerFilters.java
new file mode 100644
index 0000000..43ecd6a
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/impl/SupervisingRouteControllerFilters.java
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.impl;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.camel.Route;
+
+public final class SupervisingRouteControllerFilters {
+    private SupervisingRouteControllerFilters() {
+    }
+
+    public static final class BlackList implements 
SupervisingRouteController.Filter {
+        private final Set<String> names;
+
+        public BlackList(String name) {
+            this(Collections.singletonList(name));
+        }
+
+        public BlackList(Collection<String> names) {
+            this.names = new HashSet<>(names);
+        }
+
+        @Override
+        public SupervisingRouteController.FilterResult apply(Route route) {
+            boolean supervised = !names.contains(route.getId());
+
+            return new SupervisingRouteController.FilterResult(
+                supervised,
+                supervised ? null : "black-listed"
+            );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/2b832e93/camel-core/src/main/java/org/apache/camel/spi/RouteController.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/spi/RouteController.java 
b/camel-core/src/main/java/org/apache/camel/spi/RouteController.java
index 0e55c52..d19a8a2 100644
--- a/camel-core/src/main/java/org/apache/camel/spi/RouteController.java
+++ b/camel-core/src/main/java/org/apache/camel/spi/RouteController.java
@@ -16,7 +16,7 @@
  */
 package org.apache.camel.spi;
 
-import java.util.List;
+import java.util.Collection;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.camel.CamelContextAware;
@@ -26,6 +26,12 @@ import org.apache.camel.Service;
 
 @Experimental
 public interface RouteController extends CamelContextAware, Service {
+    /**
+     * Return the list of routes controlled by this controller.
+     *
+     * @return the list of controlled routes;
+     */
+    Collection<Route> getControlledRoutes();
 
     void startRoute(String routeId) throws Exception;
 
@@ -40,11 +46,4 @@ public interface RouteController extends CamelContextAware, 
Service {
     void suspendRoute(String routeId, long timeout, TimeUnit timeUnit) throws 
Exception;
 
     void resumeRoute(String routeId) throws Exception;
-
-    /**
-     * Return the list of routes controlled by this controller.
-     *
-     * @return the list of controlled routes;
-     */
-    List<Route> getControlledRoutes();
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/2b832e93/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/SupervisingRouteControllerAutoConfiguration.java
----------------------------------------------------------------------
diff --git 
a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/SupervisingRouteControllerAutoConfiguration.java
 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/SupervisingRouteControllerAutoConfiguration.java
index 9ff36bb..0ac9994 100644
--- 
a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/SupervisingRouteControllerAutoConfiguration.java
+++ 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/SupervisingRouteControllerAutoConfiguration.java
@@ -16,11 +16,14 @@
  */
 package org.apache.camel.spring.boot;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 
 import org.apache.camel.converter.TimePatternConverter;
 import org.apache.camel.impl.SupervisingRouteController;
+import org.apache.camel.impl.SupervisingRouteControllerFilters;
 import org.apache.camel.spi.RouteController;
 import 
org.apache.camel.spring.boot.SupervisingRouteControllerConfiguration.BackOffConfiguration;
 import 
org.apache.camel.spring.boot.SupervisingRouteControllerConfiguration.RouteConfiguration;
@@ -42,6 +45,8 @@ import org.springframework.context.annotation.Scope;
 public class SupervisingRouteControllerAutoConfiguration {
     @Autowired
     private SupervisingRouteControllerConfiguration configuration;
+    @Autowired(required = false)
+    private List<SupervisingRouteController.Filter> filters = 
Collections.emptyList();
 
     @Bean
     @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
@@ -52,17 +57,23 @@ public class SupervisingRouteControllerAutoConfiguration {
         // Initial delay
         
Optional.ofNullable(configuration.getInitialDelay()).map(TimePatternConverter::toMilliSeconds).ifPresent(controller::setInitialDelay);
 
+        // Filter list
+        controller.setFilters(filters);
+
         // Back off
         controller.setDefaultBackOff(configureBackOff(Optional.empty(), 
configuration.getDefaultBackOff()));
 
         for (Map.Entry<String, RouteConfiguration> entry: 
configuration.getRoutes().entrySet()) {
-            controller.setBackOff(
-                entry.getKey(),
-                configureBackOff(
-                    Optional.ofNullable(controller.getDefaultBackOff()),
-                    entry.getValue().getBackOff()
-                )
-            );
+            final RouteConfiguration cfg = entry.getValue();
+            final Optional<BackOff> defaultBackOff = 
Optional.ofNullable(controller.getDefaultBackOff());
+
+            if (!cfg.isSupervised()) {
+                // Mark this route as excluded from supervisor
+                controller.addFilter(new 
SupervisingRouteControllerFilters.BlackList(entry.getKey()));
+            } else {
+                // configure teh route
+                controller.setBackOff(entry.getKey(), 
configureBackOff(defaultBackOff, cfg.getBackOff()));
+            }
         }
 
         return controller;

http://git-wip-us.apache.org/repos/asf/camel/blob/2b832e93/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/SupervisingRouteControllerConfiguration.java
----------------------------------------------------------------------
diff --git 
a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/SupervisingRouteControllerConfiguration.java
 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/SupervisingRouteControllerConfiguration.java
index 4ab2290..1c4096d 100644
--- 
a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/SupervisingRouteControllerConfiguration.java
+++ 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/SupervisingRouteControllerConfiguration.java
@@ -75,10 +75,23 @@ public class SupervisingRouteControllerConfiguration {
 
     public static class RouteConfiguration {
         /**
+         * Control if the route should be supervised or not, default is true.
+         */
+        private boolean supervise = true;
+
+        /**
          * The back-off configuration from this route, inherits from default 
back-off
          */
         private BackOffConfiguration backOff;
 
+        public boolean isSupervised() {
+            return supervise;
+        }
+
+        public void setSupervise(boolean supervise) {
+            this.supervise = supervise;
+        }
+
         public BackOffConfiguration getBackOff() {
             return backOff;
         }

http://git-wip-us.apache.org/repos/asf/camel/blob/2b832e93/examples/camel-example-spring-boot-routecontroller/src/main/java/sample/camel/ApplicationRoutes.java
----------------------------------------------------------------------
diff --git 
a/examples/camel-example-spring-boot-routecontroller/src/main/java/sample/camel/ApplicationRoutes.java
 
b/examples/camel-example-spring-boot-routecontroller/src/main/java/sample/camel/ApplicationRoutes.java
index 7115570..fb6e2f5 100644
--- 
a/examples/camel-example-spring-boot-routecontroller/src/main/java/sample/camel/ApplicationRoutes.java
+++ 
b/examples/camel-example-spring-boot-routecontroller/src/main/java/sample/camel/ApplicationRoutes.java
@@ -41,8 +41,12 @@ public class ApplicationRoutes extends RouteBuilder {
             .log("From undertow ...");
 
         from("undertow:http://localhost:9012";)
-            .id("undertow-2")
+            .id("undertow2")
             .autoStartup(false)
-            .log("From undertow ...");
+            .log("From undertow 2...");
+
+        from("undertow:http://localhost:9013";)
+            .id("undertow3")
+            .log("From undertow 3...");
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/2b832e93/examples/camel-example-spring-boot-routecontroller/src/main/resources/application.properties
----------------------------------------------------------------------
diff --git 
a/examples/camel-example-spring-boot-routecontroller/src/main/resources/application.properties
 
b/examples/camel-example-spring-boot-routecontroller/src/main/resources/application.properties
index 10efe1c..8533f6b 100644
--- 
a/examples/camel-example-spring-boot-routecontroller/src/main/resources/application.properties
+++ 
b/examples/camel-example-spring-boot-routecontroller/src/main/resources/application.properties
@@ -19,7 +19,8 @@ debug = false
 
 logging.level.org.springframework = INFO
 logging.level.org.apache.camel.spring.boot = INFO
-logging.level.org.apache.camel.impl = DEBUG
+logging.level.org.apache.camel.impl = INFO
+logging.level.org.apache.camel.impl.SupervisingRouteController = DEBUG
 logging.level.org.apache.camel.util.backoff = DEBUG
 logging.level.sample.camel = DEBUG
 
@@ -42,3 +43,4 @@ camel.supervising.controller.default-back-off.delay = 5s
 camel.supervising.controller.default-back-off.max-attempts = 10
 camel.supervising.controller.routes.undertow.back-off.delay = 10s
 camel.supervising.controller.routes.undertow.back-off.max-attempts = 3
+camel.supervising.controller.routes.undertow3.supervise = false

Reply via email to