use of com.sforce.async.AsyncApiException in project incubator-gobblin by apache.
the class SalesforceExtractor method getQueryResultIds.
/**
* Get Record set using salesforce specific API(Bulk API)
* @param entity/tablename
* @param predicateList of all predicate conditions
* @return iterator with batch of records
*/
private List<BatchIdAndResultId> getQueryResultIds(String entity, List<Predicate> predicateList) throws Exception {
if (!bulkApiLogin()) {
throw new IllegalArgumentException("Invalid Login");
}
try {
boolean usingPkChunking = false;
// Set bulk job attributes
this.bulkJob.setObject(entity);
this.bulkJob.setOperation(OperationEnum.query);
this.bulkJob.setConcurrencyMode(ConcurrencyMode.Parallel);
// use pk chunking if pk chunking is configured and the expected record count is larger than the pk chunking size
if (this.pkChunking && getExpectedRecordCount() > this.pkChunkingSize) {
log.info("Enabling pk chunking with size {}", this.pkChunkingSize);
this.bulkConnection.addHeader("Sforce-Enable-PKChunking", "chunkSize=" + this.pkChunkingSize);
usingPkChunking = true;
}
// Result type as CSV
this.bulkJob.setContentType(ContentType.CSV);
this.bulkJob = this.bulkConnection.createJob(this.bulkJob);
this.bulkJob = this.bulkConnection.getJobStatus(this.bulkJob.getId());
// Construct query with the predicates
String query = this.updatedQuery;
if (!isNullPredicate(predicateList)) {
String limitString = getLimitFromInputQuery(query);
query = query.replace(limitString, "");
Iterator<Predicate> i = predicateList.listIterator();
while (i.hasNext()) {
Predicate predicate = i.next();
query = SqlQueryUtils.addPredicate(query, predicate.getCondition());
}
query = query + limitString;
}
log.info("QUERY:" + query);
ByteArrayInputStream bout = new ByteArrayInputStream(query.getBytes(ConfigurationKeys.DEFAULT_CHARSET_ENCODING));
BatchInfo bulkBatchInfo = this.bulkConnection.createBatchFromStream(this.bulkJob, bout);
long expectedSizePerBatch = usingPkChunking ? this.pkChunkingSize : this.getExpectedRecordCount();
int retryInterval = Math.min(MAX_RETRY_INTERVAL_SECS, 30 + (int) Math.ceil((float) expectedSizePerBatch / 10000) * 2);
log.info("Salesforce bulk api retry interval in seconds:" + retryInterval);
// Get batch info with complete resultset (info id - refers to the resultset id corresponding to entire resultset)
bulkBatchInfo = this.bulkConnection.getBatchInfo(this.bulkJob.getId(), bulkBatchInfo.getId());
// wait for completion, failure, or formation of PK chunking batches
while ((bulkBatchInfo.getState() != BatchStateEnum.Completed) && (bulkBatchInfo.getState() != BatchStateEnum.Failed) && (!usingPkChunking || bulkBatchInfo.getState() != BatchStateEnum.NotProcessed)) {
Thread.sleep(retryInterval * 1000);
bulkBatchInfo = this.bulkConnection.getBatchInfo(this.bulkJob.getId(), bulkBatchInfo.getId());
log.debug("Bulk Api Batch Info:" + bulkBatchInfo);
log.info("Waiting for bulk resultSetIds");
}
// Wait for pk chunking batches
BatchInfoList batchInfoList = this.bulkConnection.getBatchInfoList(this.bulkJob.getId());
if (usingPkChunking && bulkBatchInfo.getState() == BatchStateEnum.NotProcessed) {
bulkBatchInfo = waitForPkBatches(batchInfoList, retryInterval);
}
if (bulkBatchInfo.getState() == BatchStateEnum.Failed) {
log.error("Bulk batch failed: " + bulkBatchInfo.toString());
throw new RuntimeException("Failed to get bulk batch info for jobId " + bulkBatchInfo.getJobId() + " error - " + bulkBatchInfo.getStateMessage());
}
// Get resultset ids of all the batches from the batch info list
List<BatchIdAndResultId> batchIdAndResultIdList = Lists.newArrayList();
for (BatchInfo bi : batchInfoList.getBatchInfo()) {
QueryResultList list = this.bulkConnection.getQueryResultList(this.bulkJob.getId(), bi.getId());
for (String result : list.getResult()) {
batchIdAndResultIdList.add(new BatchIdAndResultId(bi.getId(), result));
}
}
log.info("QueryResultList: " + batchIdAndResultIdList);
return batchIdAndResultIdList;
} catch (RuntimeException | AsyncApiException | InterruptedException e) {
throw new RuntimeException("Failed to get query result ids from salesforce using bulk api; error - " + e.getMessage(), e);
}
}
use of com.sforce.async.AsyncApiException in project components by Talend.
the class SalesforceSessionReuseTestIT method testBulkSessionRenew.
@Test
public void testBulkSessionRenew() throws Exception {
// $NON-NLS-1$
TSalesforceInputProperties props = (TSalesforceInputProperties) new TSalesforceInputProperties("foo").init();
props.module.moduleName.setValue(EXISTING_MODULE_NAME);
props.module.main.schema.setValue(getMakeRowSchema(false));
props.connection = setupProps(null, !ADD_QUOTES);
// setup session function
props.connection.bulkConnection.setValue(true);
props.queryMode.setValue(TSalesforceInputProperties.QueryMode.Bulk);
props.condition.setValue("Name = '" + randomizedValue + "'");
// Init session
assertEquals(ValidationResult.Result.OK, testConnection(props).getStatus());
BoundedReader<?> reader = createBoundedReader(props);
assertThat(reader, instanceOf(SalesforceBulkQueryInputReader.class));
reader.start();
// Invalid the session by session id
String sessionIdBeforeRenew = ((SalesforceBulkQueryInputReader) reader).bulkRuntime.getBulkConnection().getConfig().getSessionId();
reader.close();
Thread.sleep(1000);
invalidSession(props.connection, sessionIdBeforeRenew);
// Test renew session for bulk connections
try {
reader.start();
} catch (IOException io) {
if (io.getCause() instanceof AsyncApiException && io.getMessage().contains("Unable to find any data to create batch")) {
// This kind of error shows that connection is established well, but some issue with test data.
// It happens in SalesforceBulkRuntime inside of method createBatchFromStream, after job was created.
LOGGER.warn("Issue with getting prepared test data. Error msg - {}", io.getMessage());
} else {
throw io;
}
}
// Check the renew session
String sessionIdAfterRenew = ((SalesforceBulkQueryInputReader) reader).bulkRuntime.getBulkConnection().getConfig().getSessionId();
reader.close();
assertNotEquals(sessionIdBeforeRenew, sessionIdAfterRenew);
}
use of com.sforce.async.AsyncApiException in project components by Talend.
the class SalesforceDataprepSource method connectBulk.
protected BulkConnection connectBulk(ConnectorConfig config) throws ComponentException {
/*
* When PartnerConnection is instantiated, a login is implicitly executed and, if successful, a valid session is
* stored in the ConnectorConfig instance. Use this key to initialize a BulkConnection:
*/
ConnectorConfig bulkConfig = new ConnectorConfig();
bulkConfig.setSessionId(config.getSessionId());
// For session renew
bulkConfig.setSessionRenewer(config.getSessionRenewer());
bulkConfig.setUsername(config.getUsername());
bulkConfig.setPassword(config.getPassword());
/*
* The endpoint for the Bulk API service is the same as for the normal SOAP uri until the /Soap/ part. From here
* it's '/async/versionNumber'
*/
String soapEndpoint = config.getServiceEndpoint();
// set it by a default property file
// Service endpoint should be like this:
// https://ap1.salesforce.com/services/Soap/u/37.0/00D90000000eSq3
String apiVersion = soapEndpoint.substring(soapEndpoint.lastIndexOf("/services/Soap/u/") + 17);
apiVersion = apiVersion.substring(0, apiVersion.indexOf("/"));
String restEndpoint = soapEndpoint.substring(0, soapEndpoint.indexOf("Soap/")) + "async/" + apiVersion;
bulkConfig.setRestEndpoint(restEndpoint);
// This should only be false when doing debugging.
bulkConfig.setCompression(true);
bulkConfig.setTraceMessage(false);
bulkConfig.setValidateSchema(false);
try {
return new BulkConnection(bulkConfig);
} catch (AsyncApiException e) {
throw new ComponentException(e);
}
}
use of com.sforce.async.AsyncApiException in project components by Talend.
the class SalesforceBulkRuntime method closeJob.
/**
* Close the job
*
* @throws AsyncApiException
* @throws ConnectionException
*/
public void closeJob() throws AsyncApiException, ConnectionException {
JobInfo closeJob = new JobInfo();
closeJob.setId(job.getId());
closeJob.setState(JobStateEnum.Closed);
try {
bulkConnection.updateJob(closeJob);
} catch (AsyncApiException sfException) {
if (AsyncExceptionCode.InvalidSessionId.equals(sfException.getExceptionCode())) {
SalesforceRuntimeCommon.renewSession(bulkConnection.getConfig());
closeJob();
} else if (AsyncExceptionCode.InvalidJobState.equals(sfException.getExceptionCode())) {
// Job is already closed on Salesforce side. We don't need to close it again.
return;
}
throw sfException;
}
}
use of com.sforce.async.AsyncApiException in project components by Talend.
the class SalesforceBulkQueryReader method advance.
@Override
public boolean advance() throws IOException {
currentRecord = bulkResultSet.next();
if (currentRecord == null) {
String resultId = bulkRuntime.nextResultId();
if (resultId != null) {
try {
// Get a new result set
bulkResultSet = bulkRuntime.getQueryResultSet(resultId);
currentRecord = bulkResultSet.next();
boolean advance = currentRecord != null;
if (advance) {
// New result set available to retrieve
dataCount++;
}
return advance;
} catch (AsyncApiException | ConnectionException e) {
throw new IOException(e);
}
} else {
return false;
}
}
dataCount++;
return true;
}
Aggregations