This is an automated email from the ASF dual-hosted git repository.

acosentino pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-examples.git

commit c615f06fc93408316294d0688abb011029996aae
Author: Andrea Cosentino <anco...@gmail.com>
AuthorDate: Fri Sep 2 14:25:20 2022 +0200

    Added an AWS Secrets Manager Reloading of Camel Context example
---
 .../aws/aws-secrets-manager-reloading/README.adoc  | 144 +++++++++++++++++++++
 examples/aws/aws-secrets-manager-reloading/pom.xml | 118 +++++++++++++++++
 .../org/apache/camel/example/MyApplication.java    | 125 ++++++++++++++++++
 .../org/apache/camel/example/MyRouteBuilder.java   |  29 +++++
 .../src/main/resources/application.properties      |  32 +++++
 .../src/main/resources/logback.xml                 |  30 +++++
 examples/aws/pom.xml                               |   1 +
 7 files changed, 479 insertions(+)

diff --git a/examples/aws/aws-secrets-manager-reloading/README.adoc 
b/examples/aws/aws-secrets-manager-reloading/README.adoc
new file mode 100644
index 00000000..8ccedf09
--- /dev/null
+++ b/examples/aws/aws-secrets-manager-reloading/README.adoc
@@ -0,0 +1,144 @@
+== Camel Example AWS Secrets Manager Reloading
+
+This example shows how to use AWS Secrets Manager to retrieve a secret, update 
the secret and trigger a reload of the camel context.
+
+Also notice how you can configure Camel in the `application.properties` file.
+
+=== Setup
+
+- Store the secret
+
+In this example you'll need to use the AWS CLI to run some commands during the 
example.
+
+First of all we'll need to create a secret in AWS Secret Manager, named 
`SecretTest`.
+
+We'll run
+
+[source,sh]
+----
+aws secretsmanager create-secret --name SecretTest --description "Create a 
secret" --region eu-west-1 --secret-string secret 
+----
+
+- Setting up the AWS credentials as enviroment variables
+
+This example uses the ProfileCredentialsProvider from AWS SDK v2. So you'll 
need to have a configuration file, locally to your machine.
+
+In particular you'll need to have a file placed in `~/.aws/credentials`
+
+with a content like the following
+
+[source,sh]
+----
+[default]
+aws_access_key_id = accessKey
+aws_secret_access_key = secretKey
+----
+
+[source,sh]
+----
+export CAMEL_VAULT_AWS_REGION=<region>
+export CAMEL_VAULT_AWS_USE_DEFAULT_CREDENTIALS_PROVIDER=true
+----
+
+Now you're ready to run the example.
+
+=== Build
+
+First compile the example by executing:
+
+[source,sh]
+----
+$ mvn compile
+----
+
+=== How to run
+
+Then you can run this example using
+
+[source,sh]
+----
+$ mvn camel:run
+----
+
+At this point you should see:
+
+[source,sh]
+----
+14:02:19.031 [org.apache.camel.example.MyApplication.main()] INFO  
org.apache.camel.main.MainSupport - Apache Camel (Main) 3.19.0-SNAPSHOT is 
starting
+14:02:19.121 [org.apache.camel.example.MyApplication.main()] INFO  
o.apache.camel.main.BaseMainSupport - Classpath scanning enabled from base 
package: org.apache.camel.example
+14:02:19.204 [org.apache.camel.example.MyApplication.main()] INFO  
o.a.c.i.e.DefaultBeanIntrospection - Invoked: 1 times (overall) [Method: 
setProperty, Target: org.apache.camel.vault.AwsVaultConfiguration@c3adfb, 
Arguments: [defaultCredentialsProvider, true]]
+14:02:19.210 [org.apache.camel.example.MyApplication.main()] INFO  
o.a.c.i.e.DefaultBeanIntrospection - Invoked: 2 times (overall) [Method: 
setProperty, Target: org.apache.camel.vault.AwsVaultConfiguration@c3adfb, 
Arguments: [region, eu-west-1]]
+14:02:19.226 [org.apache.camel.example.MyApplication.main()] INFO  
o.apache.camel.main.BaseMainSupport - Auto-configuration summary
+14:02:19.227 [org.apache.camel.example.MyApplication.main()] INFO  
o.apache.camel.main.BaseMainSupport -     [application.properties]       
camel.main.name=AWS-secrets-manager
+14:02:19.227 [org.apache.camel.example.MyApplication.main()] INFO  
o.apache.camel.main.BaseMainSupport -     [application.properties]       
camel.main.jmxEnabled=false
+14:02:19.227 [org.apache.camel.example.MyApplication.main()] INFO  
o.apache.camel.main.BaseMainSupport -     [application.properties]       
camel.main.beanIntrospectionLoggingLevel=INFO
+14:02:19.227 [org.apache.camel.example.MyApplication.main()] INFO  
o.apache.camel.main.BaseMainSupport -     [application.properties]       
camel.main.contextReloadEnabled=true
+14:02:19.227 [org.apache.camel.example.MyApplication.main()] INFO  
o.apache.camel.main.BaseMainSupport -     [application.properties]       
camel.vault.aws.defaultCredentialsProvider=true
+14:02:19.227 [org.apache.camel.example.MyApplication.main()] INFO  
o.apache.camel.main.BaseMainSupport -     [application.properties]       
camel.vault.aws.region=eu-west-1
+14:02:20.552 [org.apache.camel.example.MyApplication.main()] INFO  
o.a.c.i.engine.AbstractCamelContext - Apache Camel 3.19.0-SNAPSHOT 
(AWS-secrets-manager) is starting
+14:02:20.573 [org.apache.camel.example.MyApplication.main()] INFO  
o.a.c.i.engine.AbstractCamelContext - Routes startup (started:1)
+14:02:20.574 [org.apache.camel.example.MyApplication.main()] INFO  
o.a.c.i.engine.AbstractCamelContext -     Started route1 (timer://myTimer)
+14:02:20.583 [org.apache.camel.example.MyApplication.main()] INFO  
o.a.c.i.engine.AbstractCamelContext - Apache Camel 3.19.0-SNAPSHOT 
(AWS-secrets-manager) started in 1s327ms (build:31ms init:1s275ms start:21ms 
JVM-uptime:3s)
+14:02:20.720 [pool-1-thread-1] INFO  o.apache.camel.example.MyApplication - 
Found 50 events
+14:02:21.593 [Camel (AWS-secrets-manager) thread #1 - timer://myTimer] INFO  
route1 - Secret value is: secret
+14:02:31.573 [Camel (AWS-secrets-manager) thread #1 - timer://myTimer] INFO  
route1 - Secret value is: secret
+14:02:41.573 [Camel (AWS-secrets-manager) thread #1 - timer://myTimer] INFO  
route1 - Secret value is: secret
+14:02:50.288 [pool-1-thread-1] INFO  o.apache.camel.example.MyApplication - 
Found 0 events
+14:02:51.573 [Camel (AWS-secrets-manager) thread #1 - timer://myTimer] INFO  
route1 - Secret value is: secret
+14:03:01.573 [Camel (AWS-secrets-manager) thread #1 - timer://myTimer] INFO  
route1 - Secret value is: secret
+14:03:11.573 [Camel (AWS-secrets-manager) thread #1 - timer://myTimer] INFO  
route1 - Secret value is: secret
+----
+
+The example is running and it is using the original secret value. Now, in a 
different terminal, run the following AWS CLI command:
+
+[source,sh]
+----
+aws secretsmanager put-secret-value --secret-id SecretTest --region eu-west-1 
--secret-string secretImproved
+----
+
+Now, get back, to the running Camel application and in the log you should see:
+
+[source,sh]
+----
+.
+.
+.
+14:03:50.303 [pool-1-thread-1] INFO  o.apache.camel.example.MyApplication - 
Found 0 events
+14:03:51.572 [Camel (AWS-secrets-manager) thread #1 - timer://myTimer] INFO  
route1 - Secret value is: secret
+14:04:01.572 [Camel (AWS-secrets-manager) thread #1 - timer://myTimer] INFO  
route1 - Secret value is: secret
+14:04:11.572 [Camel (AWS-secrets-manager) thread #1 - timer://myTimer] INFO  
route1 - Secret value is: secret
+14:04:20.311 [pool-1-thread-1] INFO  o.apache.camel.example.MyApplication - 
Found 1 events
+14:04:20.312 [pool-1-thread-1] INFO  o.apache.camel.example.MyApplication - 
Update for secret SecretTest detected, triggering a context reload
+14:04:20.312 [pool-1-thread-1] INFO  o.a.c.i.e.DefaultContextReloadStrategy - 
Reloading CamelContext (AWS-secrets-manager) triggered by: AWS-secrets-manager
+14:04:21.608 [Camel (AWS-secrets-manager) thread #4 - timer://myTimer] INFO  
route1 - Secret value is: secretImproved
+14:04:31.607 [Camel (AWS-secrets-manager) thread #4 - timer://myTimer] INFO  
route1 - Secret value is: secretImproved
+.
+.
+.
+.
+----
+
+The Camel context has been reloaded after we noticed a `PutSecretValue` API 
invocation for this specific secret, in this specific region, in the AWS 
CloudTrail service.
+
+Now, stop the application.
+
+=== Cleanup
+
+- Delete the secret
+
+Simply run
+
+[source,sh]
+----
+aws secretsmanager delete-secret --secret-id SecretTest --region eu-west-1 
--force-delete-without-recovery
+----
+
+=== Help and contributions
+
+If you hit any problem using Camel or have some feedback, then please
+https://camel.apache.org/community/support/[let us know].
+
+We also love contributors, so
+https://camel.apache.org/community/contributing/[get involved] :-)
+
+The Camel riders!
diff --git a/examples/aws/aws-secrets-manager-reloading/pom.xml 
b/examples/aws/aws-secrets-manager-reloading/pom.xml
new file mode 100644
index 00000000..9d471953
--- /dev/null
+++ b/examples/aws/aws-secrets-manager-reloading/pom.xml
@@ -0,0 +1,118 @@
+<?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-examples-aws-parent</artifactId>
+        <version>3.19.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-example-aws-secrets-manager-reloading</artifactId>
+    <packaging>jar</packaging>
+    <name>Camel :: Example :: AWS Secrets Manager Reloading</name>
+    <description>An example for showing AWS Secrets Manager Camel component 
with reloading</description>
+
+    <properties>
+        <category>Beginner</category>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <!-- Add Camel BOM -->
+            <dependency>
+                <groupId>org.apache.camel</groupId>
+                <artifactId>camel-bom</artifactId>
+                <version>${camel.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-main</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-aws-secrets-manager</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-http</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>software.amazon.awssdk</groupId>
+            <artifactId>cloudtrail</artifactId>
+            <version>2.17.266</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-timer</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-jsonpath</artifactId>
+        </dependency>
+
+        <!-- logging -->
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-api</artifactId>
+            <version>${log4j2-version}</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-core</artifactId>
+            <version>${logback-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>${logback-version}</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.camel</groupId>
+                <artifactId>camel-maven-plugin</artifactId>
+                <version>${camel.version}</version>
+                <configuration>
+                    <logClasspath>false</logClasspath>
+                    
<mainClass>org.apache.camel.example.MyApplication</mainClass>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git 
a/examples/aws/aws-secrets-manager-reloading/src/main/java/org/apache/camel/example/MyApplication.java
 
b/examples/aws/aws-secrets-manager-reloading/src/main/java/org/apache/camel/example/MyApplication.java
new file mode 100644
index 00000000..6447bd31
--- /dev/null
+++ 
b/examples/aws/aws-secrets-manager-reloading/src/main/java/org/apache/camel/example/MyApplication.java
@@ -0,0 +1,125 @@
+/*
+ * 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.example;
+
+import org.apache.camel.main.Main;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.camel.spi.ContextReloadStrategy;
+import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.cloudtrail.CloudTrailClient;
+import software.amazon.awssdk.services.cloudtrail.model.*;
+
+import java.time.Instant;
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Main class that boot the Camel application
+ */
+public final class MyApplication {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(MyApplication.class);
+
+    public static Instant lastTime = null;
+
+    private MyApplication() {
+    }
+
+    public static void main(String[] args) throws Exception {
+        // use Camels Main class
+        Main main = new Main(MyApplication.class);
+
+        // Task to check for secret updates
+        ScheduledExecutorService executor = 
Executors.newScheduledThreadPool(1);
+        CloudTrailAnalyzerTask analyzerTask = new CloudTrailAnalyzerTask(main, 
"SecretTest");
+        executor.scheduleAtFixedRate(analyzerTask, 1, 30, TimeUnit.SECONDS);
+
+        // now keep the application running until the JVM is terminated (ctrl 
+ c or sigterm)
+        main.run(args);
+    }
+
+    protected static class CloudTrailAnalyzerTask implements Runnable {
+        private Main main;
+        private String secretName;
+        private static String eventSourceSecrets = 
"secretsmanager.amazonaws.com";
+
+        public CloudTrailAnalyzerTask(Main main, String secretName) {
+            this.main = main;
+            this.secretName = secretName;
+        }
+
+        @Override
+        public void run() {
+            boolean triggerReloading = false;
+            Region regionValue = 
Region.of(main.getCamelContext().getPropertiesComponent().loadProperties().get("camel.vault.aws.region").toString());
+            CloudTrailClient cloudTrailClient = CloudTrailClient.builder()
+                    .region(regionValue)
+                    .credentialsProvider(ProfileCredentialsProvider.create())
+                    .build();
+            try {
+                LookupEventsRequest.Builder eventsRequestBuilder = 
LookupEventsRequest.builder()
+                        
.maxResults(100).lookupAttributes(LookupAttribute.builder().attributeKey(LookupAttributeKey.EVENT_SOURCE).attributeValue(eventSourceSecrets).build());
+
+                if (lastTime != null) {
+                    eventsRequestBuilder.startTime(lastTime.plusMillis(1000));
+                }
+
+                LookupEventsRequest lookupEventsRequest = 
eventsRequestBuilder.build();
+
+                LookupEventsResponse response = 
cloudTrailClient.lookupEvents(lookupEventsRequest);
+                List<Event> events = response.events();
+
+                if (events.size() > 0) {
+                    lastTime = events.get(0).eventTime();
+                }
+
+                LOG.info("Found " + events.size() + " events");
+                for (Event event : events) {
+                    if 
(event.eventSource().equalsIgnoreCase(eventSourceSecrets)) {
+                        if 
(event.eventName().equalsIgnoreCase("PutSecretValue")) {
+                            List<Resource> a = event.resources();
+                            for (Resource res : a) {
+                                if (res.resourceName().contains(secretName)) {
+                                    LOG.info("Update for secret " + secretName 
+ " detected, triggering a context reload");
+                                    triggerReloading = true;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+
+            } catch (CloudTrailException e) {
+                throw e;
+            }
+            if (triggerReloading) {
+                if (main.getCamelContext() != null) {
+                    ContextReloadStrategy reload = 
main.getCamelContext().hasService(ContextReloadStrategy.class);
+                    if (reload != null) {
+                        // trigger reload
+                        reload.onReload(main.getCamelContext().getName());
+                    }
+                }
+            }
+        }
+    }
+
+}
diff --git 
a/examples/aws/aws-secrets-manager-reloading/src/main/java/org/apache/camel/example/MyRouteBuilder.java
 
b/examples/aws/aws-secrets-manager-reloading/src/main/java/org/apache/camel/example/MyRouteBuilder.java
new file mode 100644
index 00000000..e2b51552
--- /dev/null
+++ 
b/examples/aws/aws-secrets-manager-reloading/src/main/java/org/apache/camel/example/MyRouteBuilder.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.example;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.aws.secretsmanager.SecretsManagerConstants;
+
+public class MyRouteBuilder extends RouteBuilder {
+
+    @Override
+    public void configure() throws Exception {
+        from("timer://myTimer?fixedRate=true&period=10000")
+            .log("Secret value is: {{aws:SecretTest}}");
+    }
+}
diff --git 
a/examples/aws/aws-secrets-manager-reloading/src/main/resources/application.properties
 
b/examples/aws/aws-secrets-manager-reloading/src/main/resources/application.properties
new file mode 100644
index 00000000..e07f7e1d
--- /dev/null
+++ 
b/examples/aws/aws-secrets-manager-reloading/src/main/resources/application.properties
@@ -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.
+## ---------------------------------------------------------------------------
+
+# here you can configure options on camel main
+# https://camel.apache.org/components/next/others/main.html
+camel.main.name = AWS-secrets-manager
+camel.main.jmx-enabled = false
+
+# extended runtime statistics about bean introspection usage (java reflection)
+camel.main.bean-introspection-logging-level=INFO
+
+# Generic properties
+stock = AMZN
+stockName = Amazon
+
+camel.vault.aws.defaultCredentialsProvider=true
+camel.vault.aws.region=eu-west-1
+camel.main.context-reload-enabled = true
diff --git 
a/examples/aws/aws-secrets-manager-reloading/src/main/resources/logback.xml 
b/examples/aws/aws-secrets-manager-reloading/src/main/resources/logback.xml
new file mode 100644
index 00000000..a798d0b3
--- /dev/null
+++ b/examples/aws/aws-secrets-manager-reloading/src/main/resources/logback.xml
@@ -0,0 +1,30 @@
+<?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.
+
+-->
+<configuration>
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - 
%msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <root level="INFO">
+        <appender-ref ref="STDOUT" />
+    </root>
+</configuration>
diff --git a/examples/aws/pom.xml b/examples/aws/pom.xml
index 4a047439..6deaab1c 100644
--- a/examples/aws/pom.xml
+++ b/examples/aws/pom.xml
@@ -38,6 +38,7 @@
 
     <modules>
         <module>aws-secrets-manager</module>
+        <module>aws-secrets-manager-reloading</module>
         <module>main-endpointdsl-aws2</module>
         <module>main-endpointdsl-aws2-s3</module>
         <module>main-endpointdsl-aws2-s3-kafka</module>

Reply via email to