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.git

commit 368cbf505e12a9cfb49e6235e73764c56604ce0c
Author: Andrea Cosentino <[email protected]>
AuthorDate: Wed Feb 23 10:42:19 2022 +0100

    CAMEL-17700 - AWS Secret Manager Properties Source: Provide a fallback 
default value
---
 .../SecretsManagerPropertiesFunction.java          |  68 +++++++++-----
 .../SecretsManagerPropertiesSourceTestIT.java      | 101 ++++++++++++++++++++-
 2 files changed, 140 insertions(+), 29 deletions(-)

diff --git 
a/components/camel-aws/camel-aws-secrets-manager/src/main/java/org/apache/camel/component/aws/secretsmanager/SecretsManagerPropertiesFunction.java
 
b/components/camel-aws/camel-aws-secrets-manager/src/main/java/org/apache/camel/component/aws/secretsmanager/SecretsManagerPropertiesFunction.java
index 2144be8..93d2a89 100644
--- 
a/components/camel-aws/camel-aws-secrets-manager/src/main/java/org/apache/camel/component/aws/secretsmanager/SecretsManagerPropertiesFunction.java
+++ 
b/components/camel-aws/camel-aws-secrets-manager/src/main/java/org/apache/camel/component/aws/secretsmanager/SecretsManagerPropertiesFunction.java
@@ -37,6 +37,7 @@ import 
software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
 import 
software.amazon.awssdk.services.secretsmanager.SecretsManagerClientBuilder;
 import 
software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest;
 import 
software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse;
+import 
software.amazon.awssdk.services.secretsmanager.model.ResourceNotFoundException;
 
 /**
  * A {@link PropertiesFunction} that lookup the property value from AWS 
Secrets Manager service.
@@ -87,11 +88,16 @@ public class SecretsManagerPropertiesFunction extends 
ServiceSupport implements
                 region = awsVaultConfiguration.getRegion();
             }
         }
-        SecretsManagerClientBuilder clientBuilder = 
SecretsManagerClient.builder();
-        AwsBasicCredentials cred = AwsBasicCredentials.create(accessKey, 
secretKey);
-        clientBuilder = 
clientBuilder.credentialsProvider(StaticCredentialsProvider.create(cred));
-        clientBuilder.region(Region.of(region));
-        client = clientBuilder.build();
+        if (ObjectHelper.isNotEmpty(accessKey) && 
ObjectHelper.isNotEmpty(secretKey) && ObjectHelper.isNotEmpty(region)) {
+            SecretsManagerClientBuilder clientBuilder = 
SecretsManagerClient.builder();
+            AwsBasicCredentials cred = AwsBasicCredentials.create(accessKey, 
secretKey);
+            clientBuilder = 
clientBuilder.credentialsProvider(StaticCredentialsProvider.create(cred));
+            clientBuilder.region(Region.of(region));
+            client = clientBuilder.build();
+        } else {
+            throw new RuntimeCamelException(
+                    "Using the AWS Secrets Manager Properties Function 
requires setting AWS credentials as application properties or environment 
variables");
+        }
     }
 
     @Override
@@ -112,15 +118,19 @@ public class SecretsManagerPropertiesFunction extends 
ServiceSupport implements
         String key = remainder;
         String subkey = null;
         String returnValue = null;
-
-        if (remainder.contains(":")) {
+        String defaultValue = null;
+        if (remainder.contains("/")) {
+            key = StringHelper.before(remainder, "/");
+            subkey = StringHelper.after(remainder, "/");
+            defaultValue = StringHelper.after(subkey, ":");
+        } else if (remainder.contains(":")) {
             key = StringHelper.before(remainder, ":");
-            subkey = StringHelper.after(remainder, ":");
+            defaultValue = StringHelper.after(remainder, ":");
         }
 
         if (key != null) {
             try {
-                returnValue = getSecretFromSource(key, subkey);
+                returnValue = getSecretFromSource(key, subkey, defaultValue);
             } catch (JsonProcessingException e) {
                 throw new RuntimeCamelException("Something went wrong while 
recovering " + key + " from vault");
             }
@@ -130,28 +140,38 @@ public class SecretsManagerPropertiesFunction extends 
ServiceSupport implements
     }
 
     private String getSecretFromSource(
-            String key, String subkey)
+            String key, String subkey, String defaultValue)
             throws JsonProcessingException {
         String returnValue;
         GetSecretValueRequest request;
         GetSecretValueRequest.Builder builder = 
GetSecretValueRequest.builder();
         builder.secretId(key);
         request = builder.build();
-        GetSecretValueResponse secret = client.getSecretValue(request);
-        returnValue = secret.secretString();
-        if (secret.secretString() != null) {
-            returnValue = secret.secretString();
-        } else {
-            returnValue = new 
String(Base64.getDecoder().decode(secret.secretBinary().asByteBuffer()).array());
-        }
-        if (subkey != null) {
-            ObjectMapper mapper = new ObjectMapper();
-            JsonNode actualObj = mapper.readTree(returnValue);
-            JsonNode field = actualObj.get(subkey);
-            if (ObjectHelper.isNotEmpty(field)) {
-                returnValue = field.textValue();
+        try {
+            GetSecretValueResponse secret = client.getSecretValue(request);
+            if (ObjectHelper.isNotEmpty(secret.secretString())) {
+                returnValue = secret.secretString();
+            } else {
+                returnValue = new 
String(Base64.getDecoder().decode(secret.secretBinary().asByteBuffer()).array());
+            }
+            if (ObjectHelper.isNotEmpty(subkey)) {
+                ObjectMapper mapper = new ObjectMapper();
+                JsonNode actualObj = mapper.readTree(returnValue);
+                JsonNode field = actualObj.get(subkey);
+                if (ObjectHelper.isNotEmpty(field)) {
+                    returnValue = field.textValue();
+                } else {
+                    returnValue = null;
+                }
+            }
+            if (ObjectHelper.isEmpty(returnValue)) {
+                returnValue = defaultValue;
+            }
+        } catch (ResourceNotFoundException ex) {
+            if (ObjectHelper.isNotEmpty(defaultValue)) {
+                returnValue = defaultValue;
             } else {
-                returnValue = null;
+                throw ex;
             }
         }
         return returnValue;
diff --git 
a/components/camel-aws/camel-aws-secrets-manager/src/test/java/org/apache/camel/component/aws/secretsmanager/integration/SecretsManagerPropertiesSourceTestIT.java
 
b/components/camel-aws/camel-aws-secrets-manager/src/test/java/org/apache/camel/component/aws/secretsmanager/integration/SecretsManagerPropertiesSourceTestIT.java
index 3416c47..b8b928e 100644
--- 
a/components/camel-aws/camel-aws-secrets-manager/src/test/java/org/apache/camel/component/aws/secretsmanager/integration/SecretsManagerPropertiesSourceTestIT.java
+++ 
b/components/camel-aws/camel-aws-secrets-manager/src/test/java/org/apache/camel/component/aws/secretsmanager/integration/SecretsManagerPropertiesSourceTestIT.java
@@ -51,8 +51,8 @@ public class SecretsManagerPropertiesSourceTestIT extends 
CamelTestSupport {
         context.addRoutes(new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                
from("direct:username").setBody(simple("{{aws:database_sample:username}}")).to("mock:bar");
-                
from("direct:password").setBody(simple("{{aws:database_sample:password}}")).to("mock:bar");
+                
from("direct:username").setBody(simple("{{aws:database_sample/username}}")).to("mock:bar");
+                
from("direct:password").setBody(simple("{{aws:database_sample/password}}")).to("mock:bar");
             }
         });
         context.start();
@@ -69,8 +69,8 @@ public class SecretsManagerPropertiesSourceTestIT extends 
CamelTestSupport {
         context.addRoutes(new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                
from("direct:username").setBody(simple("{{aws:normalkey:username}}")).to("mock:bar");
-                
from("direct:password").setBody(simple("{{aws:normalkey:password}}")).to("mock:bar");
+                
from("direct:username").setBody(simple("{{aws:normalkey/username}}")).to("mock:bar");
+                
from("direct:password").setBody(simple("{{aws:normalkey/password}}")).to("mock:bar");
             }
         });
         context.start();
@@ -107,7 +107,7 @@ public class SecretsManagerPropertiesSourceTestIT extends 
CamelTestSupport {
             context.addRoutes(new RouteBuilder() {
                 @Override
                 public void configure() throws Exception {
-                    
from("direct:username").setBody(simple("{{aws:database_sample:not_existent}}")).to("mock:bar");
+                    
from("direct:username").setBody(simple("{{aws:database_sample/not_existent}}")).to("mock:bar");
                 }
             });
             context.start();
@@ -119,4 +119,95 @@ public class SecretsManagerPropertiesSourceTestIT extends 
CamelTestSupport {
         });
     }
 
+    @Test
+    public void testComplexCustomPropertiesDefaultValueFunction() throws 
Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                
from("direct:username").setBody(simple("{{aws:postgresql/additional1:admin}}")).to("mock:bar");
+                
from("direct:password").setBody(simple("{{aws:postgresql/additional2:secret}}")).to("mock:bar");
+            }
+        });
+        context.start();
+
+        getMockEndpoint("mock:bar").expectedBodiesReceived("admin", "secret");
+
+        template.sendBody("direct:username", "Hello World");
+        template.sendBody("direct:password", "Hello World");
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testComplexCustomPropertiesDefaultValueExceptionFunction() 
throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                
from("direct:username").setBody(simple("{{aws:test-3/additional1:admin}}")).to("mock:bar");
+                
from("direct:password").setBody(simple("{{aws:test-3/additional2:secret}}")).to("mock:bar");
+            }
+        });
+        context.start();
+
+        getMockEndpoint("mock:bar").expectedBodiesReceived("admin", "secret");
+
+        template.sendBody("direct:username", "Hello World");
+        template.sendBody("direct:password", "Hello World");
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testComplexCustomPropertiesExceptionFunction() throws 
Exception {
+        Exception exception = assertThrows(FailedToCreateRouteException.class, 
() -> {
+            context.addRoutes(new RouteBuilder() {
+                @Override
+                public void configure() throws Exception {
+                    
from("direct:username").setBody(simple("{{aws:test-3/additional1}}")).to("mock:bar");
+                    
from("direct:password").setBody(simple("{{aws:test-3/additional2}}")).to("mock:bar");
+                }
+            });
+            context.start();
+
+            getMockEndpoint("mock:bar").expectedBodiesReceived("admin", 
"secret");
+
+            template.sendBody("direct:username", "Hello World");
+            template.sendBody("direct:password", "Hello World");
+            assertMockEndpointsSatisfied();
+        });
+    }
+
+    @Test
+    public void testComplexSimpleDefaultValueExceptionFunction() throws 
Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                
from("direct:username").setBody(simple("{{aws:test-3:admin}}")).to("mock:bar");
+                
from("direct:password").setBody(simple("{{aws:test-1:secret}}")).to("mock:bar");
+            }
+        });
+        context.start();
+
+        getMockEndpoint("mock:bar").expectedBodiesReceived("admin", "secret");
+
+        template.sendBody("direct:username", "Hello World");
+        template.sendBody("direct:password", "Hello World");
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testComplexSimpleNoDefaultValueExceptionFunction() throws 
Exception {
+        Exception exception = assertThrows(FailedToCreateRouteException.class, 
() -> {
+            context.addRoutes(new RouteBuilder() {
+                @Override
+                public void configure() throws Exception {
+                    
from("direct:username").setBody(simple("{{aws:secretsuper}}")).to("mock:bar");
+                }
+            });
+            context.start();
+
+            getMockEndpoint("mock:bar").expectedBodiesReceived("admin");
+
+            template.sendBody("direct:username", "Hello World");
+            assertMockEndpointsSatisfied();
+        });
+    }
 }

Reply via email to