/**
* 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.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.component.salesforce.api.dto.analytics.reports.ReportMetadata;
import org.apache.camel.component.salesforce.api.dto.approval.ApprovalRequest;
import org.apache.camel.component.salesforce.api.dto.approval.ApprovalRequest.Action;
import org.apache.camel.component.salesforce.api.dto.bulk.ContentType;
import org.apache.camel.component.salesforce.internal.PayloadFormat;
import org.apache.camel.component.salesforce.internal.dto.NotifyForFieldsEnum;
import org.apache.camel.component.salesforce.internal.dto.NotifyForOperationsEnum;
import org.apache.camel.spi.UriParam;
import org.apache.camel.spi.UriParams;
/**
* Salesforce Endpoint configuration.
*/
@UriParams
public class SalesforceEndpointConfig implements Cloneable {
// default API version
public static final String DEFAULT_VERSION = "34.0";
// general parameter
public static final String API_VERSION = "apiVersion";
// parameters for Rest API
public static final String FORMAT = "format";
public static final String SOBJECT_NAME = "sObjectName";
public static final String SOBJECT_ID = "sObjectId";
public static final String SOBJECT_FIELDS = "sObjectFields";
public static final String SOBJECT_EXT_ID_NAME = "sObjectIdName";
public static final String SOBJECT_EXT_ID_VALUE = "sObjectIdValue";
public static final String SOBJECT_BLOB_FIELD_NAME = "sObjectBlobFieldName";
public static final String SOBJECT_CLASS = "sObjectClass";
public static final String SOBJECT_QUERY = "sObjectQuery";
public static final String SOBJECT_SEARCH = "sObjectSearch";
public static final String APEX_METHOD = "apexMethod";
public static final String APEX_URL = "apexUrl";
public static final String LIMIT = "limit";
// prefix for parameters in headers
public static final String APEX_QUERY_PARAM_PREFIX = "apexQueryParam.";
// parameters for Bulk API
public static final String CONTENT_TYPE = "contentType";
public static final String JOB_ID = "jobId";
public static final String BATCH_ID = "batchId";
public static final String RESULT_ID = "resultId";
// parameters for Analytics API
public static final String REPORT_ID = "reportId";
public static final String INCLUDE_DETAILS = "includeDetails";
public static final String REPORT_METADATA = "reportMetadata";
public static final String INSTANCE_ID = "instanceId";
// parameters for Streaming API
public static final String DEFAULT_REPLAY_ID = "defaultReplayId";
public static final String INITIAL_REPLAY_ID_MAP = "initialReplayIdMap";
// parameters for Approval API
public static final String APPROVAL = "approval";
// default maximum authentication retries on failed authentication or expired session
public static final int DEFAULT_MAX_AUTHENTICATION_RETRIES = 4;
// default increment and limit for Streaming connection restart attempts
public static final long DEFAULT_BACKOFF_INCREMENT = 1000L;
public static final long DEFAULT_MAX_BACKOFF = 30000L;
public static final String NOT_FOUND_BEHAVIOUR = "notFoundBehaviour";
// general properties
@UriParam
private String apiVersion = DEFAULT_VERSION;
// Rest API properties
@UriParam
private PayloadFormat format = PayloadFormat.JSON;
@UriParam(displayName = "SObject Name")
private String sObjectName;
@UriParam(displayName = "SObject Id")
private String sObjectId;
@UriParam(displayName = "SObject Fields")
private String sObjectFields;
@UriParam(displayName = "SObject Id Name")
private String sObjectIdName;
@UriParam(displayName = "SObject Id Value")
private String sObjectIdValue;
@UriParam(displayName = "SObject Blob Field Name")
private String sObjectBlobFieldName;
@UriParam(displayName = "SObject Class")
private String sObjectClass;
@UriParam(displayName = "SObject Query")
private String sObjectQuery;
@UriParam(displayName = "SObject Search")
private String sObjectSearch;
@UriParam
private String apexMethod;
@UriParam
private String apexUrl;
@UriParam
private Map<String, Object> apexQueryParams;
// Bulk API properties
@UriParam
private ContentType contentType;
@UriParam
private String jobId;
@UriParam
private String batchId;
@UriParam
private String resultId;
// Streaming API properties
@UriParam
private boolean updateTopic;
@UriParam
private NotifyForFieldsEnum notifyForFields;
@UriParam
private NotifyForOperationsEnum notifyForOperations;
@UriParam
private Boolean notifyForOperationCreate;
@UriParam
private Boolean notifyForOperationUpdate;
@UriParam
private Boolean notifyForOperationDelete;
@UriParam
private Boolean notifyForOperationUndelete;
// Analytics API properties
@UriParam
private String reportId;
@UriParam
private Boolean includeDetails;
@UriParam
private ReportMetadata reportMetadata;
@UriParam
private String instanceId;
// Streaming API properties
@UriParam
private Long defaultReplayId;
@UriParam
private Map<String, Long> initialReplayIdMap;
// Approval API properties
private ApprovalRequest approval;
// Salesforce Jetty9 HttpClient, set using reference
@UriParam
private SalesforceHttpClient httpClient;
// To allow custom ObjectMapper (for registering extra datatype modules)
@UriParam
private ObjectMapper objectMapper;
// Streaming connection restart attempt backoff interval increment
@UriParam
private long backoffIncrement = DEFAULT_BACKOFF_INCREMENT;
// Streaming connection restart attempt maximum backoff interval
@UriParam
private long maxBackoff = DEFAULT_MAX_BACKOFF;
@UriParam
private Integer limit;
@UriParam
private NotFoundBehaviour notFoundBehaviour = NotFoundBehaviour.EXCEPTION;
public SalesforceEndpointConfig copy() {
try {
final SalesforceEndpointConfig copy = (SalesforceEndpointConfig) super.clone();
// nothing to deep copy, getApexQueryParams() is readonly, so no need to deep copy
return copy;
} catch (CloneNotSupportedException ex) {
throw new RuntimeCamelException(ex);
}
}
public PayloadFormat getFormat() {
return format;
}
/**
* Payload format to use for Salesforce API calls, either JSON or XML, defaults to JSON
*/
public void setFormat(PayloadFormat format) {
this.format = format;
}
public String getApiVersion() {
return apiVersion;
}
/**
* Salesforce API version, defaults to SalesforceEndpointConfig.DEFAULT_VERSION
*/
public void setApiVersion(String apiVersion) {
this.apiVersion = apiVersion;
}
public String getSObjectName() {
return sObjectName;
}
/**
* SObject name if required or supported by API
*/
public void setSObjectName(String sObjectName) {
this.sObjectName = sObjectName;
}
public String getSObjectId() {
return sObjectId;
}
/**
* SObject ID if required by API
*/
public void setSObjectId(String sObjectId) {
this.sObjectId = sObjectId;
}
public String getSObjectFields() {
return sObjectFields;
}
/**
* SObject fields to retrieve
*/
public void setSObjectFields(String sObjectFields) {
this.sObjectFields = sObjectFields;
}
public String getSObjectIdName() {
return sObjectIdName;
}
/**
* SObject external ID field name
*/
public void setSObjectIdName(String sObjectIdName) {
this.sObjectIdName = sObjectIdName;
}
public String getSObjectIdValue() {
return sObjectIdValue;
}
/**
* SObject external ID field value
*/
public void setSObjectIdValue(String sObjectIdValue) {
this.sObjectIdValue = sObjectIdValue;
}
public String getSObjectBlobFieldName() {
return sObjectBlobFieldName;
}
/**
* SObject blob field name
*/
public void setSObjectBlobFieldName(String sObjectBlobFieldName) {
this.sObjectBlobFieldName = sObjectBlobFieldName;
}
public String getSObjectClass() {
return sObjectClass;
}
/**
* Fully qualified SObject class name, usually generated using camel-salesforce-maven-plugin
*/
public void setSObjectClass(String sObjectClass) {
this.sObjectClass = sObjectClass;
}
public String getSObjectQuery() {
return sObjectQuery;
}
/**
* Salesforce SOQL query string
*/
public void setSObjectQuery(String sObjectQuery) {
this.sObjectQuery = sObjectQuery;
}
public String getSObjectSearch() {
return sObjectSearch;
}
/**
* Salesforce SOSL search string
*/
public void setSObjectSearch(String sObjectSearch) {
this.sObjectSearch = sObjectSearch;
}
public String getApexMethod() {
return apexMethod;
}
/**
* APEX method name
*/
public void setApexMethod(String apexMethod) {
this.apexMethod = apexMethod;
}
public String getApexUrl() {
return apexUrl;
}
/**
* APEX method URL
*/
public void setApexUrl(String apexUrl) {
this.apexUrl = apexUrl;
}
public Map<String, Object> getApexQueryParams() {
final Map<String, Object> value = Optional.ofNullable(apexQueryParams).orElse(Collections.emptyMap());
return Collections.unmodifiableMap(value);
}
/**
* Query params for APEX method
*/
public void setApexQueryParams(Map<String, Object> apexQueryParams) {
this.apexQueryParams = apexQueryParams;
}
public ApprovalRequest getApproval() {
return approval;
}
/**
* The approval request for Approval API.
*
* @param approval
*/
public void setApproval(final ApprovalRequest approval) {
this.approval = approval;
}
public ContentType getContentType() {
return contentType;
}
/**
* Bulk API content type, one of XML, CSV, ZIP_XML, ZIP_CSV
*/
public void setContentType(ContentType contentType) {
this.contentType = contentType;
}
public String getJobId() {
return jobId;
}
/**
* Bulk API Job ID
*/
public void setJobId(String jobId) {
this.jobId = jobId;
}
public String getBatchId() {
return batchId;
}
/**
* Bulk API Batch ID
*/
public void setBatchId(String batchId) {
this.batchId = batchId;
}
public String getResultId() {
return resultId;
}
/**
* Bulk API Result ID
*/
public void setResultId(String resultId) {
this.resultId = resultId;
}
public boolean isUpdateTopic() {
return updateTopic;
}
/**
* Whether to update an existing Push Topic when using the Streaming API, defaults to false
*/
public void setUpdateTopic(boolean updateTopic) {
this.updateTopic = updateTopic;
}
public NotifyForFieldsEnum getNotifyForFields() {
return notifyForFields;
}
/**
* Notify for fields, options are ALL, REFERENCED, SELECT, WHERE
*/
public void setNotifyForFields(NotifyForFieldsEnum notifyForFields) {
this.notifyForFields = notifyForFields;
}
public NotifyForOperationsEnum getNotifyForOperations() {
return notifyForOperations;
}
/**
* Notify for operations, options are ALL, CREATE, EXTENDED, UPDATE (API version < 29.0)
*/
public void setNotifyForOperations(NotifyForOperationsEnum notifyForOperations) {
this.notifyForOperations = notifyForOperations;
}
public Boolean getNotifyForOperationCreate() {
return notifyForOperationCreate;
}
/**
* Notify for create operation, defaults to false (API version >= 29.0)
*/
public void setNotifyForOperationCreate(Boolean notifyForOperationCreate) {
this.notifyForOperationCreate = notifyForOperationCreate;
}
public Boolean getNotifyForOperationUpdate() {
return notifyForOperationUpdate;
}
/**
* Notify for update operation, defaults to false (API version >= 29.0)
*/
public void setNotifyForOperationUpdate(Boolean notifyForOperationUpdate) {
this.notifyForOperationUpdate = notifyForOperationUpdate;
}
public Boolean getNotifyForOperationDelete() {
return notifyForOperationDelete;
}
/**
* Notify for delete operation, defaults to false (API version >= 29.0)
*/
public void setNotifyForOperationDelete(Boolean notifyForOperationDelete) {
this.notifyForOperationDelete = notifyForOperationDelete;
}
public Boolean getNotifyForOperationUndelete() {
return notifyForOperationUndelete;
}
/**
* Notify for un-delete operation, defaults to false (API version >= 29.0)
*/
public void setNotifyForOperationUndelete(Boolean notifyForOperationUndelete) {
this.notifyForOperationUndelete = notifyForOperationUndelete;
}
public String getReportId() {
return reportId;
}
/**
* Salesforce1 Analytics report Id
*/
public void setReportId(String reportId) {
this.reportId = reportId;
}
public Boolean getIncludeDetails() {
return includeDetails;
}
/**
* Include details in Salesforce1 Analytics report, defaults to false.
*/
public void setIncludeDetails(Boolean includeDetails) {
this.includeDetails = includeDetails;
}
public ReportMetadata getReportMetadata() {
return reportMetadata;
}
/**
* Salesforce1 Analytics report metadata for filtering
*/
public void setReportMetadata(ReportMetadata reportMetadata) {
this.reportMetadata = reportMetadata;
}
public String getInstanceId() {
return instanceId;
}
/**
* Salesforce1 Analytics report execution instance ID
*/
public void setInstanceId(String instanceId) {
this.instanceId = instanceId;
}
/**
* Custom Jetty Http Client to use to connect to Salesforce.
*/
public void setHttpClient(SalesforceHttpClient httpClient) {
this.httpClient = httpClient;
}
public SalesforceHttpClient getHttpClient() {
return httpClient;
}
public ObjectMapper getObjectMapper() {
return objectMapper;
}
public long getBackoffIncrement() {
return backoffIncrement;
}
/**
* Backoff interval increment for Streaming connection restart attempts for failures beyond CometD auto-reconnect.
*/
public void setBackoffIncrement(long backoffIncrement) {
this.backoffIncrement = backoffIncrement;
}
public long getMaxBackoff() {
return maxBackoff;
}
/**
* Maximum backoff interval for Streaming connection restart attempts for failures beyond CometD auto-reconnect.
*/
public void setMaxBackoff(long maxBackoff) {
this.maxBackoff = maxBackoff;
}
/**
* Custom Jackson ObjectMapper to use when serializing/deserializing Salesforce objects.
*/
public void setObjectMapper(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
public Map<String, Object> toValueMap() {
final Map<String, Object> valueMap = new HashMap<String, Object>();
valueMap.put(FORMAT, format.toString().toLowerCase());
valueMap.put(API_VERSION, apiVersion);
valueMap.put(SOBJECT_NAME, sObjectName);
valueMap.put(SOBJECT_ID, sObjectId);
valueMap.put(SOBJECT_FIELDS, sObjectFields);
valueMap.put(SOBJECT_EXT_ID_NAME, sObjectIdName);
valueMap.put(SOBJECT_BLOB_FIELD_NAME, sObjectBlobFieldName);
valueMap.put(SOBJECT_EXT_ID_VALUE, sObjectIdValue);
valueMap.put(SOBJECT_CLASS, sObjectClass);
valueMap.put(SOBJECT_QUERY, sObjectQuery);
valueMap.put(SOBJECT_SEARCH, sObjectSearch);
valueMap.put(APEX_METHOD, apexMethod);
valueMap.put(APEX_URL, apexUrl);
valueMap.put(LIMIT, limit);
valueMap.put(APPROVAL, approval);
// apexQueryParams are handled explicitly in AbstractRestProcessor
// add bulk API properties
if (contentType != null) {
valueMap.put(CONTENT_TYPE, contentType.value());
}
valueMap.put(JOB_ID, jobId);
valueMap.put(BATCH_ID, batchId);
valueMap.put(RESULT_ID, resultId);
// add analytics API properties
valueMap.put(REPORT_ID, reportId);
valueMap.put(INCLUDE_DETAILS, includeDetails);
valueMap.put(REPORT_METADATA, reportMetadata);
valueMap.put(INSTANCE_ID, instanceId);
// add streaming API properties
valueMap.put(DEFAULT_REPLAY_ID, defaultReplayId);
valueMap.put(INITIAL_REPLAY_ID_MAP, initialReplayIdMap);
valueMap.put(NOT_FOUND_BEHAVIOUR, notFoundBehaviour);
return Collections.unmodifiableMap(valueMap);
}
public Long getDefaultReplayId() {
return defaultReplayId;
}
/**
* Default replayId setting if no value is found in {@link #initialReplayIdMap}
*
* @param defaultReplayId
*/
public void setDefaultReplayId(Long defaultReplayId) {
this.defaultReplayId = defaultReplayId;
}
public Map<String, Long> getInitialReplayIdMap() {
return Optional.ofNullable(initialReplayIdMap).orElse(Collections.emptyMap());
}
/**
* Replay IDs to start from per channel name.
*/
public void setInitialReplayIdMap(Map<String, Long> initialReplayIdMap) {
this.initialReplayIdMap = initialReplayIdMap;
}
public Integer getLimit() {
return limit;
}
/**
* Limit on number of returned records. Applicable to some of the API, check the Salesforce documentation.
*
* @param limit
*/
public void setLimit(final Integer limit) {
this.limit = limit;
}
public Action getApprovalActionType() {
if (approval == null) {
return null;
}
return approval.getActionType();
}
public String getApprovalComments() {
if (approval == null) {
return null;
}
return approval.getComments();
}
public String getApprovalContextActorId() {
if (approval == null) {
return null;
}
return approval.getContextActorId();
}
public String getApprovalContextId() {
if (approval == null) {
return null;
}
return approval.getContextId();
}
public List<String> getApprovalNextApproverIds() {
if (approval == null) {
return null;
}
return approval.getNextApproverIds();
}
public String getApprovalProcessDefinitionNameOrId() {
if (approval == null) {
return null;
}
return approval.getProcessDefinitionNameOrId();
}
public boolean isApprovalSkipEntryCriteria() {
if (approval == null) {
return false;
}
return approval.isSkipEntryCriteria();
}
/**
* Represents the kind of action to take: Submit, Approve, or Reject.
*
* @param actionType
*/
public void setApprovalActionType(final Action actionType) {
if (approval == null) {
approval = new ApprovalRequest();
}
approval.setActionType(actionType);
}
/**
* The comment to add to the history step associated with this request.
*
* @param comments
*/
public void setApprovalComments(final String comments) {
if (approval == null) {
approval = new ApprovalRequest();
}
approval.setComments(comments);
}
/**
* The ID of the submitter who’s requesting the approval record.
*
* @param contextActorId
*/
public void setApprovalContextActorId(final String contextActorId) {
if (approval == null) {
approval = new ApprovalRequest();
}
approval.setContextActorId(contextActorId);
}
/**
* The ID of the item that is being acted upon.
*
* @param contextId
*/
public void setApprovalContextId(final String contextId) {
if (approval == null) {
approval = new ApprovalRequest();
}
approval.setContextId(contextId);
}
/**
* If the process requires specification of the next approval, the ID of the user to be assigned the next request.
*
* @param nextApproverIds
*/
public void setApprovalNextApproverIds(final List<String> nextApproverIds) {
if (approval == null) {
approval = new ApprovalRequest();
}
approval.setNextApproverIds(nextApproverIds);
}
/**
* If the process requires specification of the next approval, the ID of the user to be assigned the next request.
*
* @param nextApproverIds
*/
public void setApprovalNextApproverIds(String nextApproverId) {
if (approval == null) {
approval = new ApprovalRequest();
}
approval.setNextApproverIds(nextApproverId);
}
/**
* The developer name or ID of the process definition.
*
* @param processDefinitionNameOrId
*/
public void setApprovalProcessDefinitionNameOrId(final String processDefinitionNameOrId) {
if (approval == null) {
approval = new ApprovalRequest();
}
approval.setProcessDefinitionNameOrId(processDefinitionNameOrId);
}
/**
* Determines whether to evaluate the entry criteria for the process (true) or not (false) if the process definition
* name or ID isn’t null. If the process definition name or ID isn’t specified, this argument is ignored, and
* standard evaluation is followed based on process order. By default, the entry criteria isn’t skipped if it’s not
* set by this request.
*
* @param skipEntryCriteria
*/
public void setApprovalSkipEntryCriteria(final boolean skipEntryCriteria) {
if (approval == null) {
approval = new ApprovalRequest();
}
approval.setSkipEntryCriteria(skipEntryCriteria);
}
public NotFoundBehaviour getNotFoundBehaviour() {
return notFoundBehaviour;
}
/**
* Sets the behaviour of 404 not found status received from Salesforce API.
* Should the body be set to NULL {@link NotFoundBehaviour#NULL} or should a
* exception be signaled on the exchange {@link NotFoundBehaviour#EXCEPTION}
* - the default.
*/
public void setNotFoundBehaviour(final NotFoundBehaviour notFoundBehaviour) {
this.notFoundBehaviour = notFoundBehaviour;
}
}