This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-examples.git
The following commit(s) were added to refs/heads/master by this push: new 037bae6 Updated Cassandraql example to use Eclipse JKube new e33852f Merge pull request #12 from manusa/feat/update-cassandra-kubernetes 037bae6 is described below commit 037bae6047ba8a1ba1f39952563a3a05c9ab67b0 Author: manusa <m...@marcnuri.com> AuthorDate: Fri Aug 7 15:13:48 2020 +0200 Updated Cassandraql example to use Eclipse JKube (Fabric8-maven-plugin will soon be deprecated) --- .../camel-example-cassandra-kubernetes/README.adoc | 154 +++++++++++---------- .../camel-example-cassandra-kubernetes/pom.xml | 76 ++++++---- .../kubernetes/{fmp => jkube}/CqlPopulateBean.java | 14 +- .../RowProcessor.java} | 30 ++-- .../resources/META-INF/spring/camel-context.xml | 9 +- .../{fabric8 => jkube}/cassandra-service.yaml | 0 .../{fabric8 => jkube}/cassandra-statefulset.yaml | 5 +- examples/pom.xml | 1 + 8 files changed, 168 insertions(+), 121 deletions(-) diff --git a/examples/camel-example-cassandra-kubernetes/README.adoc b/examples/camel-example-cassandra-kubernetes/README.adoc index 33a5240..82d47a4 100644 --- a/examples/camel-example-cassandra-kubernetes/README.adoc +++ b/examples/camel-example-cassandra-kubernetes/README.adoc @@ -5,47 +5,52 @@ Apache Camel (Cassandraql component). This example is based on: -* Minikube 0.21.0 (Kubernetes version >= 1.7) -* Fabric8 Maven Plugin (version >= 3.5) +* Minikube 1.11.0 (Kubernetes version >= 1.17) +* https://www.eclipse.org/jkube[Eclipse JKube] -First thing you'll need to do is preparing the environment. +First thing you'll need to do is to prepare the environment. -Don't forget to use a bit more memory for your Minikube for running this -example: +Don't forget to use a bit more memory for your Minikube setup to run this +example smoothly: -.... +[source,sh] +---- $ minikube start --memory 5120 --cpus=4 -.... +---- Once your Minikube node is up and running you'll need to run the -following command. In your src/main/resource/fabric8/ folder you'll find -two yaml file. Run the following command using them: +following command. In your `src/main/resource/jkube/` folder you'll find +two yaml files. Run the following commands using them to prepare the Cassandra cluster: -.... -$ kubectl create -f src/main/resources/fabric8/cassandra-service.yaml -$ kubectl create -f src/main/resources/fabric8/cassandra-statefulset.yaml -.... +[source,sh] +---- +$ kubectl create -f src/main/resources/jkube/cassandra-service.yaml +$ kubectl create -f src/main/resources/jkube/cassandra-statefulset.yaml +---- To check the correct startup of the cluster run the following command: -.... -$ kubectl get statefulsets -NAME DESIRED CURRENT AGE -cassandra 2 2 2h -.... +[source,sh] +---- +$ kubectl get statefulsets.apps +NAME READY AGE +cassandra 2/2 3h44m +---- and check the status of the pods -.... +[source,sh] +---- $ kubectl get pods NAME READY STATUS RESTARTS AGE cassandra-0 1/1 Running 0 2h cassandra-1 1/1 Running 0 2h -.... +---- You can also verify the health of your cluster by running -.... +[source,sh] +---- $ kubectl exec <pod_name> -it nodetool status Datacenter: DC1-K8Demo ====================== @@ -54,76 +59,81 @@ Status=Up/Down -- Address Load Tokens Owns (effective) Host ID Rack UN 172.17.0.4 212.14 KiB 32 53.1% 9bf81ccd-4aa1-451b-b56e-c16c5ee04836 Rack1-K8Demo UN 172.17.0.6 170.08 KiB 32 46.9% 69cc6f60-9ccf-439d-a298-b79b643c1586 Rack1-K8Demo -.... +---- === Building and running -Navigate to the project folder and the example can be built with +Navigate to the project folder where the example can be built with -.... -mvn clean -Pkubernetes-install fabric8:deploy -.... +[source,sh] +---- +$ mvn clean -Pkubernetes-install k8s:deploy +---- -When the example runs in fabric8, you can use the Kubectl command tool +When the example runs in Kubernetes, you can use the Kubectl command tool to inspect the status To list all the running pods: -.... -kubectl get pods -.... - -Then find the name of the pod that runs this quickstart, and output the -logs from the running pods with: - -.... -kubectl logs <name of pod> -.... - -and you should see something like this: - -.... -2017-08-06 10:43:52,209 [main ] INFO ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1068e947: startup date [Sun Aug 06 10:43:52 UTC 2017]; root of context hierarchy -2017-08-06 10:43:52,244 [main ] INFO XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [META-INF/spring/camel-context.xml] -2017-08-06 10:43:53,425 [main ] INFO GuavaCompatibility - Detected Guava >= 19 in the classpath, using modern compatibility layer -2017-08-06 10:43:53,564 [main ] INFO ClockFactory - Using native clock to generate timestamps. -2017-08-06 10:43:53,639 [main ] INFO NettyUtil - Did not find Netty's native epoll transport in the classpath, defaulting to NIO. -2017-08-06 10:43:54,054 [main ] INFO DCAwareRoundRobinPolicy - Using data-center name 'DC1-K8Demo' for DCAwareRoundRobinPolicy (if this is incorrect, please provide the correct datacenter name with DCAwareRoundRobinPolicy constructor) -2017-08-06 10:43:54,056 [main ] INFO Cluster - New Cassandra host cassandra/172.17.0.2:9042 added -2017-08-06 10:43:54,056 [main ] INFO Cluster - New Cassandra host cassandra/172.17.0.4:9042 added -2017-08-06 10:43:56,845 [main ] INFO SpringCamelContext - Apache Camel 2.20.0-SNAPSHOT (CamelContext: camel-1) is starting -2017-08-06 10:43:56,846 [main ] INFO ManagedManagementStrategy - JMX is enabled -2017-08-06 10:43:57,105 [main ] INFO DefaultTypeConverter - Type converters loaded (core: 192, classpath: 1) -2017-08-06 10:43:57,225 [main ] INFO SpringCamelContext - StreamCaching is not in use. If using streams then its recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html -2017-08-06 10:43:57,230 [main ] INFO ClockFactory - Using native clock to generate timestamps. -2017-08-06 10:43:57,918 [main ] INFO DCAwareRoundRobinPolicy - Using data-center name 'DC1-K8Demo' for DCAwareRoundRobinPolicy (if this is incorrect, please provide the correct datacenter name with DCAwareRoundRobinPolicy constructor) -2017-08-06 10:43:57,920 [main ] INFO Cluster - New Cassandra host cassandra/172.17.0.2:9042 added -2017-08-06 10:43:57,920 [main ] INFO Cluster - New Cassandra host cassandra/172.17.0.4:9042 added -2017-08-06 10:43:58,488 [main ] INFO SpringCamelContext - Route: cassandra-route started and consuming from: timer://foo?period=5000 -2017-08-06 10:43:58,489 [main ] INFO SpringCamelContext - Total 1 routes, of which 1 are started. -2017-08-06 10:43:58,489 [main ] INFO SpringCamelContext - Apache Camel 2.20.0-SNAPSHOT (CamelContext: camel-1) started in 1.645 seconds -2017-08-06 10:43:58,492 [main ] INFO DefaultLifecycleProcessor - Starting beans in phase 2147483646 -2017-08-06 10:43:59,586 [2 - timer://foo] INFO cassandra-route - Query result set [Row[1, oscerd]] -2017-08-06 10:44:04,575 [2 - timer://foo] INFO cassandra-route - Query result set [Row[1, oscerd]] -2017-08-06 10:44:09,577 [2 - timer://foo] INFO cassandra-route - Query result set [Row[1, oscerd]] -.... +[source,sh] +---- +$ kubectl get pods +---- + +You can follow the log for the created Pod by running: + +[source,sh] +---- +$ mvn -Pkubernetes-install k8s:log +---- + +You should then see an output similar to this: + +[source,sh] +---- +[INFO] k8s: 2020-08-07 12:34:32,569 [main ] INFO GuavaCompatibility - Detected Guava >= 19 in the classpath, using modern compatibility layer +[INFO] k8s: 2020-08-07 12:34:32,834 [main ] INFO ClockFactory - Using native clock to generate timestamps. +[INFO] k8s: 2020-08-07 12:34:33,005 [main ] INFO NettyUtil - Did not find Netty's native epoll transport in the classpath, defaulting to NIO. +[INFO] k8s: 2020-08-07 12:34:34,122 [main ] INFO DCAwareRoundRobinPolicy - Using data-center name 'DC1-K8Demo' for DCAwareRoundRobinPolicy (if this is incorrect, please provide the correct datacenter name with DCAwareRoundRobinPolicy constructor) +[INFO] k8s: 2020-08-07 12:34:34,124 [main ] INFO Cluster - New Cassandra host cassandra/172.17.0.7:9042 added +[INFO] k8s: 2020-08-07 12:34:34,150 [main ] INFO Cluster - New Cassandra host cassandra/172.17.0.6:9042 added +[INFO] k8s: 2020-08-07 12:34:36,780 [main ] INFO CqlPopulateBean - Cassandra was populated with sample values for test.users table +[INFO] k8s: 2020-08-07 12:34:37,372 [main ] INFO LRUCacheFactory - Detected and using LRUCacheFactory: camel-caffeine-lrucache +[INFO] k8s: 2020-08-07 12:34:38,012 [main ] INFO AbstractCamelContext - Apache Camel 3.5.0-SNAPSHOT (camel-1) is starting +[INFO] k8s: 2020-08-07 12:34:38,019 [main ] INFO AbstractCamelContext - StreamCaching is not in use. If using streams then its recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html +[INFO] k8s: 2020-08-07 12:34:38,019 [main ] INFO AbstractCamelContext - Using HealthCheck: camel-health +[INFO] k8s: 2020-08-07 12:34:38,664 [main ] INFO DefaultMavenCoordinates - DataStax Java driver for Apache Cassandra(R) (com.datastax.oss:java-driver-core) version 4.8.0 +[INFO] k8s: 2020-08-07 12:34:39,554 [s0-admin-0 ] INFO Clock - Using native clock for microsecond precision +[INFO] k8s: 2020-08-07 12:34:41,453 [main ] INFO InternalRouteStartupManager - Route: cassandra-route started and consuming from: timer://foo +[INFO] k8s: 2020-08-07 12:34:41,454 [main ] INFO AbstractCamelContext - Total 1 routes, of which 1 are started +[INFO] k8s: 2020-08-07 12:34:41,455 [main ] INFO AbstractCamelContext - Apache Camel 3.5.0-SNAPSHOT (camel-1) started in 3.441 seconds +[INFO] k8s: 2020-08-07 12:34:41,469 [main ] INFO BaseMainSupport - Using properties from: classpath:application.properties;optional=true +[INFO] k8s: 2020-08-07 12:34:41,557 [main ] INFO DefaultRoutesCollector - No additional Camel XML routes discovered from: classpath:camel/*.xml +[INFO] k8s: 2020-08-07 12:34:41,557 [main ] INFO DefaultRoutesCollector - No additional Camel XML route templates discovered from: classpath:camel-template/*.xml +[INFO] k8s: 2020-08-07 12:34:41,559 [main ] INFO DefaultRoutesCollector - No additional Camel XML rests discovered from: classpath:camel-rest/*.xml +[INFO] k8s: 2020-08-07 12:34:42,557 [1 - timer://foo] INFO cassandra-route - Query result set [1-oscerd,2-not-a-bot] +[INFO] k8s: 2020-08-07 12:34:47,548 [1 - timer://foo] INFO cassandra-route - Query result set [1-oscerd,2-not-a-bot] +[INFO] k8s: 2020-08-07 12:34:52,661 [1 - timer://foo] INFO cassandra-route - Query result set [1-oscerd,2-not-a-bot] +---- === Cleanup Run following to undeploy the application and cassandra nodes -.... -$ mvn -Pkubernetes-install fabric8:undeploy -$ kubectl create -f src/main/resources/fabric8/cassandra-service.yaml -$ kubectl create -f src/main/resources/fabric8/cassandra-statefulset.yaml -.... +[source,sh] +---- +$ mvn -Pkubernetes-install k8s:undeploy +$ kubectl delete -f src/main/resources/jkube/cassandra-service.yaml +$ kubectl delete -f src/main/resources/jkube/cassandra-statefulset.yaml +---- Make sure no pod is running -.... +[source,sh] +---- $ kubectl get pods No resources found. -.... +---- === Help and contributions diff --git a/examples/camel-example-cassandra-kubernetes/pom.xml b/examples/camel-example-cassandra-kubernetes/pom.xml index 4123006..c6d4cc5 100644 --- a/examples/camel-example-cassandra-kubernetes/pom.xml +++ b/examples/camel-example-cassandra-kubernetes/pom.xml @@ -36,6 +36,7 @@ <category>Cloud</category> <!-- dependency versions --> <cassandra.driver.version>3.7.2</cassandra.driver.version> + <main.class>org.apache.camel.spring.Main</main.class> </properties> <dependencyManagement> @@ -72,6 +73,12 @@ <groupId>com.datastax.cassandra</groupId> <artifactId>cassandra-driver-core</artifactId> <version>${cassandra.driver.version}</version> + <exclusions> + <exclusion> + <groupId>io.netty</groupId> + <artifactId>netty-handler</artifactId> + </exclusion> + </exclusions> </dependency> <!-- used for generating random message --> @@ -98,30 +105,55 @@ <version>${log4j-version}</version> </dependency> </dependencies> - - <!-- only run tests if this profile is enabled --> + <build> + <plugins> + <!-- allows the route to be ran via 'mvn exec:java' --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <version>${exec-maven-plugin-version}</version> + <configuration> + <mainClass>${main.class}</mainClass> + </configuration> + </plugin> + <!-- Create a Fat JAR --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + <version>${maven-assembly-plugin-version}</version> + <configuration> + <descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs> + <appendAssemblyId>false</appendAssemblyId> + <archive> + <manifest> + <mainClass>${main.class}</mainClass> + </manifest> + </archive> + </configuration> + <executions> + <execution> + <id>fat-jar</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> <profiles> <profile> <id>kubernetes-install</id> - <build> <defaultGoal>install</defaultGoal> - <plugins> - <plugin> - <groupId>io.fabric8</groupId> - <artifactId>fabric8-maven-plugin</artifactId> - <version>${fabric8-maven-plugin-version}</version> - <configuration> - <generator> - <config> - <java-exec> - <mainClass>org.apache.camel.spring.Main</mainClass> - </java-exec> - </config> - </generator> - </configuration> + <groupId>org.eclipse.jkube</groupId> + <artifactId>kubernetes-maven-plugin</artifactId> + <version>${jkube-version}</version> <executions> <execution> <goals> @@ -132,15 +164,7 @@ </executions> </plugin> - <!-- allows the route to be ran via 'mvn exec:java' --> - <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>exec-maven-plugin</artifactId> - <version>${exec-maven-plugin-version}</version> - <configuration> - <mainClass>org.apache.camel.spring.Main</mainClass> - </configuration> - </plugin> + </plugins> </build> diff --git a/examples/camel-example-cassandra-kubernetes/src/main/java/org/apache/camel/example/kubernetes/fmp/CqlPopulateBean.java b/examples/camel-example-cassandra-kubernetes/src/main/java/org/apache/camel/example/kubernetes/jkube/CqlPopulateBean.java similarity index 63% copy from examples/camel-example-cassandra-kubernetes/src/main/java/org/apache/camel/example/kubernetes/fmp/CqlPopulateBean.java copy to examples/camel-example-cassandra-kubernetes/src/main/java/org/apache/camel/example/kubernetes/jkube/CqlPopulateBean.java index b4ee7ad..f7094f7 100644 --- a/examples/camel-example-cassandra-kubernetes/src/main/java/org/apache/camel/example/kubernetes/fmp/CqlPopulateBean.java +++ b/examples/camel-example-cassandra-kubernetes/src/main/java/org/apache/camel/example/kubernetes/jkube/CqlPopulateBean.java @@ -14,21 +14,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.camel.example.kubernetes.fmp; +package org.apache.camel.example.kubernetes.jkube; import com.datastax.driver.core.Cluster; import com.datastax.driver.core.Session; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class CqlPopulateBean { + private static final Logger log = LoggerFactory.getLogger(CqlPopulateBean.class); + public void populate() { Cluster cluster = Cluster.builder().addContactPoint("cassandra").build(); Session session = cluster.connect(); - session.execute("create keyspace if not exists test with replication = {'class':'SimpleStrategy', 'replication_factor':1};"); - session.execute("create table if not exists test.users ( id int primary key, name text );"); - session.execute("insert into test.users (id,name) values (1, 'oscerd') if not exists;"); + session.execute("CREATE KEYSPACE IF NOT EXISTS test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':1};"); + session.execute("CREATE TABLE IF NOT EXISTS test.users ( id int primary key, name text );"); + session.execute("INSERT INTO test.users (id,name) VALUES (1, 'oscerd') IF NOT EXISTS;"); + session.execute("INSERT INTO test.users (id,name) VALUES (2, 'not-a-bot') IF NOT EXISTS;"); session.close(); cluster.close(); + log.info("Cassandra was populated with sample values for test.users table"); } } diff --git a/examples/camel-example-cassandra-kubernetes/src/main/java/org/apache/camel/example/kubernetes/fmp/CqlPopulateBean.java b/examples/camel-example-cassandra-kubernetes/src/main/java/org/apache/camel/example/kubernetes/jkube/RowProcessor.java similarity index 53% rename from examples/camel-example-cassandra-kubernetes/src/main/java/org/apache/camel/example/kubernetes/fmp/CqlPopulateBean.java rename to examples/camel-example-cassandra-kubernetes/src/main/java/org/apache/camel/example/kubernetes/jkube/RowProcessor.java index b4ee7ad..9235d49 100644 --- a/examples/camel-example-cassandra-kubernetes/src/main/java/org/apache/camel/example/kubernetes/fmp/CqlPopulateBean.java +++ b/examples/camel-example-cassandra-kubernetes/src/main/java/org/apache/camel/example/kubernetes/jkube/RowProcessor.java @@ -14,21 +14,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.camel.example.kubernetes.fmp; +package org.apache.camel.example.kubernetes.jkube; -import com.datastax.driver.core.Cluster; -import com.datastax.driver.core.Session; +import com.datastax.oss.driver.api.core.cql.Row; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; -public class CqlPopulateBean { - - public void populate() { - Cluster cluster = Cluster.builder().addContactPoint("cassandra").build(); - Session session = cluster.connect(); - session.execute("create keyspace if not exists test with replication = {'class':'SimpleStrategy', 'replication_factor':1};"); - session.execute("create table if not exists test.users ( id int primary key, name text );"); - session.execute("insert into test.users (id,name) values (1, 'oscerd') if not exists;"); - session.close(); - cluster.close(); - } +import java.util.List; +import java.util.stream.Collectors; +public class RowProcessor implements Processor { + @SuppressWarnings("unchecked") + @Override + public void process(Exchange exchange) { + final List<Row> rows = exchange.getIn().getBody(List.class); + exchange.getIn().setBody(rows.stream() + .map(row -> String.format("%s-%s", row.getInt("id"), row.getString("name"))) + .collect(Collectors.joining(",")) + ); + } } diff --git a/examples/camel-example-cassandra-kubernetes/src/main/resources/META-INF/spring/camel-context.xml b/examples/camel-example-cassandra-kubernetes/src/main/resources/META-INF/spring/camel-context.xml index 2303f7d..f4d722d 100644 --- a/examples/camel-example-cassandra-kubernetes/src/main/resources/META-INF/spring/camel-context.xml +++ b/examples/camel-example-cassandra-kubernetes/src/main/resources/META-INF/spring/camel-context.xml @@ -26,14 +26,15 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> - <bean id="populate" class="org.apache.camel.example.kubernetes.fmp.CqlPopulateBean" init-method="populate"/> - + <bean id="populate" class="org.apache.camel.example.kubernetes.jkube.CqlPopulateBean" init-method="populate"/> + <bean id="rowProcessor" class="org.apache.camel.example.kubernetes.jkube.RowProcessor"/> <camelContext xmlns="http://camel.apache.org/schema/spring" depends-on="populate"> <route id="cassandra-route"> <from uri="timer:foo?period=5000"/> - <to uri="cql://cassandra/test?cql=select * from users;&consistencyLevel=quorum" /> - <log message="Query result set ${body}"/> + <to uri="cql://cassandra/test?datacenter=DC1-K8Demo&cql=SELECT * FROM users;&consistencyLevel=quorum" /> + <process ref="rowProcessor"/> + <log message="Query result set [${body}]"/> </route> </camelContext> diff --git a/examples/camel-example-cassandra-kubernetes/src/main/resources/fabric8/cassandra-service.yaml b/examples/camel-example-cassandra-kubernetes/src/main/resources/jkube/cassandra-service.yaml similarity index 100% rename from examples/camel-example-cassandra-kubernetes/src/main/resources/fabric8/cassandra-service.yaml rename to examples/camel-example-cassandra-kubernetes/src/main/resources/jkube/cassandra-service.yaml diff --git a/examples/camel-example-cassandra-kubernetes/src/main/resources/fabric8/cassandra-statefulset.yaml b/examples/camel-example-cassandra-kubernetes/src/main/resources/jkube/cassandra-statefulset.yaml similarity index 97% rename from examples/camel-example-cassandra-kubernetes/src/main/resources/fabric8/cassandra-statefulset.yaml rename to examples/camel-example-cassandra-kubernetes/src/main/resources/jkube/cassandra-statefulset.yaml index 6650053..fdb1665 100644 --- a/examples/camel-example-cassandra-kubernetes/src/main/resources/fabric8/cassandra-statefulset.yaml +++ b/examples/camel-example-cassandra-kubernetes/src/main/resources/jkube/cassandra-statefulset.yaml @@ -15,13 +15,16 @@ # limitations under the License. # -apiVersion: "apps/v1beta1" +apiVersion: "apps/v1" kind: StatefulSet metadata: name: cassandra spec: serviceName: cassandra replicas: 2 + selector: + matchLabels: + app: cassandra template: metadata: labels: diff --git a/examples/pom.xml b/examples/pom.xml index d9b861e..caab63b 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -189,6 +189,7 @@ <woodstox-version>6.0.3</woodstox-version> <xmlunit-version>1.6</xmlunit-version> <derby-version>10.14.2.0</derby-version> + <jkube-version>1.0.0-rc-1</jkube-version> </properties> <!-- Comment out the snapshot repositories as we don't need them now -->