Search in sources :

Example 1 with AsyncApiException

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);
    }
}
Also used : QueryResultList(com.sforce.async.QueryResultList) AsyncApiException(com.sforce.async.AsyncApiException) Predicate(org.apache.gobblin.source.extractor.watermark.Predicate) ByteArrayInputStream(java.io.ByteArrayInputStream) BatchInfoList(com.sforce.async.BatchInfoList) BatchInfo(com.sforce.async.BatchInfo)

Example 2 with AsyncApiException

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);
}
Also used : IOException(java.io.IOException) TSalesforceInputProperties(org.talend.components.salesforce.tsalesforceinput.TSalesforceInputProperties) AsyncApiException(com.sforce.async.AsyncApiException) Test(org.junit.Test)

Example 3 with AsyncApiException

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);
    }
}
Also used : ConnectorConfig(com.sforce.ws.ConnectorConfig) ComponentException(org.talend.components.api.exception.ComponentException) BulkConnection(com.sforce.async.BulkConnection) AsyncApiException(com.sforce.async.AsyncApiException)

Example 4 with AsyncApiException

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;
    }
}
Also used : JobInfo(com.sforce.async.JobInfo) AsyncApiException(com.sforce.async.AsyncApiException)

Example 5 with AsyncApiException

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;
}
Also used : IOException(java.io.IOException) AsyncApiException(com.sforce.async.AsyncApiException) ConnectionException(com.sforce.ws.ConnectionException)

Aggregations

AsyncApiException (com.sforce.async.AsyncApiException)10 IOException (java.io.IOException)6 ConnectionException (com.sforce.ws.ConnectionException)5 ComponentException (org.talend.components.api.exception.ComponentException)3 BulkConnection (com.sforce.async.BulkConnection)2 ConnectorConfig (com.sforce.ws.ConnectorConfig)2 TSalesforceBulkExecProperties (org.talend.components.salesforce.tsalesforcebulkexec.TSalesforceBulkExecProperties)2 BatchInfo (com.sforce.async.BatchInfo)1 BatchInfoList (com.sforce.async.BatchInfoList)1 JobInfo (com.sforce.async.JobInfo)1 QueryResultList (com.sforce.async.QueryResultList)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 Predicate (org.apache.gobblin.source.extractor.watermark.Predicate)1 Test (org.junit.Test)1 SalesforceConnectionProperties (org.talend.components.salesforce.SalesforceConnectionProperties)1 SalesforceBulkRuntime (org.talend.components.salesforce.runtime.SalesforceBulkRuntime)1 ConnectionHolder (org.talend.components.salesforce.runtime.common.ConnectionHolder)1 TSalesforceInputProperties (org.talend.components.salesforce.tsalesforceinput.TSalesforceInputProperties)1