You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by lb...@apache.org on 2017/08/11 13:00:53 UTC
[1/2] camel git commit: CAMEL-11659: Create a ClusteredRouteController
Repository: camel
Updated Branches:
refs/heads/master f8ddd2305 -> d043c7d0a
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/camel-example-spring-boot-supervising-route-controller/readme.adoc
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-supervising-route-controller/readme.adoc b/examples/camel-example-spring-boot-supervising-route-controller/readme.adoc
new file mode 100644
index 0000000..8c7bb28
--- /dev/null
+++ b/examples/camel-example-spring-boot-supervising-route-controller/readme.adoc
@@ -0,0 +1,51 @@
+# Camel Supervising Route Controller Example Spring Boot
+
+This example shows how to work with a simple Apache Camel application using Spring Boot and a Supervising Route Controller.
+
+## How to run
+
+You can run this example using
+
+ mvn spring-boot:run
+
+Beside JMX you can use Spring Boot Endpoints to interact with the routes:
+
+* To get info about the routes
++
+[source]
+----
+curl -XGET -s http://localhost:8080/camel/routes
+----
++
++* To get details about a route
+++
++[source]
++----
++curl -XGET -s http://localhost:8080/camel/routes/{id}/detail
++----
+
+* To get info about a route
++
+[source]
+----
+curl -XGET -s http://localhost:8080/camel/routes/{id}/info
+----
+
+* To stop a route
++
+[source]
+----
+curl -XPOST -s http://localhost:8080/camel/routes/{id}/stop
+----
+
+* To start a route
++
+[source]
+----
+curl -XPOST -s http://localhost:8080/camel/routes/{id}/stop
+----
+
+
+## More information
+
+You can find more information about Apache Camel at the website: http://camel.apache.org/
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/camel-example-spring-boot-supervising-route-controller/src/main/java/sample/camel/Application.java
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-supervising-route-controller/src/main/java/sample/camel/Application.java b/examples/camel-example-spring-boot-supervising-route-controller/src/main/java/sample/camel/Application.java
new file mode 100644
index 0000000..2a97fed
--- /dev/null
+++ b/examples/camel-example-spring-boot-supervising-route-controller/src/main/java/sample/camel/Application.java
@@ -0,0 +1,37 @@
+/**
+ * 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 sample.camel;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+//CHECKSTYLE:OFF
+/**
+ * A sample Spring Boot application that starts the Camel routes.
+ */
+@SpringBootApplication
+public class Application {
+
+ /**
+ * A main method to start this application.
+ */
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
+//CHECKSTYLE:ON
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/camel-example-spring-boot-supervising-route-controller/src/main/java/sample/camel/ApplicationRoutes.java
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-supervising-route-controller/src/main/java/sample/camel/ApplicationRoutes.java b/examples/camel-example-spring-boot-supervising-route-controller/src/main/java/sample/camel/ApplicationRoutes.java
new file mode 100644
index 0000000..fb6e2f5
--- /dev/null
+++ b/examples/camel-example-spring-boot-supervising-route-controller/src/main/java/sample/camel/ApplicationRoutes.java
@@ -0,0 +1,52 @@
+/**
+ * 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 sample.camel;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.springframework.stereotype.Component;
+
+/**
+ *
+ */
+@Component
+public class ApplicationRoutes extends RouteBuilder {
+ @Override
+ public void configure() throws Exception {
+ from("timer:foo?period=5s")
+ .id("foo")
+ .startupOrder(2)
+ .log("From timer (foo) ...");
+
+ from("timer:bar?period=5s")
+ .id("bar")
+ .startupOrder(1)
+ .log("From timer (bar) ...");
+
+ from("undertow:http://localhost:9011")
+ .id("undertow")
+ .log("From undertow ...");
+
+ from("undertow:http://localhost:9012")
+ .id("undertow2")
+ .autoStartup(false)
+ .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/d043c7d0/examples/camel-example-spring-boot-supervising-route-controller/src/main/resources/application.properties
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..8533f6b
--- /dev/null
+++ b/examples/camel-example-spring-boot-supervising-route-controller/src/main/resources/application.properties
@@ -0,0 +1,46 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+debug = false
+
+logging.level.org.springframework = INFO
+logging.level.org.apache.camel.spring.boot = INFO
+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
+
+endpoints.enabled = false
+endpoints.jmx.enabled = false
+endpoints.health.enabled = true
+
+# camel routes is by default enabled
+# so you do not have to configure below
+# endpoints.camelroutes.path = /camel/routes
+# endpoints.camelroutes.enabled = true
+
+management.security.enabled = false
+
+camel.springboot.name = SampleSupervisingRouteController
+
+camel.supervising.controller.enabled = true
+camel.supervising.controller.initial-delay = 5s
+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
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/pom.xml
----------------------------------------------------------------------
diff --git a/examples/pom.xml b/examples/pom.xml
index 268733d..7a4441b 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -96,6 +96,7 @@
<module>camel-example-spring</module>
<module>camel-example-spring-boot</module>
<module>camel-example-spring-boot-activemq</module>
+ <module>camel-example-spring-boot-clustered-route-controller</module>
<module>camel-example-spring-boot-geocoder</module>
<module>camel-example-spring-boot-grpc</module>
<module>camel-example-spring-boot-infinispan</module>
@@ -104,8 +105,8 @@
<module>camel-example-spring-boot-pojo</module>
<module>camel-example-spring-boot-rest-jpa</module>
<module>camel-example-spring-boot-rest-swagger</module>
- <module>camel-example-spring-boot-routecontroller</module>
<module>camel-example-spring-boot-servicecall</module>
+ <module>camel-example-spring-boot-supervising-route-controller</module>
<module>camel-example-spring-cloud-servicecall</module>
<module>camel-example-spring-javaconfig</module>
<module>camel-example-spring-jms</module>
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/platforms/spring-boot/components-starter/camel-atomix-starter/src/main/java/org/apache/camel/component/atomix/ha/springboot/AtomixClusterServiceAutoConfiguration.java
----------------------------------------------------------------------
diff --git a/platforms/spring-boot/components-starter/camel-atomix-starter/src/main/java/org/apache/camel/component/atomix/ha/springboot/AtomixClusterServiceAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-atomix-starter/src/main/java/org/apache/camel/component/atomix/ha/springboot/AtomixClusterServiceAutoConfiguration.java
new file mode 100644
index 0000000..8bb7ab5
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-atomix-starter/src/main/java/org/apache/camel/component/atomix/ha/springboot/AtomixClusterServiceAutoConfiguration.java
@@ -0,0 +1,96 @@
+/**
+ * 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.component.atomix.ha.springboot;
+
+
+import java.util.stream.Collectors;
+
+import io.atomix.catalyst.transport.Address;
+import org.apache.camel.component.atomix.ha.AtomixClusterClientService;
+import org.apache.camel.component.atomix.ha.AtomixClusterService;
+import org.apache.camel.ha.CamelClusterService;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.camel.spring.boot.ha.ClusteredRouteControllerAutoConfiguration;
+import org.apache.camel.util.ObjectHelper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.AllNestedConditions;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Scope;
+
+@Configuration
+@AutoConfigureBefore({ ClusteredRouteControllerAutoConfiguration.class, CamelAutoConfiguration.class })
+@Conditional(AtomixClusterServiceAutoConfiguration.AutoConfigurationCondition.class)
+@EnableConfigurationProperties(AtomixClusterServiceConfiguration.class)
+public class AtomixClusterServiceAutoConfiguration {
+ @Autowired
+ private AtomixClusterServiceConfiguration configuration;
+
+ @Bean(initMethod = "start", destroyMethod = "stop")
+ @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
+ @ConditionalOnProperty(prefix = "camel.clustered.service.atomix", name = "mode", havingValue = "node")
+ public CamelClusterService clusterNode() {
+ AtomixClusterService service = new AtomixClusterService();
+ service.setNodes(configuration.getNodes().stream().map(Address::new).collect(Collectors.toList()));
+
+ ObjectHelper.ifNotEmpty(configuration.isEphemeral(), service::setEphemeral);
+ ObjectHelper.ifNotEmpty(configuration.getId(), service::setId);
+ ObjectHelper.ifNotEmpty(configuration.getAddress(), service::setAddress);
+ ObjectHelper.ifNotEmpty(configuration.getStoragePath(), service::setStoragePath);
+ ObjectHelper.ifNotEmpty(configuration.getStorageLevel(), service::setStorageLevel);
+ ObjectHelper.ifNotEmpty(configuration.getConfigurationUri(), service::setConfigurationUri);
+
+ return service;
+ }
+
+ @Bean(initMethod = "start", destroyMethod = "stop")
+ @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
+ @ConditionalOnProperty(prefix = "camel.clustered.service.atomix", name = "mode", havingValue = "client")
+ public CamelClusterService clusterClient() {
+ AtomixClusterClientService service = new AtomixClusterClientService();
+ service.setNodes(configuration.getNodes().stream().map(Address::new).collect(Collectors.toList()));
+
+ ObjectHelper.ifNotEmpty(configuration.getId(), service::setId);
+ ObjectHelper.ifNotEmpty(configuration.getConfigurationUri(), service::setConfigurationUri);
+
+ return service;
+ }
+
+ // *****************************************
+ // Conditions
+ // *****************************************
+
+ public static class AutoConfigurationCondition extends AllNestedConditions {
+ public AutoConfigurationCondition() {
+ super(ConfigurationPhase.REGISTER_BEAN);
+ }
+
+ @ConditionalOnProperty(prefix = "camel.clustered.service.atomix", name = "enabled")
+ static class IfEnabled {
+ }
+
+
+ @ConditionalOnProperty(prefix = "camel.clustered.service.atomix", name = "mode")
+ static class WithMode {
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/platforms/spring-boot/components-starter/camel-atomix-starter/src/main/java/org/apache/camel/component/atomix/ha/springboot/AtomixClusterServiceConfiguration.java
----------------------------------------------------------------------
diff --git a/platforms/spring-boot/components-starter/camel-atomix-starter/src/main/java/org/apache/camel/component/atomix/ha/springboot/AtomixClusterServiceConfiguration.java b/platforms/spring-boot/components-starter/camel-atomix-starter/src/main/java/org/apache/camel/component/atomix/ha/springboot/AtomixClusterServiceConfiguration.java
new file mode 100644
index 0000000..27b281a
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-atomix-starter/src/main/java/org/apache/camel/component/atomix/ha/springboot/AtomixClusterServiceConfiguration.java
@@ -0,0 +1,151 @@
+/**
+ * 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.component.atomix.ha.springboot;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import io.atomix.copycat.server.storage.StorageLevel;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties(prefix = "camel.clustered.service.atomix")
+public class AtomixClusterServiceConfiguration {
+ enum Mode {
+ node,
+ client
+ }
+
+ /**
+ * Sets if the atomix cluster service should be enabled or not, default is false.
+ */
+ private boolean enabled;
+
+ /**
+ * Sets the cluster mode.
+ */
+ private Mode mode;
+ /**
+ * The address of the nodes composing the cluster.
+ */
+ private Set<String> nodes = new HashSet<>();
+
+ /**
+ * The cluster id.
+ */
+ private String id;
+
+ /**
+ * The address of the node - node only.
+ */
+ private String address;
+
+ /**
+ * Sets if the local member should join groups as PersistentMember or not (node only).
+ */
+ private Boolean ephemeral;
+
+ /**
+ * The storage directory - node only.
+ */
+ private String storagePath;
+
+ /**
+ * The storage mode - node only.
+ */
+ private StorageLevel storageLevel = StorageLevel.MEMORY;
+
+ /**
+ * The Atomix configuration uri.
+ */
+ private String configurationUri;
+
+ // *********************************
+ // Properties
+ // *********************************
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public Mode getMode() {
+ return mode;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public void setNodes(Set<String> nodes) {
+ this.nodes = nodes;
+ }
+
+ public void setMode(Mode mode) {
+ this.mode = mode;
+ }
+
+ public Set<String> getNodes() {
+ return nodes;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public Boolean isEphemeral() {
+ return ephemeral;
+ }
+
+ public void setEphemeral(Boolean ephemeral) {
+ this.ephemeral = ephemeral;
+ }
+
+ public String getStoragePath() {
+ return storagePath;
+ }
+
+ public void setStoragePath(String storagePath) {
+ this.storagePath = storagePath;
+ }
+
+ public StorageLevel getStorageLevel() {
+ return storageLevel;
+ }
+
+ public void setStorageLevel(StorageLevel storageLevel) {
+ this.storageLevel = storageLevel;
+ }
+
+ public String getConfigurationUri() {
+ return configurationUri;
+ }
+
+ public void setConfigurationUri(String configurationUri) {
+ this.configurationUri = configurationUri;
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/platforms/spring-boot/components-starter/camel-atomix-starter/src/main/java/org/apache/camel/component/atomix/springboot/StringToAddressConverter.java
----------------------------------------------------------------------
diff --git a/platforms/spring-boot/components-starter/camel-atomix-starter/src/main/java/org/apache/camel/component/atomix/springboot/StringToAddressConverter.java b/platforms/spring-boot/components-starter/camel-atomix-starter/src/main/java/org/apache/camel/component/atomix/springboot/StringToAddressConverter.java
new file mode 100644
index 0000000..3abf63c
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-atomix-starter/src/main/java/org/apache/camel/component/atomix/springboot/StringToAddressConverter.java
@@ -0,0 +1,29 @@
+/**
+ * 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.component.atomix.springboot;
+
+import io.atomix.catalyst.transport.Address;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.stereotype.Component;
+
+@Component
+public class StringToAddressConverter implements Converter<String, Address> {
+ @Override
+ public Address convert(String source) {
+ return new Address(source);
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/platforms/spring-boot/components-starter/camel-atomix-starter/src/main/resources/META-INF/spring.factories
----------------------------------------------------------------------
diff --git a/platforms/spring-boot/components-starter/camel-atomix-starter/src/main/resources/META-INF/spring.factories b/platforms/spring-boot/components-starter/camel-atomix-starter/src/main/resources/META-INF/spring.factories
index c8186fd..ae14d13 100644
--- a/platforms/spring-boot/components-starter/camel-atomix-starter/src/main/resources/META-INF/spring.factories
+++ b/platforms/spring-boot/components-starter/camel-atomix-starter/src/main/resources/META-INF/spring.factories
@@ -16,18 +16,19 @@
## ---------------------------------------------------------------------------
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-org.apache.camel.component.atomix.client.map.springboot.AtomixClientMapComponentAutoConfiguration,\
-org.apache.camel.component.atomix.client.multimap.springboot.AtomixClientMultiMapComponentAutoConfiguration,\
-org.apache.camel.component.atomix.client.set.springboot.AtomixClientSetComponentAutoConfiguration,\
-org.apache.camel.component.atomix.client.value.springboot.AtomixClientValueComponentAutoConfiguration,\
-org.apache.camel.component.atomix.client.queue.springboot.AtomixClientQueueComponentAutoConfiguration,\
-org.apache.camel.component.atomix.client.messaging.springboot.AtomixClientMessagingComponentAutoConfiguration,\
+org.apache.camel.component.atomix.client.map.springboot.AtomixMapComponentAutoConfiguration,\
+org.apache.camel.component.atomix.client.multimap.springboot.AtomixMultiMapComponentAutoConfiguration,\
+org.apache.camel.component.atomix.client.set.springboot.AtomixSetComponentAutoConfiguration,\
+org.apache.camel.component.atomix.client.value.springboot.AtomixValueComponentAutoConfiguration,\
+org.apache.camel.component.atomix.client.queue.springboot.AtomixQueueComponentAutoConfiguration,\
+org.apache.camel.component.atomix.client.messaging.springboot.AtomixMessagingComponentAutoConfiguration,\
org.apache.camel.component.atomix.client.set.springboot.AtomixSetComponentAutoConfiguration,\
org.apache.camel.component.atomix.client.queue.springboot.AtomixQueueComponentAutoConfiguration,\
org.apache.camel.component.atomix.client.map.springboot.AtomixMapComponentAutoConfiguration,\
org.apache.camel.component.atomix.client.multimap.springboot.AtomixMultiMapComponentAutoConfiguration,\
org.apache.camel.component.atomix.client.value.springboot.AtomixValueComponentAutoConfiguration,\
-org.apache.camel.component.atomix.client.messaging.springboot.AtomixMessagingComponentAutoConfiguration
+org.apache.camel.component.atomix.client.messaging.springboot.AtomixMessagingComponentAutoConfiguration,\
+org.apache.camel.component.atomix.ha.springboot.AtomixClusterServiceAutoConfiguration
[2/2] camel git commit: CAMEL-11659: Create a ClusteredRouteController
Posted by lb...@apache.org.
CAMEL-11659: Create a ClusteredRouteController
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/d043c7d0
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/d043c7d0
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/d043c7d0
Branch: refs/heads/master
Commit: d043c7d0a7315c6c6a7971894f4574361c93289d
Parents: f8ddd23
Author: lburgazzoli <lb...@gmail.com>
Authored: Thu Aug 10 17:27:49 2017 +0200
Committer: lburgazzoli <lb...@gmail.com>
Committed: Fri Aug 11 14:54:43 2017 +0200
----------------------------------------------------------------------
.../impl/ha/ClusteredRouteConfiguration.java | 54 ++++
.../camel/impl/ha/ClusteredRouteController.java | 314 +++++++++++++++++++
.../camel/impl/ha/ClusteredRouteFilter.java | 32 ++
.../camel/impl/ha/ClusteredRouteFilters.java | 59 ++++
.../camel/impl/ha/ClusteredRoutePolicy.java | 76 ++++-
.../atomix/ha/AtomixClusterClientService.java | 10 +
.../atomix/ha/AtomixClusterService.java | 10 +
.../component/atomix/ha/AtomixClusterView.java | 18 +-
...usteredRouteControllerAutoConfiguration.java | 101 ++++++
.../ClusteredRouteControllerConfiguration.java | 147 +++++++++
.../main/resources/META-INF/spring.factories | 1 +
examples/README.adoc | 6 +-
.../cluster-bootstrap/pom.xml | 77 +++++
.../examples/cluster/ClusterBootstrap.java | 41 +++
.../src/main/resources/log4j2.xml | 18 ++
.../cluster-node/pom.xml | 100 ++++++
.../camel/examples/cluster/ClusterNode.java | 36 +++
.../cluster/ClusterNodeConfiguration.java | 68 ++++
.../src/main/resources/application.properties | 31 ++
.../pom.xml | 68 ++++
.../readme.adoc | 25 ++
.../pom.xml | 154 ---------
.../readme.adoc | 51 ---
.../src/main/java/sample/camel/Application.java | 37 ---
.../java/sample/camel/ApplicationRoutes.java | 52 ---
.../src/main/resources/application.properties | 46 ---
.../pom.xml | 154 +++++++++
.../readme.adoc | 51 +++
.../src/main/java/sample/camel/Application.java | 37 +++
.../java/sample/camel/ApplicationRoutes.java | 52 +++
.../src/main/resources/application.properties | 46 +++
examples/pom.xml | 3 +-
.../AtomixClusterServiceAutoConfiguration.java | 96 ++++++
.../AtomixClusterServiceConfiguration.java | 151 +++++++++
.../springboot/StringToAddressConverter.java | 29 ++
.../main/resources/META-INF/spring.factories | 15 +-
36 files changed, 1903 insertions(+), 363 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRouteConfiguration.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRouteConfiguration.java b/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRouteConfiguration.java
new file mode 100644
index 0000000..9cdfaeb
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRouteConfiguration.java
@@ -0,0 +1,54 @@
+/**
+ * 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.ha;
+
+import java.time.Duration;
+
+import org.apache.camel.util.ObjectHelper;
+
+public class ClusteredRouteConfiguration implements Cloneable {
+ private String namespace;
+ private Duration initialDelay;
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+
+ public Duration getInitialDelay() {
+ return initialDelay;
+ }
+
+ public void setInitialDelay(Duration initialDelay) {
+ this.initialDelay = initialDelay;
+ }
+
+ // ****************************************
+ // Copy
+ // ****************************************
+
+ public ClusteredRouteConfiguration copy() {
+ try {
+ return (ClusteredRouteConfiguration) super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw ObjectHelper.wrapRuntimeCamelException(e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRouteController.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRouteController.java b/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRouteController.java
new file mode 100644
index 0000000..2a1849e
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRouteController.java
@@ -0,0 +1,314 @@
+/**
+ * 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.ha;
+
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Route;
+import org.apache.camel.ha.CamelClusterService;
+import org.apache.camel.impl.DefaultRouteController;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.spi.RoutePolicy;
+import org.apache.camel.spi.RoutePolicyFactory;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.ServiceHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ClusteredRouteController extends DefaultRouteController {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ClusteredRouteController.class);
+
+ private final Set<String> routes;
+ private final ConcurrentMap<String, ClusteredRouteConfiguration> configurations;
+ private final List<ClusteredRouteFilter> filters;
+ private final PolicyFactory policyFactory;
+ private final ClusteredRouteConfiguration defaultConfiguration;
+ private CamelClusterService clusterService;
+
+ public ClusteredRouteController() {
+ this.routes = new CopyOnWriteArraySet<>();
+ this.configurations = new ConcurrentHashMap<>();
+ this.filters = new ArrayList<>();
+ this.policyFactory = new PolicyFactory();
+
+ this.defaultConfiguration = new ClusteredRouteConfiguration();
+ this.defaultConfiguration.setInitialDelay(Duration.ofMillis(0));
+ }
+
+ // *******************************
+ // Properties.
+ // *******************************
+
+ /**
+ * Add a filter used to to filter cluster aware routes.
+ */
+ public void addFilter(ClusteredRouteFilter filter) {
+ this.filters.add(filter);
+ }
+
+ /**
+ * Sets the filters used to filter cluster aware routes.
+ */
+ public void setFilters(Collection<ClusteredRouteFilter> filters) {
+ this.filters.clear();
+ this.filters.addAll(filters);
+ }
+
+ public Collection<ClusteredRouteFilter> getFilters() {
+ return Collections.unmodifiableList(filters);
+ }
+
+ /**
+ * Add a configuration for the given route.
+ */
+ public void addRouteConfiguration(String routeId, ClusteredRouteConfiguration configuration) {
+ configurations.put(routeId, configuration);
+ }
+
+ /**
+ * Sets the configurations for the routes.
+ */
+ public void setRoutesConfiguration(Map<String, ClusteredRouteConfiguration> configurations) {
+ this.configurations.clear();
+ this.configurations.putAll(configurations);
+ }
+
+ public Map<String, ClusteredRouteConfiguration> getRoutesConfiguration() {
+ return Collections.unmodifiableMap(this.configurations);
+ }
+
+ public Duration getInitialDelay() {
+ return this.defaultConfiguration.getInitialDelay();
+ }
+
+ /**
+ * Set the amount of time the route controller should wait before to start
+ * the routes after the camel context is started.
+ *
+ * @param initialDelay the initial delay.
+ */
+ public void setInitialDelay(Duration initialDelay) {
+ this.defaultConfiguration.setInitialDelay(initialDelay);
+ }
+
+ public String getNamespace() {
+ return this.defaultConfiguration.getNamespace();
+ }
+
+ /**
+ * Set the default namespace.
+ */
+ public void setNamespace(String namespace) {
+ this.defaultConfiguration.setNamespace(namespace);
+ }
+
+ public CamelClusterService getClusterService() {
+ return clusterService;
+ }
+
+ public void setClusterService(CamelClusterService clusterService) {
+ // prevent replacing the service
+ if (this.clusterService != null && this.clusterService != clusterService) {
+ throw new IllegalArgumentException("CamelClusterService is already set");
+ }
+
+ this.clusterService = clusterService;
+ }
+
+ // *******************************
+ //
+ // *******************************
+
+ @Override
+ public Collection<Route> getControlledRoutes() {
+ return this.routes.stream()
+ .map(getCamelContext()::getRoute)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public void doStart() throws Exception {
+ final CamelContext context = getCamelContext();
+
+ // Parameters validation
+ ObjectHelper.notNull(defaultConfiguration.getNamespace(), "Namespace");
+ ObjectHelper.notNull(defaultConfiguration.getInitialDelay(), "initialDelay");
+ ObjectHelper.notNull(context, "camelContext");
+
+ if (clusterService == null) {
+ // Finally try to grab it from the camel context.
+ clusterService = context.hasService(CamelClusterService.class);
+ }
+
+ ObjectHelper.notNull(clusterService, "clusterService");
+
+ if (!ServiceHelper.isStarted(clusterService)) {
+ // Start the cluster service if not yet started.
+ clusterService.start();
+ }
+
+ super.doStart();
+ }
+
+ @Override
+ public void doStop() throws Exception {
+ if (ServiceHelper.isStarted(clusterService)) {
+ // Stop the cluster service.
+ clusterService.stop();
+ }
+ }
+
+ @Override
+ public void setCamelContext(CamelContext camelContext) {
+ if (!camelContext.getRoutePolicyFactories().contains(this.policyFactory)) {
+ camelContext.addRoutePolicyFactory(this.policyFactory);
+ }
+
+ super.setCamelContext(camelContext);
+ }
+
+ // *******************************
+ // Route operations are disabled
+ // *******************************
+
+ @Override
+ public void startRoute(String routeId) throws Exception {
+ failIfClustered(routeId);
+
+ // Delegate to default impl.
+ super.startRoute(routeId);
+ }
+
+ @Override
+ public void stopRoute(String routeId) throws Exception {
+ failIfClustered(routeId);
+
+ // Delegate to default impl.
+ super.stopRoute(routeId);
+ }
+
+ @Override
+ public void stopRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception {
+ failIfClustered(routeId);
+
+ // Delegate to default impl.
+ super.stopRoute(routeId, timeout, timeUnit);
+ }
+
+ @Override
+ public boolean stopRoute(String routeId, long timeout, TimeUnit timeUnit, boolean abortAfterTimeout) throws Exception {
+ failIfClustered(routeId);
+
+ // Delegate to default impl.
+ return super.stopRoute(routeId, timeout, timeUnit, abortAfterTimeout);
+ }
+
+ @Override
+ public void suspendRoute(String routeId) throws Exception {
+ failIfClustered(routeId);
+
+ // Delegate to default impl.
+ super.suspendRoute(routeId);
+ }
+
+ @Override
+ public void suspendRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception {
+ failIfClustered(routeId);
+
+ // Delegate to default impl.
+ super.suspendRoute(routeId, timeout, timeUnit);
+ }
+
+ @Override
+ public void resumeRoute(String routeId) throws Exception {
+ failIfClustered(routeId);
+
+ // Delegate to default impl.
+ super.resumeRoute(routeId);
+ }
+
+ // *******************************
+ // Helpers
+ // *******************************
+
+ private void failIfClustered(String routeId) {
+ // Can't perform action on routes managed by this controller as they
+ // are clustered and they may be part of the same view.
+ if (routes.contains(routeId)) {
+ throw new UnsupportedOperationException(
+ "Operation not supported as route " + routeId + " is clustered"
+ );
+ }
+ }
+
+ // *******************************
+ // Factories
+ // *******************************
+
+ private final class PolicyFactory implements RoutePolicyFactory {
+ @Override
+ public RoutePolicy createRoutePolicy(CamelContext camelContext, String routeId, RouteDefinition route) {
+ // All the filter have to be match to include the route in the
+ // clustering set-up
+ if (filters.stream().allMatch(filter -> filter.test(camelContext, routeId, route))) {
+
+ if (ObjectHelper.isNotEmpty(route.getRoutePolicies())) {
+ // Check if the route is already configured with a clustered
+ // route policy, in that case exclude it.
+ if (route.getRoutePolicies().stream().anyMatch(ClusteredRoutePolicy.class::isInstance)) {
+ LOGGER.debug("Route '{}' has a ClusteredRoutePolicy already set-up", routeId);
+ return null;
+ }
+ }
+
+ try {
+ final ClusteredRouteConfiguration configuration = configurations.getOrDefault(routeId, defaultConfiguration);
+ final String namespace = ObjectHelper.supplyIfEmpty(configuration.getNamespace(), defaultConfiguration::getNamespace);
+ final Duration initialDelay = ObjectHelper.supplyIfEmpty(configuration.getInitialDelay(), defaultConfiguration::getInitialDelay);
+
+ ClusteredRoutePolicy policy = new ClusteredRoutePolicy(clusterService.getView(namespace));
+ policy.setCamelContext(getCamelContext());
+ policy.setInitialDelay(initialDelay);
+
+ LOGGER.debug("Attaching route '{}' to namespace '{}'", routeId, namespace);
+
+ routes.add(routeId);
+
+ return policy;
+ } catch (Exception e) {
+ throw ObjectHelper.wrapRuntimeCamelException(e);
+ }
+ }
+
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRouteFilter.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRouteFilter.java b/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRouteFilter.java
new file mode 100644
index 0000000..a6d3c01
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRouteFilter.java
@@ -0,0 +1,32 @@
+/**
+ * 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.ha;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.model.RouteDefinition;
+
+public interface ClusteredRouteFilter {
+ /**
+ * Test if the route should be clustered or not.
+ *
+ * @param camelContext the camel context
+ * @param routeId the route id
+ * @param route the route definition
+ * @return true if the route should be included
+ */
+ boolean test(CamelContext camelContext, String routeId, RouteDefinition route);
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRouteFilters.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRouteFilters.java b/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRouteFilters.java
new file mode 100644
index 0000000..ccda0e1
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRouteFilters.java
@@ -0,0 +1,59 @@
+/**
+ * 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.ha;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.util.ObjectHelper;
+
+public final class ClusteredRouteFilters {
+ private ClusteredRouteFilters() {
+ }
+
+ public static final class IsAutoStartup implements ClusteredRouteFilter {
+ @Override
+ public boolean test(CamelContext camelContext, String routeId, RouteDefinition route) {
+ try {
+ return route.isAutoStartup(camelContext);
+ } catch (Exception e) {
+ throw ObjectHelper.wrapRuntimeCamelException(e);
+ }
+ }
+ }
+
+ public static final class BlackList implements ClusteredRouteFilter {
+ 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 boolean test(CamelContext camelContext, String routeId, RouteDefinition route) {
+ return !names.contains(routeId);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRoutePolicy.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRoutePolicy.java b/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRoutePolicy.java
index 542b15b..e85b3bf 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRoutePolicy.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/ha/ClusteredRoutePolicy.java
@@ -16,14 +16,19 @@
*/
package org.apache.camel.impl.ha;
+import java.time.Duration;
import java.util.EventObject;
import java.util.HashSet;
import java.util.Set;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
import org.apache.camel.CamelContext;
import org.apache.camel.CamelContextAware;
import org.apache.camel.Route;
+import org.apache.camel.ServiceStatus;
import org.apache.camel.StartupListener;
import org.apache.camel.api.management.ManagedAttribute;
import org.apache.camel.api.management.ManagedResource;
@@ -39,7 +44,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ManagedResource(description = "Clustered Route policy using")
-public final class ClusteredRoutePolicy extends RoutePolicySupport implements CamelContextAware {
+public class ClusteredRoutePolicy extends RoutePolicySupport implements CamelContextAware {
private static final Logger LOGGER = LoggerFactory.getLogger(ClusteredRoutePolicy.class);
private final AtomicBoolean leader;
@@ -50,6 +55,8 @@ public final class ClusteredRoutePolicy extends RoutePolicySupport implements Ca
private final CamelClusterEventListener.Leadership leadershipEventListener;
private final CamelContextStartupListener listener;
private final AtomicBoolean contextStarted;
+ private Duration initialDelay;
+ private ScheduledExecutorService executorService;
private CamelContext camelContext;
@@ -61,6 +68,7 @@ public final class ClusteredRoutePolicy extends RoutePolicySupport implements Ca
this.startedRoutes = new HashSet<>();
this.leader = new AtomicBoolean(false);
this.contextStarted = new AtomicBoolean(false);
+ this.initialDelay = Duration.ofMillis(0);
try {
this.listener = new CamelContextStartupListener();
@@ -74,6 +82,9 @@ public final class ClusteredRoutePolicy extends RoutePolicySupport implements Ca
this.refCount = ReferenceCount.onRelease(() -> {
if (camelContext != null) {
camelContext.getManagementStrategy().removeEventNotifier(listener);
+ if (executorService != null) {
+ camelContext.getExecutorServiceManager().shutdownNow(executorService);
+ }
}
clusterView.removeEventListener(leadershipEventListener);
@@ -102,11 +113,24 @@ public final class ClusteredRoutePolicy extends RoutePolicySupport implements Ca
this.camelContext = camelContext;
this.camelContext.addStartupListener(this.listener);
this.camelContext.getManagementStrategy().addEventNotifier(this.listener);
+ this.executorService = camelContext.getExecutorServiceManager().newSingleThreadScheduledExecutor(this, "ClusteredRoutePolicy");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
+ public Duration getInitialDelay() {
+ return initialDelay;
+ }
+
+ public void setInitialDelay(Duration initialDelay) {
+ this.initialDelay = initialDelay;
+ }
+
+ // ****************************************************
+ // life-cycle
+ // ****************************************************
+
@Override
public void onInit(Route route) {
super.onInit(route);
@@ -121,7 +145,7 @@ public final class ClusteredRoutePolicy extends RoutePolicySupport implements Ca
}
@Override
- public void doShutdown() {
+ public void doShutdown() throws Exception {
this.refCount.release();
}
@@ -159,11 +183,19 @@ public final class ClusteredRoutePolicy extends RoutePolicySupport implements Ca
}
private void doStartManagedRoutes() {
+ if (!isRunAllowed()) {
+ return;
+ }
+
try {
for (Route route : stoppedRoutes) {
- LOGGER.debug("Starting route {}", route.getId());
- camelContext.startRoute(route.getId());
- startedRoutes.add(route);
+ ServiceStatus status = route.getRouteContext().getRoute().getStatus(getCamelContext());
+ if (status.isStartable()) {
+ LOGGER.debug("Starting route '{}'", route.getId());
+ camelContext.startRoute(route.getId());
+
+ startedRoutes.add(route);
+ }
}
stoppedRoutes.removeAll(startedRoutes);
@@ -183,11 +215,19 @@ public final class ClusteredRoutePolicy extends RoutePolicySupport implements Ca
}
private void doStopManagedRoutes() {
+ if (!isRunAllowed()) {
+ return;
+ }
+
try {
for (Route route : startedRoutes) {
- LOGGER.debug("Stopping route {}", route.getId());
- stopRoute(route);
- stoppedRoutes.add(route);
+ ServiceStatus status = route.getRouteContext().getRoute().getStatus(getCamelContext());
+ if (status.isStoppable()) {
+ LOGGER.debug("Stopping route '{}'", route.getId());
+ stopRoute(route);
+
+ stoppedRoutes.add(route);
+ }
}
startedRoutes.removeAll(stoppedRoutes);
@@ -196,6 +236,16 @@ public final class ClusteredRoutePolicy extends RoutePolicySupport implements Ca
}
}
+ private void onCamelContextStarted() {
+ LOGGER.debug("Apply cluster policy (stopped-routes='{}', started-routes='{}')",
+ stoppedRoutes.stream().map(Route::getId).collect(Collectors.joining(",")),
+ startedRoutes.stream().map(Route::getId).collect(Collectors.joining(","))
+ );
+
+ clusterView.addEventListener(leadershipEventListener);
+ setLeader(clusterView.getLocalMember().isMaster());
+ }
+
// ****************************************************
// Event handling
// ****************************************************
@@ -240,8 +290,14 @@ public final class ClusteredRoutePolicy extends RoutePolicySupport implements Ca
// so start/stop of managed routes do not clash with CamelContext
// startup
if (contextStarted.compareAndSet(false, true)) {
- clusterView.addEventListener(leadershipEventListener);
- setLeader(clusterView.getLocalMember().isMaster());
+
+ // Eventually delay the startup of the routes a later time
+ if (initialDelay.toMillis() > 0) {
+ LOGGER.debug("Policy will be effective in {}", initialDelay);
+ executorService.schedule(ClusteredRoutePolicy.this::onCamelContextStarted, initialDelay.toMillis(), TimeUnit.MILLISECONDS);
+ } else {
+ ClusteredRoutePolicy.this.onCamelContextStarted();
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/components/camel-atomix/src/main/java/org/apache/camel/component/atomix/ha/AtomixClusterClientService.java
----------------------------------------------------------------------
diff --git a/components/camel-atomix/src/main/java/org/apache/camel/component/atomix/ha/AtomixClusterClientService.java b/components/camel-atomix/src/main/java/org/apache/camel/component/atomix/ha/AtomixClusterClientService.java
index 6194f81..6df320f 100644
--- a/components/camel-atomix/src/main/java/org/apache/camel/component/atomix/ha/AtomixClusterClientService.java
+++ b/components/camel-atomix/src/main/java/org/apache/camel/component/atomix/ha/AtomixClusterClientService.java
@@ -113,6 +113,16 @@ public final class AtomixClusterClientService extends AbstractCamelClusterServic
}
@Override
+ protected void doStop() throws Exception {
+ super.doStop();
+
+ if (atomix != null) {
+ LOGGER.debug("Shutdown atomix client {}", atomix);
+ atomix.close().join();
+ }
+ }
+
+ @Override
protected AtomixClusterView createView(String namespace) throws Exception {
return new AtomixClusterView(this, namespace, getOrCreateClient(), configuration);
}
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/components/camel-atomix/src/main/java/org/apache/camel/component/atomix/ha/AtomixClusterService.java
----------------------------------------------------------------------
diff --git a/components/camel-atomix/src/main/java/org/apache/camel/component/atomix/ha/AtomixClusterService.java b/components/camel-atomix/src/main/java/org/apache/camel/component/atomix/ha/AtomixClusterService.java
index 3faf79e..b2315ae 100644
--- a/components/camel-atomix/src/main/java/org/apache/camel/component/atomix/ha/AtomixClusterService.java
+++ b/components/camel-atomix/src/main/java/org/apache/camel/component/atomix/ha/AtomixClusterService.java
@@ -143,6 +143,16 @@ public final class AtomixClusterService extends AbstractCamelClusterService<Atom
}
@Override
+ protected void doStop() throws Exception {
+ super.doStop();
+
+ if (atomix != null) {
+ LOGGER.debug("Shutdown atomix replica {}", atomix);
+ atomix.shutdown().join();
+ }
+ }
+
+ @Override
protected AtomixClusterView createView(String namespace) throws Exception {
return new AtomixClusterView(this, namespace, getOrCreateReplica(), configuration);
}
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/components/camel-atomix/src/main/java/org/apache/camel/component/atomix/ha/AtomixClusterView.java
----------------------------------------------------------------------
diff --git a/components/camel-atomix/src/main/java/org/apache/camel/component/atomix/ha/AtomixClusterView.java b/components/camel-atomix/src/main/java/org/apache/camel/component/atomix/ha/AtomixClusterView.java
index 4f02a85..4be80a1 100644
--- a/components/camel-atomix/src/main/java/org/apache/camel/component/atomix/ha/AtomixClusterView.java
+++ b/components/camel-atomix/src/main/java/org/apache/camel/component/atomix/ha/AtomixClusterView.java
@@ -93,13 +93,25 @@ final class AtomixClusterView extends AbstractCamelClusterView {
).get();
LOGGER.debug("Listen election events");
- group.election().onElection(term -> fireLeadershipChangedEvent(new AtomixClusterMember(term.leader())));
+ group.election().onElection(term -> {
+ if (isRunAllowed()) {
+ fireLeadershipChangedEvent(new AtomixClusterMember(term.leader()));
+ }
+ });
LOGGER.debug("Listen join events");
- group.onJoin(member -> fireMemberAddedEvent(new AtomixClusterMember(member)));
+ group.onJoin(member -> {
+ if (isRunAllowed()) {
+ fireMemberAddedEvent(new AtomixClusterMember(member));
+ }
+ });
LOGGER.debug("Listen leave events");
- group.onLeave(member -> fireMemberRemovedEvent(new AtomixClusterMember(member)));
+ group.onLeave(member -> {
+ if (isRunAllowed()) {
+ fireMemberRemovedEvent(new AtomixClusterMember(member));
+ }
+ });
LOGGER.debug("Join group {}", getNamespace());
localMember.join();
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/ha/ClusteredRouteControllerAutoConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/ha/ClusteredRouteControllerAutoConfiguration.java b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/ha/ClusteredRouteControllerAutoConfiguration.java
new file mode 100644
index 0000000..29be993
--- /dev/null
+++ b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/ha/ClusteredRouteControllerAutoConfiguration.java
@@ -0,0 +1,101 @@
+/**
+ * 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.spring.boot.ha;
+
+import java.time.Duration;
+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.ha.CamelClusterService;
+import org.apache.camel.impl.ha.ClusteredRouteConfiguration;
+import org.apache.camel.impl.ha.ClusteredRouteController;
+import org.apache.camel.impl.ha.ClusteredRouteFilter;
+import org.apache.camel.impl.ha.ClusteredRouteFilters;
+import org.apache.camel.spi.RouteController;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.camel.util.ObjectHelper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Scope;
+
+@Configuration
+@AutoConfigureBefore(CamelAutoConfiguration.class)
+@ConditionalOnProperty(prefix = "camel.clustered.controller", name = "enabled")
+@EnableConfigurationProperties(ClusteredRouteControllerConfiguration.class)
+public class ClusteredRouteControllerAutoConfiguration {
+ @Autowired
+ private ClusteredRouteControllerConfiguration configuration;
+ @Autowired(required = false)
+ private List<ClusteredRouteFilter> filters = Collections.emptyList();
+
+ @Bean
+ @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
+ @ConditionalOnMissingBean
+ @ConditionalOnBean(CamelClusterService.class)
+ public RouteController routeController() {
+ ClusteredRouteController controller = new ClusteredRouteController();
+ controller.setNamespace(configuration.getNamespace());
+
+ Optional.ofNullable(configuration.getInitialDelay())
+ .map(TimePatternConverter::toMilliSeconds)
+ .map(Duration::ofMillis)
+ .ifPresent(controller::setInitialDelay);
+
+ controller.setFilters(filters);
+ controller.addFilter(new ClusteredRouteFilters.IsAutoStartup());
+
+ if (ObjectHelper.isEmpty(configuration.getClusterService())) {
+ controller.setClusterService(configuration.getClusterService());
+ }
+
+ for (Map.Entry<String, ClusteredRouteControllerConfiguration.RouteConfiguration> entry: configuration.getRoutes().entrySet()) {
+ final String routeId = entry.getKey();
+ final ClusteredRouteControllerConfiguration.RouteConfiguration conf = entry.getValue();
+
+ if (conf.isClustered()) {
+ ClusteredRouteConfiguration routeConfiguration = new ClusteredRouteConfiguration();
+
+ routeConfiguration.setNamespace(
+ Optional.ofNullable(conf.getNamespace())
+ .orElseGet(controller::getNamespace)
+ );
+ routeConfiguration.setInitialDelay(
+ Optional.ofNullable(conf.getInitialDelay())
+ .map(TimePatternConverter::toMilliSeconds)
+ .map(Duration::ofMillis)
+ .orElseGet(controller::getInitialDelay)
+ );
+
+ controller.addRouteConfiguration(routeId, routeConfiguration);
+ } else {
+ controller.addFilter(new ClusteredRouteFilters.BlackList(routeId));
+ }
+ }
+
+ return controller;
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/ha/ClusteredRouteControllerConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/ha/ClusteredRouteControllerConfiguration.java b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/ha/ClusteredRouteControllerConfiguration.java
new file mode 100644
index 0000000..946c20d
--- /dev/null
+++ b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/ha/ClusteredRouteControllerConfiguration.java
@@ -0,0 +1,147 @@
+/**
+ * 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.spring.boot.ha;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.ha.CamelClusterService;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties(prefix = "camel.clustered.controller")
+public class ClusteredRouteControllerConfiguration {
+ /**
+ * Global option to enable/disable this ${@link org.apache.camel.spi.RouteController}, default is false.
+ */
+ private boolean enabled;
+
+ /**
+ * Set the amount of time the route controller should wait before to start
+ * the routes after the camel context is started or after the route is
+ * initialized if the route is created after the camel context is started.
+ */
+ private String initialDelay;
+
+ /**
+ * The default namespace.
+ */
+ private String namespace;
+
+ /**
+ * The reference to a cluster service.
+ */
+ private String clusterServiceRef;
+
+ /**
+ * The cluster service.
+ */
+ private CamelClusterService clusterService;
+
+ /**
+ * Routes configuration.
+ */
+ private Map<String, RouteConfiguration> routes = new HashMap<>();
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public String getInitialDelay() {
+ return initialDelay;
+ }
+
+ public void setInitialDelay(String initialDelay) {
+ this.initialDelay = initialDelay;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+
+ public Map<String, RouteConfiguration> getRoutes() {
+ return routes;
+ }
+
+ public void setRoutes(Map<String, RouteConfiguration> routes) {
+ this.routes = routes;
+ }
+
+ public CamelClusterService getClusterService() {
+ return clusterService;
+ }
+
+ public void setClusterService(CamelClusterService clusterService) {
+ this.clusterService = clusterService;
+ }
+
+ // *****************************************
+ // Configuration Classes
+ // *****************************************
+
+ public static class RouteConfiguration {
+ /**
+ * Control if the route should be clustered or not, default is true.
+ */
+ private boolean clustered = true;
+
+ /**
+ * Set the amount of time the route controller should wait before to start
+ * the routes after the camel context is started or after the route is
+ * initialized if the route is created after the camel context is started.
+ */
+ private String initialDelay;
+
+ /**
+ * The default namespace.
+ */
+ private String namespace;
+
+
+ public boolean isClustered() {
+ return clustered;
+ }
+
+ public void setClustered(boolean clustered) {
+ this.clustered = clustered;
+ }
+
+ public String getInitialDelay() {
+ return initialDelay;
+ }
+
+ public void setInitialDelay(String initialDelay) {
+ this.initialDelay = initialDelay;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/components/camel-spring-boot/src/main/resources/META-INF/spring.factories
----------------------------------------------------------------------
diff --git a/components/camel-spring-boot/src/main/resources/META-INF/spring.factories b/components/camel-spring-boot/src/main/resources/META-INF/spring.factories
index ac8c58e..9686cc3 100644
--- a/components/camel-spring-boot/src/main/resources/META-INF/spring.factories
+++ b/components/camel-spring-boot/src/main/resources/META-INF/spring.factories
@@ -26,4 +26,5 @@ org.apache.camel.spring.boot.cloud.CamelCloudServiceCallConfigurationAutoConfigu
org.apache.camel.spring.boot.cloud.CamelCloudServiceDiscoveryAutoConfiguration,\
org.apache.camel.spring.boot.cloud.CamelCloudServiceFilterAutoConfiguration,\
org.apache.camel.spring.boot.cloud.CamelCloudServiceChooserAutoConfiguration,\
+org.apache.camel.spring.boot.ha.ClusteredRouteControllerAutoConfiguration,\
org.apache.camel.spring.boot.security.CamelSSLAutoConfiguration
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/README.adoc
----------------------------------------------------------------------
diff --git a/examples/README.adoc b/examples/README.adoc
index bb2568c..1f10378 100644
--- a/examples/README.adoc
+++ b/examples/README.adoc
@@ -11,7 +11,7 @@ View the individual example READMEs for details.
### Examples
// examples: START
-Number of Examples: 96 (8 deprecated)
+Number of Examples: 97 (8 deprecated)
[width="100%",cols="4,2,4",options="header"]
|=======================================================================
@@ -44,11 +44,13 @@ Number of Examples: 96 (8 deprecated)
| link:camel-example-spring-boot/readme.adoc[Spring Boot] (camel-example-spring-boot) | Beginner | An example showing how to work with Camel and Spring Boot
+| link:camel-example-spring-boot-clustered-route-controller/readme.adoc[Spring Boot Clustered Route Controller] (camel-example-spring-boot-clustered-route-controller) | Beginner | An example showing how to work with Camel's Clustered Route Controller and Spring Boot
+
| link:camel-example-spring-boot-live-reload/readme.adoc[Spring Boot Live Reload] (camel-example-spring-boot-live-reload) | Beginner | An example showing how to use the live reload feature of Spring Boot with Camel
| link:camel-example-spring-boot-pojo/README.adoc[Spring Boot Pojo] (camel-example-spring-boot-pojo) | Beginner | An example showing how to work with Camel POJO routing with Spring Boot
-| link:camel-example-spring-boot-routecontroller/readme.adoc[Spring Boot Routecontroller] (camel-example-spring-boot-routecontroller) | Beginner | An example showing how to work with Camel Route Controller and Spring Boot
+| link:camel-example-spring-boot-supervising-route-controller/readme.adoc[Spring Boot Supervising Route Controller] (camel-example-spring-boot-supervising-route-controller) | Beginner | An example showing how to work with Camel's Supervising Route Controller and Spring Boot
| link:camel-example-spring-javaconfig/README.md[Spring Java Config] (camel-example-spring-javaconfig) | Beginner | An example showing how to work with Camel and Spring Java Config
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/camel-example-spring-boot-clustered-route-controller/cluster-bootstrap/pom.xml
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-clustered-route-controller/cluster-bootstrap/pom.xml b/examples/camel-example-spring-boot-clustered-route-controller/cluster-bootstrap/pom.xml
new file mode 100644
index 0000000..f86fb3b
--- /dev/null
+++ b/examples/camel-example-spring-boot-clustered-route-controller/cluster-bootstrap/pom.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.camel.example</groupId>
+ <artifactId>camel-example-spring-boot-clustered-route-controller</artifactId>
+ <version>2.20.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>camel-example-spring-boot-clustered-route-controller-cluster-bootstrap</artifactId>
+ <name>Camel :: Example :: Spring Boot :: Clustered Route Controller :: Cluster Bootstrap</name>
+ <description>Bootstrap an Atomix Cluster (single node)</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>io.atomix</groupId>
+ <artifactId>atomix-all</artifactId>
+ <version>${atomix-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.6.0</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>java</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <includeProjectDependencies>true</includeProjectDependencies>
+ <mainClass>org.apache.camel.examples.cluster.ClusterBootstrap</mainClass>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/camel-example-spring-boot-clustered-route-controller/cluster-bootstrap/src/main/java/org/apache/camel/examples/cluster/ClusterBootstrap.java
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-clustered-route-controller/cluster-bootstrap/src/main/java/org/apache/camel/examples/cluster/ClusterBootstrap.java b/examples/camel-example-spring-boot-clustered-route-controller/cluster-bootstrap/src/main/java/org/apache/camel/examples/cluster/ClusterBootstrap.java
new file mode 100644
index 0000000..1115524
--- /dev/null
+++ b/examples/camel-example-spring-boot-clustered-route-controller/cluster-bootstrap/src/main/java/org/apache/camel/examples/cluster/ClusterBootstrap.java
@@ -0,0 +1,41 @@
+/**
+ * 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.examples.cluster;
+
+import io.atomix.AtomixReplica;
+import io.atomix.catalyst.transport.Address;
+import io.atomix.catalyst.transport.netty.NettyTransport;
+import io.atomix.copycat.server.storage.Storage;
+import io.atomix.copycat.server.storage.StorageLevel;
+
+public final class ClusterBootstrap {
+ private ClusterBootstrap() {
+ }
+
+ public static void main(String[] args) {
+ String address = System.getProperty("cluster.address", "127.0.0.1:8700");
+
+ AtomixReplica.builder(new Address(address))
+ .withTransport(new NettyTransport())
+ .withStorage(Storage.builder()
+ .withStorageLevel(StorageLevel.MEMORY)
+ .build())
+ .build()
+ .bootstrap()
+ .join();
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/camel-example-spring-boot-clustered-route-controller/cluster-bootstrap/src/main/resources/log4j2.xml
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-clustered-route-controller/cluster-bootstrap/src/main/resources/log4j2.xml b/examples/camel-example-spring-boot-clustered-route-controller/cluster-bootstrap/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..06e8664
--- /dev/null
+++ b/examples/camel-example-spring-boot-clustered-route-controller/cluster-bootstrap/src/main/resources/log4j2.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="INFO">
+ <Appenders>
+ <Console name="Console" target="SYSTEM_OUT">
+ <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
+ </Console>
+ <File name="File" fileName="target/cluster-bootstrap.log" immediateFlush="false" append="false">
+ <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
+ </File>
+ </Appenders>
+ <Loggers>
+ <Logger name="io.atomix" level="DEBUG"/>
+
+ <Root level="INFO">
+ <AppenderRef ref="Console" />
+ </Root>
+ </Loggers>
+</Configuration>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/camel-example-spring-boot-clustered-route-controller/cluster-node/pom.xml
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-clustered-route-controller/cluster-node/pom.xml b/examples/camel-example-spring-boot-clustered-route-controller/cluster-node/pom.xml
new file mode 100644
index 0000000..c137031
--- /dev/null
+++ b/examples/camel-example-spring-boot-clustered-route-controller/cluster-node/pom.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.camel.example</groupId>
+ <artifactId>camel-example-spring-boot-clustered-route-controller</artifactId>
+ <version>2.20.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>camel-example-spring-boot-clustered-route-controller-cluster-node</artifactId>
+ <name>Camel :: Example :: Spring Boot :: Clustered Route Controller :: Cluster Node</name>
+ <description>Bootstrap an Camel Cluster Node</description>
+
+ <dependencyManagement>
+ <dependencies>
+ <!-- Spring Boot BOM -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-dependencies</artifactId>
+ <version>${spring.boot-version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <!-- Camel BOM -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-spring-boot-dependencies</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-undertow</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-actuator</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-spring-boot-starter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-atomix-starter</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${spring-boot-version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/camel-example-spring-boot-clustered-route-controller/cluster-node/src/main/java/org/apache/camel/examples/cluster/ClusterNode.java
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-clustered-route-controller/cluster-node/src/main/java/org/apache/camel/examples/cluster/ClusterNode.java b/examples/camel-example-spring-boot-clustered-route-controller/cluster-node/src/main/java/org/apache/camel/examples/cluster/ClusterNode.java
new file mode 100644
index 0000000..7228dc3
--- /dev/null
+++ b/examples/camel-example-spring-boot-clustered-route-controller/cluster-node/src/main/java/org/apache/camel/examples/cluster/ClusterNode.java
@@ -0,0 +1,36 @@
+/**
+ * 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.examples.cluster;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+//CHECKSTYLE:OFF
+/**
+ * A sample Spring Boot application that starts the Camel routes.
+ */
+@SpringBootApplication
+public class ClusterNode {
+
+ /**
+ * A main method to start this application.
+ */
+ public static void main(String[] args) {
+ SpringApplication.run(ClusterNode.class, args);
+ }
+}
+//CHECKSTYLE:ON
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/camel-example-spring-boot-clustered-route-controller/cluster-node/src/main/java/org/apache/camel/examples/cluster/ClusterNodeConfiguration.java
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-clustered-route-controller/cluster-node/src/main/java/org/apache/camel/examples/cluster/ClusterNodeConfiguration.java b/examples/camel-example-spring-boot-clustered-route-controller/cluster-node/src/main/java/org/apache/camel/examples/cluster/ClusterNodeConfiguration.java
new file mode 100644
index 0000000..e7df7be
--- /dev/null
+++ b/examples/camel-example-spring-boot-clustered-route-controller/cluster-node/src/main/java/org/apache/camel/examples/cluster/ClusterNodeConfiguration.java
@@ -0,0 +1,68 @@
+/**
+ * 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.examples.cluster;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class ClusterNodeConfiguration {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ClusterNodeConfiguration.class);
+
+ @Bean
+ public RouteBuilder routeBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ // This route is configured to be local (see application.properties)
+ // so it will be started regardless of the leadership status if
+ // this node.
+ from("timer:heartbeat?period=10s")
+ .routeId("heartbeat")
+ .log("HeartBeat route (timer) {{node.id}} ...");
+
+ // This route is configured to be clustered so it will be started
+ // by the controller only when this node is leader
+ from("timer:clustered?period=5s")
+ .routeId("clustered")
+ .log("Clustered route (timer) {{node.id}} ...");
+ }
+ };
+ }
+
+ /**
+ * A small hack to find out the a free port so you can run multiple instances
+ * of the example without having to manually set the property: server.port
+ */
+ @Bean
+ public EmbeddedServletContainerCustomizer containerCustomizer() {
+ return container -> {
+ try (ServerSocket socket = new ServerSocket(0)) {
+ LOGGER.debug("server.port: {}", socket.getLocalPort());
+ container.setPort(socket.getLocalPort());
+ } catch (IOException ignored) {
+ }
+ };
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/camel-example-spring-boot-clustered-route-controller/cluster-node/src/main/resources/application.properties
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-clustered-route-controller/cluster-node/src/main/resources/application.properties b/examples/camel-example-spring-boot-clustered-route-controller/cluster-node/src/main/resources/application.properties
new file mode 100644
index 0000000..e364efa
--- /dev/null
+++ b/examples/camel-example-spring-boot-clustered-route-controller/cluster-node/src/main/resources/application.properties
@@ -0,0 +1,31 @@
+
+debug = false
+
+logging.level.org.springframework = INFO
+logging.level.io.atomix = DEBUG
+logging.level.org.apache.camel.ha = DEBUG
+logging.level.org.apache.camel.impl.ha = DEBUG
+logging.level.org.apache.camel.component.atomix = DEBUG
+logging.level.org.apache.camel.examples.cluster = DEBUG
+
+endpoints.enabled = false
+endpoints.jmx.enabled = false
+endpoints.health.enabled = true
+
+management.port = -1
+
+node.id = ${random.uuid}
+
+camel.springboot.name = SampleClusteredRouteController
+camel.springboot.jmx-enabled = false
+
+camel.clustered.controller.enabled = true
+camel.clustered.controller.namespace = camel
+camel.clustered.controller.initial-delay = 5s
+
+camel.clustered.controller.routes.heartbeat.clustered = false
+
+camel.clustered.service.atomix.enabled = true
+camel.clustered.service.atomix.mode = client
+camel.clustered.service.atomix.nodes = localhost:8700
+camel.clustered.service.atomix.id = ${node.id}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/camel-example-spring-boot-clustered-route-controller/pom.xml
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-clustered-route-controller/pom.xml b/examples/camel-example-spring-boot-clustered-route-controller/pom.xml
new file mode 100644
index 0000000..c27d554
--- /dev/null
+++ b/examples/camel-example-spring-boot-clustered-route-controller/pom.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.camel.example</groupId>
+ <artifactId>examples</artifactId>
+ <version>2.20.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>camel-example-spring-boot-clustered-route-controller</artifactId>
+ <name>Camel :: Example :: Spring Boot :: Clustered Route Controller</name>
+ <description>An example showing how to work with Camel's Clustered Route Controller and Spring Boot</description>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>cluster-bootstrap</module>
+ <module>cluster-node</module>
+ </modules>
+ <properties>
+ <category>Beginner</category>
+
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ <spring.boot-version>${spring-boot-version}</spring.boot-version>
+ </properties>
+
+
+
+ <profiles>
+ <profile>
+ <id>jdk9-build</id>
+ <activation>
+ <jdk>9</jdk>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <argLine>--add-modules java.xml.bind --add-opens java.base/java.lang=ALL-UNNAMED</argLine>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/camel-example-spring-boot-clustered-route-controller/readme.adoc
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-clustered-route-controller/readme.adoc b/examples/camel-example-spring-boot-clustered-route-controller/readme.adoc
new file mode 100644
index 0000000..38cc96f
--- /dev/null
+++ b/examples/camel-example-spring-boot-clustered-route-controller/readme.adoc
@@ -0,0 +1,25 @@
+# Camel Clustered Route Controller Example Spring Boot
+
+This example shows how to work with a simple Apache Camel application using Spring Boot and a Clustered Route Controller.
+
+## How to run
+
+1. build the project:
++
+ mvn clean package
+
+2. in a shell, run the cluster node
++
+ mvn -pl cluster-bootstrap exec:java
+
+3. in a separate shell, run the first camel node
++
+ mvn -pl cluster-node spring-boot:run
+
+4. in a separate shell, run the second camel node
++
+ mvn -pl cluster-node spring-boot:run
+
+## More information
+
+You can find more information about Apache Camel at the website: http://camel.apache.org/
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/camel-example-spring-boot-routecontroller/pom.xml
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-routecontroller/pom.xml b/examples/camel-example-spring-boot-routecontroller/pom.xml
deleted file mode 100644
index b30b67e..0000000
--- a/examples/camel-example-spring-boot-routecontroller/pom.xml
+++ /dev/null
@@ -1,154 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.apache.camel.example</groupId>
- <artifactId>examples</artifactId>
- <version>2.20.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>camel-example-spring-boot-routecontroller</artifactId>
- <name>Camel :: Example :: Spring Boot :: Route Controller</name>
- <description>An example showing how to work with Camel Route Controller and Spring Boot</description>
-
- <properties>
- <category>Beginner</category>
-
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <spring.boot-version>${spring-boot-version}</spring.boot-version>
- </properties>
-
- <dependencyManagement>
- <dependencies>
- <!-- Spring Boot BOM -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-dependencies</artifactId>
- <version>${spring.boot-version}</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- <!-- Camel BOM -->
- <dependency>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-spring-boot-dependencies</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
-
- <dependencies>
-
- <dependency>
- <groupId>org.jolokia</groupId>
- <artifactId>jolokia-core</artifactId>
- </dependency>
-
- <!-- Spring Boot -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-undertow</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-actuator</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-configuration-processor</artifactId>
- <optional>true</optional>
- <version>${spring-boot-version}</version>
- </dependency>
-
- <!-- Camel -->
- <dependency>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-spring-boot-starter</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-undertow-starter</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-stream-starter</artifactId>
- </dependency>
-
- <!-- test -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-test-spring</artifactId>
- <scope>test</scope>
- </dependency>
-
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- <version>${spring-boot-version}</version>
- <executions>
- <execution>
- <goals>
- <goal>repackage</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
- <profiles>
- <profile>
- <id>jdk9-build</id>
- <activation>
- <jdk>9</jdk>
- </activation>
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <argLine>--add-modules java.xml.bind --add-opens java.base/java.lang=ALL-UNNAMED</argLine>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-</project>
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/camel-example-spring-boot-routecontroller/readme.adoc
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-routecontroller/readme.adoc b/examples/camel-example-spring-boot-routecontroller/readme.adoc
deleted file mode 100644
index f94221d..0000000
--- a/examples/camel-example-spring-boot-routecontroller/readme.adoc
+++ /dev/null
@@ -1,51 +0,0 @@
-# Camel Route Controller Example Spring Boot
-
-This example shows how to work with a simple Apache Camel application using Spring Boot and a Route Controller.
-
-## How to run
-
-You can run this example using
-
- mvn spring-boot:run
-
-Beside JMX you can use Spring Boot Endpoints to interact with the routes:
-
-* To get info about the routes
-+
-[source]
-----
-curl -XGET -s http://localhost:8080/camel/routes
-----
-+
-+* To get details about a route
-++
-+[source]
-+----
-+curl -XGET -s http://localhost:8080/camel/routes/{id}/detail
-+----
-
-* To get info about a route
-+
-[source]
-----
-curl -XGET -s http://localhost:8080/camel/routes/{id}/info
-----
-
-* To stop a route
-+
-[source]
-----
-curl -XPOST -s http://localhost:8080/camel/routes/{id}/stop
-----
-
-* To start a route
-+
-[source]
-----
-curl -XPOST -s http://localhost:8080/camel/routes/{id}/stop
-----
-
-
-## More information
-
-You can find more information about Apache Camel at the website: http://camel.apache.org/
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/camel-example-spring-boot-routecontroller/src/main/java/sample/camel/Application.java
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-routecontroller/src/main/java/sample/camel/Application.java b/examples/camel-example-spring-boot-routecontroller/src/main/java/sample/camel/Application.java
deleted file mode 100644
index 2a97fed..0000000
--- a/examples/camel-example-spring-boot-routecontroller/src/main/java/sample/camel/Application.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * 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 sample.camel;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-//CHECKSTYLE:OFF
-/**
- * A sample Spring Boot application that starts the Camel routes.
- */
-@SpringBootApplication
-public class Application {
-
- /**
- * A main method to start this application.
- */
- public static void main(String[] args) {
- SpringApplication.run(Application.class, args);
- }
-
-}
-//CHECKSTYLE:ON
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/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
deleted file mode 100644
index fb6e2f5..0000000
--- a/examples/camel-example-spring-boot-routecontroller/src/main/java/sample/camel/ApplicationRoutes.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * 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 sample.camel;
-
-import org.apache.camel.builder.RouteBuilder;
-import org.springframework.stereotype.Component;
-
-/**
- *
- */
-@Component
-public class ApplicationRoutes extends RouteBuilder {
- @Override
- public void configure() throws Exception {
- from("timer:foo?period=5s")
- .id("foo")
- .startupOrder(2)
- .log("From timer (foo) ...");
-
- from("timer:bar?period=5s")
- .id("bar")
- .startupOrder(1)
- .log("From timer (bar) ...");
-
- from("undertow:http://localhost:9011")
- .id("undertow")
- .log("From undertow ...");
-
- from("undertow:http://localhost:9012")
- .id("undertow2")
- .autoStartup(false)
- .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/d043c7d0/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
deleted file mode 100644
index 8533f6b..0000000
--- a/examples/camel-example-spring-boot-routecontroller/src/main/resources/application.properties
+++ /dev/null
@@ -1,46 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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.
-## ---------------------------------------------------------------------------
-
-debug = false
-
-logging.level.org.springframework = INFO
-logging.level.org.apache.camel.spring.boot = INFO
-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
-
-endpoints.enabled = false
-endpoints.jmx.enabled = false
-endpoints.health.enabled = true
-
-# camel routes is by default enabled
-# so you do not have to configure below
-# endpoints.camelroutes.path = /camel/routes
-# endpoints.camelroutes.enabled = true
-
-management.security.enabled = false
-
-camel.springboot.name = SampleSupervisingRouteController
-
-camel.supervising.controller.enabled = true
-camel.supervising.controller.initial-delay = 5s
-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
http://git-wip-us.apache.org/repos/asf/camel/blob/d043c7d0/examples/camel-example-spring-boot-supervising-route-controller/pom.xml
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-supervising-route-controller/pom.xml b/examples/camel-example-spring-boot-supervising-route-controller/pom.xml
new file mode 100644
index 0000000..6b231fe
--- /dev/null
+++ b/examples/camel-example-spring-boot-supervising-route-controller/pom.xml
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.camel.example</groupId>
+ <artifactId>examples</artifactId>
+ <version>2.20.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>camel-example-spring-boot-supervising-route-controller</artifactId>
+ <name>Camel :: Example :: Spring Boot :: Supervising Route Controller</name>
+ <description>An example showing how to work with Camel's Supervising Route Controller and Spring Boot</description>
+
+ <properties>
+ <category>Beginner</category>
+
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ <spring.boot-version>${spring-boot-version}</spring.boot-version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <!-- Spring Boot BOM -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-dependencies</artifactId>
+ <version>${spring.boot-version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <!-- Camel BOM -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-spring-boot-dependencies</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.jolokia</groupId>
+ <artifactId>jolokia-core</artifactId>
+ </dependency>
+
+ <!-- Spring Boot -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-undertow</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-actuator</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-configuration-processor</artifactId>
+ <optional>true</optional>
+ <version>${spring-boot-version}</version>
+ </dependency>
+
+ <!-- Camel -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-spring-boot-starter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-undertow-starter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-stream-starter</artifactId>
+ </dependency>
+
+ <!-- test -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test-spring</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${spring-boot-version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>jdk9-build</id>
+ <activation>
+ <jdk>9</jdk>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <argLine>--add-modules java.xml.bind --add-opens java.base/java.lang=ALL-UNNAMED</argLine>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>