CAMEL-17558: Fix salesforce lazy login
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceLoginConfig.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceLoginConfig.java
index c97a9cc..b969aaa 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceLoginConfig.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceLoginConfig.java
@@ -93,6 +93,10 @@
      */
     public void setLoginUrl(String loginUrl) {
         this.loginUrl = loginUrl;
+        if (loginUrl != null) {
+            // strip trailing slash
+            this.loginUrl = loginUrl.endsWith("/") ? loginUrl.substring(0, loginUrl.length() - 1) : loginUrl;
+        }
     }
 
     public String getClientId() {
@@ -227,6 +231,9 @@
     }
 
     public void validate() {
+        if (lazyLogin) {
+            return;
+        }
         ObjectHelper.notNull(loginUrl, "loginUrl");
         ObjectHelper.notNull(clientId, "clientId");
 
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/SalesforceSession.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/SalesforceSession.java
index a0a0c84..4072862 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/SalesforceSession.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/SalesforceSession.java
@@ -97,10 +97,6 @@
         this.timeout = timeout;
         this.config = config;
 
-        // strip trailing '/'
-        String loginUrl = config.getLoginUrl();
-        config.setLoginUrl(loginUrl.endsWith("/") ? loginUrl.substring(0, loginUrl.length() - 1) : loginUrl);
-
         this.objectMapper = JsonUtils.createObjectMapper();
         this.listeners = new CopyOnWriteArraySet<>();
     }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/AbstractSalesforceTestBase.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/AbstractSalesforceTestBase.java
index dd6b88f..1772fd4 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/AbstractSalesforceTestBase.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/AbstractSalesforceTestBase.java
@@ -27,6 +27,7 @@
 public abstract class AbstractSalesforceTestBase extends CamelTestSupport {
 
     protected final Logger log = LoggerFactory.getLogger(getClass());
+    protected SalesforceComponent component;
 
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
@@ -46,7 +47,7 @@
 
     protected void createComponent() throws Exception {
         // create the component
-        SalesforceComponent component = new SalesforceComponent();
+        component = new SalesforceComponent();
         final SalesforceEndpointConfig config = new SalesforceEndpointConfig();
         config.setApiVersion(System.getProperty("apiVersion", salesforceApiVersionToUse()));
         component.setConfig(config);
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/LazyLoginTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/LazyLoginTest.java
new file mode 100644
index 0000000..9dee1e3
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/LazyLoginTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.salesforce;
+
+import java.util.HashMap;
+
+import org.apache.camel.component.salesforce.dto.generated.Merchandise__c;
+import org.junit.jupiter.api.Test;
+
+public class LazyLoginTest extends AbstractSalesforceTestBase {
+
+    @Test
+    public void lazyLoginDoesNotThrowExceptions() throws Exception {
+        // If we got this far, then createComponent() succeeded without an exception related to lazy login
+        // Now we just need to make sure credentials provided after startup work
+        final SalesforceLoginConfig config = LoginConfigHelper.getLoginConfig();
+        component.getLoginConfig().setLoginUrl(config.getLoginUrl());
+        component.getLoginConfig().setClientId(config.getClientId());
+        component.getLoginConfig().setClientSecret(config.getClientSecret());
+        component.getLoginConfig().setUserName(config.getUserName());
+        component.getLoginConfig().setPassword(config.getPassword());
+        component.getLoginConfig().setKeystore(config.getKeystore());
+        component.getLoginConfig().setRefreshToken(config.getRefreshToken());
+        component.getSession().login(null);
+    }
+
+    @Override
+    protected void createComponent() throws Exception {
+        // create the component, but do not set any credentials or login info
+        component = new SalesforceComponent();
+        component.setLazyLogin(true);
+
+        final SalesforceEndpointConfig config = new SalesforceEndpointConfig();
+        config.setApiVersion(System.getProperty("apiVersion", salesforceApiVersionToUse()));
+        component.setConfig(config);
+
+        HashMap<String, Object> clientProperties = new HashMap<>();
+        clientProperties.put("timeout", "60000");
+        clientProperties.put("maxRetries", "3");
+        // 4MB for RestApiIntegrationTest.testGetBlobField()
+        clientProperties.put("maxContentLength", String.valueOf(4 * 1024 * 1024));
+        component.setHttpClientProperties(clientProperties);
+
+        // set DTO package
+        component.setPackages(Merchandise__c.class.getPackage().getName());
+
+        // add it to context
+        context().addComponent("salesforce", component);
+    }
+}