Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.force</groupId>
<artifactId>dataloader</artifactId>
<version>64.1.0</version>
<version>65.0.0</version>
<packaging>jar</packaging>
<name>Salesforce Data Loader</name>
<url>https://github.com/forcedotcom/dataloader</url>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ private void updateJobStatus() {

// hack because jobInfo is not updated if an entire batch fails
private int getNumRecordsProcessedInJob() {
int numRecordsProcessedInJob = this.jobInfo.getNumberRecordsProcessed();
int numRecordsProcessedInJob = (int) this.jobInfo.getNumberRecordsProcessed();
if (appConfig.isBulkAPIEnabled() || appConfig.isBulkV2APIEnabled()) {
// Bulk v2 counts all processed records in the total
numRecordsProcessedInJob -= this.jobInfo.getNumberRecordsFailed();
Expand All @@ -374,7 +374,7 @@ private int getNumRecordsProcessedInJob() {

// hack because jobInfo is not updated if an entire batch fails
private int getNumRecordsFailedInJob() {
int numRecordsFailedInJob = this.jobInfo.getNumberRecordsFailed();
int numRecordsFailedInJob = (int) this.jobInfo.getNumberRecordsFailed();
int numRecordsPerBatch = 0;
try {
numRecordsPerBatch = this.appConfig.getInt(AppConfig.PROP_IMPORT_BATCH_SIZE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ public ConnectorConfig getConnectorConfig() {
cc.setAuthEndpoint(server + PartnerClient.getServicePath());
cc.setServiceEndpoint(server + PartnerClient.getServicePath()); // Partner SOAP service
cc.setRestEndpoint(server + BulkV1Client.getServicePath()); // REST service: Bulk v1
logger.info("Post-login endpoint configured: SOAP=" + PartnerClient.getServicePath()
+ ", REST=" + BulkV1Client.getServicePath());
}

return cc;
Expand All @@ -229,7 +231,7 @@ public static String getCurrentAPIVersionInWSC() {
String[] connectURLArray = Connector.END_POINT.split("\\/");
return connectURLArray[connectURLArray.length-1];
}

public static String getPreviousAPIVersionInWSC() {
String currentAPIVersion = getCurrentAPIVersionInWSC();
String[] versionStrArray = currentAPIVersion.split("\\.");
Expand Down
37 changes: 33 additions & 4 deletions src/main/java/com/salesforce/dataloader/client/LoginClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ public class LoginClient extends ClientBase<PartnerConnection> {

private static Logger LOG = DLLogManager.getLogger(LoginClient.class);

/** Minimum API version where SOAP login is no longer supported (per Salesforce). */
private static final double SOAP_LOGIN_REMOVED_IN_VERSION = 65.0;
/** API version to use for SOAP login when session version >= 65.0 (per product decision). */
private static final String DEFAULT_LOGIN_API_VERSION = "64.0";

private ConnectorConfig connectorConfig = null;

private LoginClient(Controller controller) {
Expand Down Expand Up @@ -133,7 +138,8 @@ private boolean login() throws ConnectionException, ApiFault {
String origEndpoint = new String(appConfig.getAuthEndpointForCurrentEnv());
try {
dologin();
logger.debug("able to successfully invoke server APIs of version " + getAPIVersionForTheSession());
logger.info("Login succeeded using API " + getApiVersionForLogin(getAPIVersionForTheSession())
+ ", session API version for operations: " + getAPIVersionForTheSession());
} catch (UnexpectedErrorFault fault) {
// attempt login with previous API version
if (fault.getExceptionCode() == ExceptionCode.UNSUPPORTED_API_VERSION
Expand Down Expand Up @@ -331,8 +337,30 @@ public ConnectorConfig getConnectorConfig() {
return cc;
}

/**
* API version to use for the SOAP login request only.
* SOAP login is not supported in API versions >= 65; for those, returns 64.0.
* Other operations continue to use the session version unchanged.
*/
public static String getApiVersionForLogin(String currentSessionVersion) {
if (currentSessionVersion == null || currentSessionVersion.isEmpty()) {
return currentSessionVersion;
}
try {
double version = Double.parseDouble(currentSessionVersion);
return version >= SOAP_LOGIN_REMOVED_IN_VERSION ? DEFAULT_LOGIN_API_VERSION : currentSessionVersion;
} catch (NumberFormatException e) {
LOG.error("Invalid session API version for login: {}", currentSessionVersion, e);
throw new IllegalArgumentException("Invalid session API version: " + currentSessionVersion, e);
}
}

public static String getServicePath() {
return "/services/Soap/u/" + getAPIVersionForTheSession() + "/";
return getServicePath(getAPIVersionForTheSession());
}

public static String getServicePath(String apiVersion) {
return "/services/Soap/u/" + apiVersion + "/";
}

public LimitInfo getAPILimitInfo() {
Expand All @@ -353,8 +381,9 @@ private synchronized ConnectorConfig getLoginConnectorConfig(String serverURL) {
serverURL = appConfig.getAuthEndpointForCurrentEnv();
}
this.connectorConfig = getConnectorConfig();
this.connectorConfig.setAuthEndpoint(serverURL + getServicePath());
this.connectorConfig.setServiceEndpoint(serverURL + getServicePath());
String loginServicePath = getServicePath(getApiVersionForLogin(getAPIVersionForTheSession()));
this.connectorConfig.setAuthEndpoint(serverURL + loginServicePath);
this.connectorConfig.setServiceEndpoint(serverURL + loginServicePath);
return this.connectorConfig;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -539,11 +539,13 @@ else if (filePath.equals(daoName))
public void logout() {
getLoginClient().logout();
getPartnerClient().logout();
getSObjectMetaDataClient().logout();

this.bulkV1Client = null;
this.bulkV2Client = null;
this.restClient = null;
appConfig.setValue(AppConfig.PROP_OAUTH_ACCESSTOKEN, "");
appConfig.setValue(AppConfig.PROP_ENTITY, "");
}

public boolean attachmentsEnabled() {
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/com/salesforce/dataloader/ui/LoaderWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ public void refresh() {
public void dispose() {
// make sure configuration gets written
if(this.controller != null) {
// Clear metadata client cache and entity selection to prevent stale org data on restart
if (this.controller.isLoggedIn()) {
this.controller.getSObjectMetaDataClient().logout();
this.controller.getAppConfig().setValue(com.salesforce.dataloader.config.AppConfig.PROP_ENTITY, "");
}
controller.saveConfig();
}
}
Expand Down
7 changes: 5 additions & 2 deletions src/test/java/com/salesforce/dataloader/TestBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
package com.salesforce.dataloader;

import com.salesforce.dataloader.client.BulkV1Client;
import com.salesforce.dataloader.client.LoginClient;
import com.salesforce.dataloader.client.PartnerClient;
import com.salesforce.dataloader.config.AppConfig;
import com.salesforce.dataloader.config.Messages;
Expand Down Expand Up @@ -293,8 +294,10 @@ protected ConnectorConfig getWSCConfig(String apiVersionStr) {
if (!configEndpoint.equals("")) { //$NON-NLS-1$
try {
PartnerClient.setAPIVersionForTheSession(apiVersionStr);
bindingConfig.setAuthEndpoint(configEndpoint + PartnerClient.getServicePath());
bindingConfig.setServiceEndpoint(configEndpoint + PartnerClient.getServicePath()); // Partner SOAP service
String loginVersion = LoginClient.getApiVersionForLogin(apiVersionStr);
String loginServicePath = LoginClient.getServicePath(loginVersion);
bindingConfig.setAuthEndpoint(configEndpoint + loginServicePath);
bindingConfig.setServiceEndpoint(configEndpoint + loginServicePath);
bindingConfig.setRestEndpoint(configEndpoint + BulkV1Client.getServicePath()); // REST service: Bulk v1
bindingConfig.setManualLogin(true);
// set long timeout for tests with larger data sets
Expand Down
103 changes: 103 additions & 0 deletions src/test/java/com/salesforce/dataloader/client/LoginClientTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright (c) 2015, salesforce.com, inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package com.salesforce.dataloader.client;

import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

/**
* Unit tests for LoginClient API version logic.
* SOAP login is not supported in API versions >= 65; login falls back to 64.0.
*/
public class LoginClientTest {

@Test
public void getApiVersionForLogin_when65_returns64() {
assertEquals("64.0", LoginClient.getApiVersionForLogin("65.0"));
}

@Test
public void getApiVersionForLogin_when66_returns64() {
assertEquals("64.0", LoginClient.getApiVersionForLogin("66.0"));
}

@Test
public void getApiVersionForLogin_when70_returns64() {
assertEquals("64.0", LoginClient.getApiVersionForLogin("70.0"));
}

@Test
public void getApiVersionForLogin_when64_returns64() {
assertEquals("64.0", LoginClient.getApiVersionForLogin("64.0"));
}

@Test
public void getApiVersionForLogin_when63_returns63() {
assertEquals("63.0", LoginClient.getApiVersionForLogin("63.0"));
}

@Test
public void getApiVersionForLogin_when50_returns50() {
assertEquals("50.0", LoginClient.getApiVersionForLogin("50.0"));
}

@Test
public void getApiVersionForLogin_whenNull_returnsNull() {
assertNull(LoginClient.getApiVersionForLogin(null));
}

@Test
public void getApiVersionForLogin_whenEmpty_returnsEmpty() {
assertEquals("", LoginClient.getApiVersionForLogin(""));
}

@Test
public void getServicePath_usesProvidedVersion() {
assertEquals("/services/Soap/u/64.0/", LoginClient.getServicePath("64.0"));
assertEquals("/services/Soap/u/65.0/", LoginClient.getServicePath("65.0"));
}

@Test
public void getServicePath_withLoginVersion_uses64ForV65Session() {
String loginVersion = LoginClient.getApiVersionForLogin("65.0");
assertEquals("/services/Soap/u/64.0/", LoginClient.getServicePath(loginVersion));
}

@Test
public void getServicePath_withLoginVersion_passesThrough64() {
String loginVersion = LoginClient.getApiVersionForLogin("64.0");
assertEquals("/services/Soap/u/64.0/", LoginClient.getServicePath(loginVersion));
}

@Test
public void getServicePath_withLoginVersion_passesThrough63() {
String loginVersion = LoginClient.getApiVersionForLogin("63.0");
assertEquals("/services/Soap/u/63.0/", LoginClient.getServicePath(loginVersion));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public void setUp() {
dateOnlyCalendar = new DateOnlyCalendar();
}

@Ignore // This test assumes that the default timezone is PST, which is not true on all systems
@Test
public void testSetTimeInMillisWithDefaultTimeZone() {
long timeInMillis = 1633046400000L; // 2021-10-01 00:00:00 GMT
Expand Down
Loading