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

orpiske pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new 0ade008  CAMEL-15840: avoid keeping duplicate copies of the 
configuration object in camel-aws2-sns (#4592)
0ade008 is described below

commit 0ade008d9e7968403bb36015d11f4f053fd1af90
Author: Otavio Rodolfo Piske <orpi...@users.noreply.github.com>
AuthorDate: Wed Nov 11 12:47:19 2020 +0100

    CAMEL-15840: avoid keeping duplicate copies of the configuration object in 
camel-aws2-sns (#4592)
    
    Includes a reproducer for CAMEL-15840
---
 .../camel/component/aws2/sns/Sns2Component.java    | 67 +++++++++++++++++---
 .../camel/component/aws2/sns/Sns2Endpoint.java     |  6 +-
 ...SnsTopicProducerCustomConfigLocalstackTest.java | 71 ++++++++++++++++++++++
 .../aws2/sns/localstack/TestSnsConfiguration.java  | 41 +++++++++++++
 4 files changed, 170 insertions(+), 15 deletions(-)

diff --git 
a/components/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2Component.java
 
b/components/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2Component.java
index 689b2e8..6bf75a9 100644
--- 
a/components/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2Component.java
+++ 
b/components/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2Component.java
@@ -18,6 +18,7 @@ package org.apache.camel.component.aws2.sns;
 
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
@@ -50,23 +51,30 @@ public class Sns2Component extends DefaultComponent {
 
     @Override
     protected Endpoint createEndpoint(String uri, String remaining, 
Map<String, Object> parameters) throws Exception {
-
         if (remaining == null || remaining.trim().length() == 0) {
             throw new IllegalArgumentException("Topic name must be 
specified.");
         }
-        Sns2Configuration configuration = this.configuration != null ? 
this.configuration.copy() : new Sns2Configuration();
+
+        if (containsTransientParameters(parameters)) {
+            Map<String, Object> transientParameters = 
getTransientParameters(parameters);
+
+            setProperties(getCamelContext(), this, transientParameters);
+        }
+
+        configuration = this.configuration != null ? this.configuration : new 
Sns2Configuration();
+        Sns2Endpoint endpoint = new Sns2Endpoint(uri, this, configuration);
+
+        Map<String, Object> nonTransientParameters = 
getNonTransientParameters(parameters);
+
+        setProperties(endpoint, nonTransientParameters);
+
         if (remaining.startsWith("arn:")) {
-            String[] parts = remaining.split(":");
-            if (parts.length != 6 || !parts[2].equals("sns")) {
-                throw new IllegalArgumentException("Topic arn must be in 
format arn:aws:sns:region:account:name.");
-            }
-            configuration.setTopicArn(remaining);
-            configuration.setRegion(Region.of(parts[3]).toString());
+            parseRemaining(remaining);
         } else {
             configuration.setTopicName(remaining);
+            LOG.debug("Created the endpoint with topic {}", 
configuration.getTopicName());
         }
-        Sns2Endpoint endpoint = new Sns2Endpoint(uri, this, configuration);
-        setProperties(endpoint, parameters);
+
         if (endpoint.getConfiguration().isAutoDiscoverClient()) {
             checkAndSetRegistryClient(configuration, endpoint);
         }
@@ -78,6 +86,44 @@ public class Sns2Component extends DefaultComponent {
         return endpoint;
     }
 
+    /*
+     This method, along with getTransientParameters, getNonTransientParameters 
and validateParameters handle transient
+     parameters. Transient parameters, in this sense, means temporary 
parameters passed to the URI, that should
+     no be directly set on the endpoint because they apply to a different 
lifecycle in the component/endpoint creation.
+     For example, the "configuration" parameter is used to set a different 
Component/Endpoint configuration class other
+     than the one provided by Camel. Because the configuration object is 
required to configure these objects, it must
+     be used earlier in the life cycle ... and not later as part of the 
transport setup. Therefore, transient.
+     */
+    private boolean containsTransientParameters(Map<String, Object> 
parameters) {
+        return parameters.containsKey("configuration");
+    }
+
+    private Map<String, Object> getNonTransientParameters(Map<String, Object> 
parameters) {
+        return parameters.entrySet().stream().filter(k -> 
!k.getKey().equals("configuration"))
+                .collect(Collectors.toMap(k -> k.getKey(), k -> k.getValue()));
+    }
+
+    private Map<String, Object> getTransientParameters(Map<String, Object> 
parameters) {
+        return parameters.entrySet().stream().filter(k -> 
k.getKey().equals("configuration"))
+                .collect(Collectors.toMap(k -> k.getKey(), k -> k.getValue()));
+    }
+
+    @Override
+    protected void validateParameters(String uri, Map<String, Object> 
parameters, String optionPrefix) {
+        super.validateParameters(uri, getNonTransientParameters(parameters), 
optionPrefix);
+    }
+
+    private void parseRemaining(String remaining) {
+        String[] parts = remaining.split(":");
+        if (parts.length != 6 || !parts[2].equals("sns")) {
+            throw new IllegalArgumentException("Topic arn must be in format 
arn:aws:sns:region:account:name.");
+        }
+        configuration.setTopicArn(remaining);
+        configuration.setRegion(Region.of(parts[3]).toString());
+
+        LOG.debug("Created the endpoint with topic arn {}", 
configuration.getTopicArn());
+    }
+
     public Sns2Configuration getConfiguration() {
         return configuration;
     }
@@ -103,4 +149,5 @@ public class Sns2Component extends DefaultComponent {
             LOG.debug("SnsClient instance is already set at endpoint level: 
skipping the check in the registry");
         }
     }
+
 }
diff --git 
a/components/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2Endpoint.java
 
b/components/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2Endpoint.java
index ef5b00c..05db0f1 100644
--- 
a/components/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2Endpoint.java
+++ 
b/components/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2Endpoint.java
@@ -62,7 +62,7 @@ public class Sns2Endpoint extends DefaultEndpoint implements 
HeaderFilterStrateg
     @Metadata(required = true)
     private String topicNameOrArn; // to support component docs
     @UriParam
-    private Sns2Configuration configuration;
+    private final Sns2Configuration configuration;
     @UriParam
     private HeaderFilterStrategy headerFilterStrategy;
 
@@ -185,10 +185,6 @@ public class Sns2Endpoint extends DefaultEndpoint 
implements HeaderFilterStrateg
         return configuration;
     }
 
-    public void setConfiguration(Sns2Configuration configuration) {
-        this.configuration = configuration;
-    }
-
     public void setSNSClient(SnsClient snsClient) {
         this.snsClient = snsClient;
     }
diff --git 
a/components/camel-aws2-sns/src/test/java/org/apache/camel/component/aws2/sns/localstack/SnsTopicProducerCustomConfigLocalstackTest.java
 
b/components/camel-aws2-sns/src/test/java/org/apache/camel/component/aws2/sns/localstack/SnsTopicProducerCustomConfigLocalstackTest.java
new file mode 100644
index 0000000..d096e22
--- /dev/null
+++ 
b/components/camel-aws2-sns/src/test/java/org/apache/camel/component/aws2/sns/localstack/SnsTopicProducerCustomConfigLocalstackTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.aws2.sns.localstack;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.ExchangePattern;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.aws2.sns.Sns2Constants;
+import org.apache.camel.test.infra.common.SharedNameGenerator;
+import org.apache.camel.test.infra.common.TestEntityNameGenerator;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class SnsTopicProducerCustomConfigLocalstackTest extends 
Aws2SNSBaseTest {
+
+    @RegisterExtension
+    public static SharedNameGenerator sharedNameGenerator = new 
TestEntityNameGenerator();
+
+    @Test
+    public void sendInOnly() throws Exception {
+        Exchange exchange = template.send("direct:start", 
ExchangePattern.InOnly, new Processor() {
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setHeader(Sns2Constants.SUBJECT, "This is my 
subject");
+                exchange.getIn().setBody("This is my message text.");
+            }
+        });
+
+        assertNotNull(exchange.getIn().getHeader(Sns2Constants.MESSAGE_ID));
+    }
+
+    @Test
+    public void sendInOut() throws Exception {
+        Exchange exchange = template.send("direct:start", 
ExchangePattern.InOut, new Processor() {
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setHeader(Sns2Constants.SUBJECT, "This is my 
subject");
+                exchange.getIn().setBody("This is my message text.");
+            }
+        });
+
+        
assertNotNull(exchange.getMessage().getHeader(Sns2Constants.MESSAGE_ID));
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                        
.toF("aws2-sns://%s?subject=The+subject+message&configuration=#class:%s",
+                                sharedNameGenerator.getName(), 
TestSnsConfiguration.class.getName());
+            }
+        };
+    }
+}
diff --git 
a/components/camel-aws2-sns/src/test/java/org/apache/camel/component/aws2/sns/localstack/TestSnsConfiguration.java
 
b/components/camel-aws2-sns/src/test/java/org/apache/camel/component/aws2/sns/localstack/TestSnsConfiguration.java
new file mode 100644
index 0000000..10a8f5f
--- /dev/null
+++ 
b/components/camel-aws2-sns/src/test/java/org/apache/camel/component/aws2/sns/localstack/TestSnsConfiguration.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.component.aws2.sns.localstack;
+
+import org.apache.camel.component.aws2.sns.Sns2Configuration;
+import org.apache.camel.test.infra.aws2.clients.AWSSDKClientUtils;
+import software.amazon.awssdk.services.sns.SnsClient;
+
+public class TestSnsConfiguration extends Sns2Configuration {
+    private SnsClient snsClient;
+
+    public TestSnsConfiguration() {
+        snsClient = AWSSDKClientUtils.newSNSClient();
+        super.setAmazonSNSClient(snsClient);
+    }
+
+    @Override
+    public void setAmazonSNSClient(SnsClient amazonSNSClient) {
+        // NO-OP
+    }
+
+    @Override
+    public SnsClient getAmazonSNSClient() {
+        return snsClient;
+    }
+}

Reply via email to