Skip to content

Commit 82bb730

Browse files
Merge pull request #1652 from mcgrinberg/merge-src-from-private
W-21353818 Update src changes
2 parents 527e912 + de086f3 commit 82bb730

9 files changed

Lines changed: 155 additions & 10 deletions

File tree

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>com.force</groupId>
55
<artifactId>dataloader</artifactId>
6-
<version>64.1.0</version>
6+
<version>65.0.0</version>
77
<packaging>jar</packaging>
88
<name>Salesforce Data Loader</name>
99
<url>https://github.com/forcedotcom/dataloader</url>

src/main/java/com/salesforce/dataloader/action/visitor/bulk/BulkApiVisitorUtil.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ private void updateJobStatus() {
354354

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

375375
// hack because jobInfo is not updated if an entire batch fails
376376
private int getNumRecordsFailedInJob() {
377-
int numRecordsFailedInJob = this.jobInfo.getNumberRecordsFailed();
377+
int numRecordsFailedInJob = (int) this.jobInfo.getNumberRecordsFailed();
378378
int numRecordsPerBatch = 0;
379379
try {
380380
numRecordsPerBatch = this.appConfig.getInt(AppConfig.PROP_IMPORT_BATCH_SIZE);

src/main/java/com/salesforce/dataloader/client/ClientBase.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ public ConnectorConfig getConnectorConfig() {
220220
cc.setAuthEndpoint(server + PartnerClient.getServicePath());
221221
cc.setServiceEndpoint(server + PartnerClient.getServicePath()); // Partner SOAP service
222222
cc.setRestEndpoint(server + BulkV1Client.getServicePath()); // REST service: Bulk v1
223+
logger.info("Post-login endpoint configured: SOAP=" + PartnerClient.getServicePath()
224+
+ ", REST=" + BulkV1Client.getServicePath());
223225
}
224226

225227
return cc;
@@ -229,7 +231,7 @@ public static String getCurrentAPIVersionInWSC() {
229231
String[] connectURLArray = Connector.END_POINT.split("\\/");
230232
return connectURLArray[connectURLArray.length-1];
231233
}
232-
234+
233235
public static String getPreviousAPIVersionInWSC() {
234236
String currentAPIVersion = getCurrentAPIVersionInWSC();
235237
String[] versionStrArray = currentAPIVersion.split("\\.");

src/main/java/com/salesforce/dataloader/client/LoginClient.java

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ public class LoginClient extends ClientBase<PartnerConnection> {
6262

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

65+
/** Minimum API version where SOAP login is no longer supported (per Salesforce). */
66+
private static final double SOAP_LOGIN_REMOVED_IN_VERSION = 65.0;
67+
/** API version to use for SOAP login when session version >= 65.0 (per product decision). */
68+
private static final String DEFAULT_LOGIN_API_VERSION = "64.0";
69+
6570
private ConnectorConfig connectorConfig = null;
6671

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

340+
/**
341+
* API version to use for the SOAP login request only.
342+
* SOAP login is not supported in API versions >= 65; for those, returns 64.0.
343+
* Other operations continue to use the session version unchanged.
344+
*/
345+
public static String getApiVersionForLogin(String currentSessionVersion) {
346+
if (currentSessionVersion == null || currentSessionVersion.isEmpty()) {
347+
return currentSessionVersion;
348+
}
349+
try {
350+
double version = Double.parseDouble(currentSessionVersion);
351+
return version >= SOAP_LOGIN_REMOVED_IN_VERSION ? DEFAULT_LOGIN_API_VERSION : currentSessionVersion;
352+
} catch (NumberFormatException e) {
353+
LOG.error("Invalid session API version for login: {}", currentSessionVersion, e);
354+
throw new IllegalArgumentException("Invalid session API version: " + currentSessionVersion, e);
355+
}
356+
}
357+
334358
public static String getServicePath() {
335-
return "/services/Soap/u/" + getAPIVersionForTheSession() + "/";
359+
return getServicePath(getAPIVersionForTheSession());
360+
}
361+
362+
public static String getServicePath(String apiVersion) {
363+
return "/services/Soap/u/" + apiVersion + "/";
336364
}
337365

338366
public LimitInfo getAPILimitInfo() {
@@ -353,8 +381,9 @@ private synchronized ConnectorConfig getLoginConnectorConfig(String serverURL) {
353381
serverURL = appConfig.getAuthEndpointForCurrentEnv();
354382
}
355383
this.connectorConfig = getConnectorConfig();
356-
this.connectorConfig.setAuthEndpoint(serverURL + getServicePath());
357-
this.connectorConfig.setServiceEndpoint(serverURL + getServicePath());
384+
String loginServicePath = getServicePath(getApiVersionForLogin(getAPIVersionForTheSession()));
385+
this.connectorConfig.setAuthEndpoint(serverURL + loginServicePath);
386+
this.connectorConfig.setServiceEndpoint(serverURL + loginServicePath);
358387
return this.connectorConfig;
359388
}
360389

src/main/java/com/salesforce/dataloader/controller/Controller.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,11 +539,13 @@ else if (filePath.equals(daoName))
539539
public void logout() {
540540
getLoginClient().logout();
541541
getPartnerClient().logout();
542+
getSObjectMetaDataClient().logout();
542543

543544
this.bulkV1Client = null;
544545
this.bulkV2Client = null;
545546
this.restClient = null;
546547
appConfig.setValue(AppConfig.PROP_OAUTH_ACCESSTOKEN, "");
548+
appConfig.setValue(AppConfig.PROP_ENTITY, "");
547549
}
548550

549551
public boolean attachmentsEnabled() {

src/main/java/com/salesforce/dataloader/ui/LoaderWindow.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ public void refresh() {
119119
public void dispose() {
120120
// make sure configuration gets written
121121
if(this.controller != null) {
122+
// Clear metadata client cache and entity selection to prevent stale org data on restart
123+
if (this.controller.isLoggedIn()) {
124+
this.controller.getSObjectMetaDataClient().logout();
125+
this.controller.getAppConfig().setValue(com.salesforce.dataloader.config.AppConfig.PROP_ENTITY, "");
126+
}
122127
controller.saveConfig();
123128
}
124129
}

src/test/java/com/salesforce/dataloader/TestBase.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
package com.salesforce.dataloader;
2727

2828
import com.salesforce.dataloader.client.BulkV1Client;
29+
import com.salesforce.dataloader.client.LoginClient;
2930
import com.salesforce.dataloader.client.PartnerClient;
3031
import com.salesforce.dataloader.config.AppConfig;
3132
import com.salesforce.dataloader.config.Messages;
@@ -293,8 +294,10 @@ protected ConnectorConfig getWSCConfig(String apiVersionStr) {
293294
if (!configEndpoint.equals("")) { //$NON-NLS-1$
294295
try {
295296
PartnerClient.setAPIVersionForTheSession(apiVersionStr);
296-
bindingConfig.setAuthEndpoint(configEndpoint + PartnerClient.getServicePath());
297-
bindingConfig.setServiceEndpoint(configEndpoint + PartnerClient.getServicePath()); // Partner SOAP service
297+
String loginVersion = LoginClient.getApiVersionForLogin(apiVersionStr);
298+
String loginServicePath = LoginClient.getServicePath(loginVersion);
299+
bindingConfig.setAuthEndpoint(configEndpoint + loginServicePath);
300+
bindingConfig.setServiceEndpoint(configEndpoint + loginServicePath);
298301
bindingConfig.setRestEndpoint(configEndpoint + BulkV1Client.getServicePath()); // REST service: Bulk v1
299302
bindingConfig.setManualLogin(true);
300303
// set long timeout for tests with larger data sets
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Copyright (c) 2015, salesforce.com, inc.
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
6+
* that the following conditions are met:
7+
*
8+
* Redistributions of source code must retain the above copyright notice, this list of conditions and the
9+
* following disclaimer.
10+
*
11+
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
12+
* the following disclaimer in the documentation and/or other materials provided with the distribution.
13+
*
14+
* Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or
15+
* promote products derived from this software without specific prior written permission.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
18+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
19+
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20+
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21+
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24+
* POSSIBILITY OF SUCH DAMAGE.
25+
*/
26+
package com.salesforce.dataloader.client;
27+
28+
import org.junit.Test;
29+
30+
import static org.junit.Assert.assertEquals;
31+
import static org.junit.Assert.assertNull;
32+
33+
/**
34+
* Unit tests for LoginClient API version logic.
35+
* SOAP login is not supported in API versions >= 65; login falls back to 64.0.
36+
*/
37+
public class LoginClientTest {
38+
39+
@Test
40+
public void getApiVersionForLogin_when65_returns64() {
41+
assertEquals("64.0", LoginClient.getApiVersionForLogin("65.0"));
42+
}
43+
44+
@Test
45+
public void getApiVersionForLogin_when66_returns64() {
46+
assertEquals("64.0", LoginClient.getApiVersionForLogin("66.0"));
47+
}
48+
49+
@Test
50+
public void getApiVersionForLogin_when70_returns64() {
51+
assertEquals("64.0", LoginClient.getApiVersionForLogin("70.0"));
52+
}
53+
54+
@Test
55+
public void getApiVersionForLogin_when64_returns64() {
56+
assertEquals("64.0", LoginClient.getApiVersionForLogin("64.0"));
57+
}
58+
59+
@Test
60+
public void getApiVersionForLogin_when63_returns63() {
61+
assertEquals("63.0", LoginClient.getApiVersionForLogin("63.0"));
62+
}
63+
64+
@Test
65+
public void getApiVersionForLogin_when50_returns50() {
66+
assertEquals("50.0", LoginClient.getApiVersionForLogin("50.0"));
67+
}
68+
69+
@Test
70+
public void getApiVersionForLogin_whenNull_returnsNull() {
71+
assertNull(LoginClient.getApiVersionForLogin(null));
72+
}
73+
74+
@Test
75+
public void getApiVersionForLogin_whenEmpty_returnsEmpty() {
76+
assertEquals("", LoginClient.getApiVersionForLogin(""));
77+
}
78+
79+
@Test
80+
public void getServicePath_usesProvidedVersion() {
81+
assertEquals("/services/Soap/u/64.0/", LoginClient.getServicePath("64.0"));
82+
assertEquals("/services/Soap/u/65.0/", LoginClient.getServicePath("65.0"));
83+
}
84+
85+
@Test
86+
public void getServicePath_withLoginVersion_uses64ForV65Session() {
87+
String loginVersion = LoginClient.getApiVersionForLogin("65.0");
88+
assertEquals("/services/Soap/u/64.0/", LoginClient.getServicePath(loginVersion));
89+
}
90+
91+
@Test
92+
public void getServicePath_withLoginVersion_passesThrough64() {
93+
String loginVersion = LoginClient.getApiVersionForLogin("64.0");
94+
assertEquals("/services/Soap/u/64.0/", LoginClient.getServicePath(loginVersion));
95+
}
96+
97+
@Test
98+
public void getServicePath_withLoginVersion_passesThrough63() {
99+
String loginVersion = LoginClient.getApiVersionForLogin("63.0");
100+
assertEquals("/services/Soap/u/63.0/", LoginClient.getServicePath(loginVersion));
101+
}
102+
103+
}

src/test/java/com/salesforce/dataloader/util/DateOnlyCalendarTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public void setUp() {
3939
dateOnlyCalendar = new DateOnlyCalendar();
4040
}
4141

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

0 commit comments

Comments
 (0)