This is an automated email from the ASF dual-hosted git repository. jeremyross pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push: new 959eacd CAMEL-17818: camel-salesforce: stream query results 959eacd is described below commit 959eacd46af42dd10555a728777f6966cdd53867 Author: Jeremy Ross <jeremy.g.r...@gmail.com> AuthorDate: Thu Mar 24 11:27:26 2022 -0500 CAMEL-17818: camel-salesforce: stream query results --- .../salesforce/SalesforceComponentConfigurer.java | 6 ++ .../salesforce/SalesforceEndpointConfigurer.java | 6 ++ .../salesforce/SalesforceEndpointUriFactory.java | 3 +- .../camel/component/salesforce/salesforce.json | 2 + .../src/main/docs/salesforce-component.adoc | 6 +- .../salesforce/SalesforceEndpointConfig.java | 16 ++++ .../api/dto/AbstractQueryRecordsBase.java | 33 +++----- .../dto/analytics/reports/QueryRecordsReport.java | 14 +--- .../internal/dto/QueryRecordsPushTopic.java | 13 +-- .../internal/processor/AbstractRestProcessor.java | 28 ++++++- .../internal/processor/JsonRestProcessor.java | 52 +++++++++++- .../internal/processor/QueryResultIterator.java | 95 ++++++++++++++++++++++ .../CompositeApiBatchIntegrationTest.java | 12 +-- .../salesforce/CompositeApiIntegrationTest.java | 12 +-- .../salesforce/RecentIntegrationTest.java | 12 +-- .../salesforce/RestApiIntegrationTest.java | 77 ++++++++++++++++-- .../dto/generated/QueryRecordsAccount.java | 13 +-- .../dto/generated/QueryRecordsContact.java | 13 +-- .../dto/generated/QueryRecordsLine_Item__c.java | 13 +-- .../AbstractRestProcessorApprovalTest.java | 7 ++ .../resources/sobject-query-records-optional.vm | 12 +-- .../src/main/resources/sobject-query-records.vm | 12 +-- .../test/resources/generated/QueryRecordsCase.java | 12 +-- .../QueryRecordsComplexCalculatedFormula.java | 12 +-- 24 files changed, 304 insertions(+), 177 deletions(-) diff --git a/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceComponentConfigurer.java b/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceComponentConfigurer.java index 1018e7c..173d977 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceComponentConfigurer.java +++ b/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceComponentConfigurer.java @@ -191,6 +191,8 @@ public class SalesforceComponentConfigurer extends PropertyConfigurerSupport imp case "sObjectSearch": getOrCreateConfig(target).setSObjectSearch(property(camelContext, java.lang.String.class, value)); return true; case "sslcontextparameters": case "sslContextParameters": target.setSslContextParameters(property(camelContext, org.apache.camel.support.jsse.SSLContextParameters.class, value)); return true; + case "streamqueryresult": + case "streamQueryResult": getOrCreateConfig(target).setStreamQueryResult(property(camelContext, java.lang.Boolean.class, value)); return true; case "updatetopic": case "updateTopic": getOrCreateConfig(target).setUpdateTopic(property(camelContext, boolean.class, value)); return true; case "useglobalsslcontextparameters": @@ -371,6 +373,8 @@ public class SalesforceComponentConfigurer extends PropertyConfigurerSupport imp case "sObjectSearch": return java.lang.String.class; case "sslcontextparameters": case "sslContextParameters": return org.apache.camel.support.jsse.SSLContextParameters.class; + case "streamqueryresult": + case "streamQueryResult": return java.lang.Boolean.class; case "updatetopic": case "updateTopic": return boolean.class; case "useglobalsslcontextparameters": @@ -552,6 +556,8 @@ public class SalesforceComponentConfigurer extends PropertyConfigurerSupport imp case "sObjectSearch": return getOrCreateConfig(target).getSObjectSearch(); case "sslcontextparameters": case "sslContextParameters": return target.getSslContextParameters(); + case "streamqueryresult": + case "streamQueryResult": return getOrCreateConfig(target).getStreamQueryResult(); case "updatetopic": case "updateTopic": return getOrCreateConfig(target).isUpdateTopic(); case "useglobalsslcontextparameters": diff --git a/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceEndpointConfigurer.java b/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceEndpointConfigurer.java index 836f542..15675a5 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceEndpointConfigurer.java +++ b/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceEndpointConfigurer.java @@ -130,6 +130,8 @@ public class SalesforceEndpointConfigurer extends PropertyConfigurerSupport impl case "sObjectQuery": target.getConfiguration().setSObjectQuery(property(camelContext, java.lang.String.class, value)); return true; case "sobjectsearch": case "sObjectSearch": target.getConfiguration().setSObjectSearch(property(camelContext, java.lang.String.class, value)); return true; + case "streamqueryresult": + case "streamQueryResult": target.getConfiguration().setStreamQueryResult(property(camelContext, java.lang.Boolean.class, value)); return true; case "updatetopic": case "updateTopic": target.getConfiguration().setUpdateTopic(property(camelContext, boolean.class, value)); return true; default: return false; @@ -248,6 +250,8 @@ public class SalesforceEndpointConfigurer extends PropertyConfigurerSupport impl case "sObjectQuery": return java.lang.String.class; case "sobjectsearch": case "sObjectSearch": return java.lang.String.class; + case "streamqueryresult": + case "streamQueryResult": return java.lang.Boolean.class; case "updatetopic": case "updateTopic": return boolean.class; default: return null; @@ -367,6 +371,8 @@ public class SalesforceEndpointConfigurer extends PropertyConfigurerSupport impl case "sObjectQuery": return target.getConfiguration().getSObjectQuery(); case "sobjectsearch": case "sObjectSearch": return target.getConfiguration().getSObjectSearch(); + case "streamqueryresult": + case "streamQueryResult": return target.getConfiguration().getStreamQueryResult(); case "updatetopic": case "updateTopic": return target.getConfiguration().isUpdateTopic(); default: return null; diff --git a/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceEndpointUriFactory.java b/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceEndpointUriFactory.java index ba7cbff..a67e457 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceEndpointUriFactory.java +++ b/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceEndpointUriFactory.java @@ -21,7 +21,7 @@ public class SalesforceEndpointUriFactory extends org.apache.camel.support.compo private static final Set<String> SECRET_PROPERTY_NAMES; private static final Set<String> MULTI_VALUE_PREFIXES; static { - Set<String> props = new HashSet<>(59); + Set<String> props = new HashSet<>(60); props.add("initialReplayIdMap"); props.add("notifyForOperations"); props.add("sObjectQuery"); @@ -79,6 +79,7 @@ public class SalesforceEndpointUriFactory extends org.apache.camel.support.compo props.add("rawQueryParameters"); props.add("notFoundBehaviour"); props.add("allOrNone"); + props.add("streamQueryResult"); props.add("topicName"); props.add("notifyForOperationDelete"); PROPERTY_NAMES = Collections.unmodifiableSet(props); diff --git a/components/camel-salesforce/camel-salesforce-component/src/generated/resources/org/apache/camel/component/salesforce/salesforce.json b/components/camel-salesforce/camel-salesforce-component/src/generated/resources/org/apache/camel/component/salesforce/salesforce.json index de1185d..60eab17 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/generated/resources/org/apache/camel/component/salesforce/salesforce.json +++ b/components/camel-salesforce/camel-salesforce-component/src/generated/resources/org/apache/camel/component/salesforce/salesforce.json @@ -72,6 +72,7 @@ "sObjectName": { "kind": "property", "displayName": "SObject Name", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.salesforce.SalesforceEndpointConfig", "configurationField": "config", "description": "SObject name if required or supported by API" }, "sObjectQuery": { "kind": "property", "displayName": "SObject Query", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.salesforce.SalesforceEndpointConfig", "configurationField": "config", "description": "Salesforce SOQL query string" }, "sObjectSearch": { "kind": "property", "displayName": "SObject Search", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.salesforce.SalesforceEndpointConfig", "configurationField": "config", "description": "Salesforce SOSL search string" }, + "streamQueryResult": { "kind": "property", "displayName": "Stream query result", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "false", "configurationClass": "org.apache.camel.component.salesforce.SalesforceEndpointConfig", "configurationField": "config", "description": "If true, streams SOQL query result and transparently handles subsequent requests if t [...] "updateTopic": { "kind": "property", "displayName": "Update Topic", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.salesforce.SalesforceEndpointConfig", "configurationField": "config", "description": "Whether to update an existing Push Topic when using the Streaming API, defaults to false" }, "config": { "kind": "property", "displayName": "Config", "group": "common (advanced)", "label": "common,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.salesforce.SalesforceEndpointConfig", "deprecated": false, "autowired": false, "secret": false, "description": "Global endpoint configuration - use to set values that are common to all endpoints" }, "httpClientProperties": { "kind": "property", "displayName": "Http Client Properties", "group": "common (advanced)", "label": "common,advanced", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "Used to set any properties that can be configured on the underlying HTTP client. Have a look at properties of SalesforceHttpClient and the Jetty HttpClient for all ava [...] @@ -161,6 +162,7 @@ "sObjectName": { "kind": "parameter", "displayName": "SObject Name", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.salesforce.SalesforceEndpointConfig", "configurationField": "configuration", "description": "SObject name if required or supported by API" }, "sObjectQuery": { "kind": "parameter", "displayName": "SObject Query", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.salesforce.SalesforceEndpointConfig", "configurationField": "configuration", "description": "Salesforce SOQL query string" }, "sObjectSearch": { "kind": "parameter", "displayName": "SObject Search", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.salesforce.SalesforceEndpointConfig", "configurationField": "configuration", "description": "Salesforce SOSL search string" }, + "streamQueryResult": { "kind": "parameter", "displayName": "Stream query result", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "false", "configurationClass": "org.apache.camel.component.salesforce.SalesforceEndpointConfig", "configurationField": "configuration", "description": "If true, streams SOQL query result and transparently handles subsequent reque [...] "updateTopic": { "kind": "parameter", "displayName": "Update Topic", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.salesforce.SalesforceEndpointConfig", "configurationField": "configuration", "description": "Whether to update an existing Push Topic when using the Streaming API, defaults to false" }, "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a m [...] "replayId": { "kind": "parameter", "displayName": "Replay Id", "group": "consumer", "label": "consumer", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "description": "The replayId value to use when subscribing" }, diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/docs/salesforce-component.adoc b/components/camel-salesforce/camel-salesforce-component/src/main/docs/salesforce-component.adoc index 4a6e940..35d417f 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/main/docs/salesforce-component.adoc +++ b/components/camel-salesforce/camel-salesforce-component/src/main/docs/salesforce-component.adoc @@ -526,12 +526,13 @@ Runs a Salesforce SOQL query | Parameter | Type | Description | Default | Required | Body or `sObjectQuery` | `String` | SOQL query | | x +| streamQueryResult | `Boolean` | If true, returns a streaming `Iterator` and transparently retrieves all pages as needed. The `sObjectClass` option must reference an `AbstractQueryRecordsBase` subclass. | false | | `sObjectClass` | `String` | Fully qualified name of class to deserialize response to. Usually a subclass of `AbstractQueryRecordsBase`, e.g. `org.my.dto.QueryRecordsAccount`| |x |=== *Output* -Type: Instance of class supplied in `sObjectClass` +Type: Instance of class supplied in `sObjectClass`, or `Iterator<SomeSObject>` if `streamQueryResult` is true. [[queryMore]] ==== Query More @@ -562,12 +563,13 @@ Executes the specified SOQL query. Unlike the `query` operation , `queryAll` ret | Parameter | Type | Description | Default | Required | Body or `sObjectQuery` | `String` | SOQL query | | x +| streamQueryResult | `Boolean` | If true, returns a streaming `Iterable` and transparently retrieves all pages as needed. The `sObjectClass` option must reference an `AbstractQueryRecordsBase` subclass. | false | | `sObjectClass` | `String` | Fully qualified name of class to deserialize response to. Usually a subclass of `AbstractQueryRecordsBase`, e.g. `org.my.dto.QueryRecordsAccount`| |x |=== *Output* -Type: Instance of class supplied in `sObjectClass` +Type: Instance of class supplied in `sObjectClass`, or `Iterator<SomeSObject>` if `streamQueryResult` is true. [[sosl_search]] ==== Search diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpointConfig.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpointConfig.java index 70ba1bc..b334dbb 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpointConfig.java +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpointConfig.java @@ -59,6 +59,7 @@ public class SalesforceEndpointConfig implements Cloneable { 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 STREAM_QUERY_RESULT = "streamQueryResult"; public static final String SOBJECT_SEARCH = "sObjectSearch"; public static final String APEX_METHOD = "apexMethod"; public static final String APEX_URL = "apexUrl"; @@ -138,6 +139,8 @@ public class SalesforceEndpointConfig implements Cloneable { private String sObjectClass; @UriParam(displayName = "SObject Query") private String sObjectQuery; + @UriParam(displayName = "Stream query result", defaultValue = "false") + private Boolean streamQueryResult = false; @UriParam(displayName = "SObject Search") private String sObjectSearch; @UriParam @@ -387,6 +390,18 @@ public class SalesforceEndpointConfig implements Cloneable { return sObjectSearch; } + public Boolean getStreamQueryResult() { + return streamQueryResult; + } + + /** + * If true, streams SOQL query result and transparently handles subsequent requests if there are multiple pages. + * Otherwise, results are returned one page at a time. + */ + public void setStreamQueryResult(Boolean streamQueryResult) { + this.streamQueryResult = streamQueryResult; + } + /** * Salesforce SOSL search string */ @@ -771,6 +786,7 @@ public class SalesforceEndpointConfig implements Cloneable { valueMap.put(SOBJECT_EXT_ID_VALUE, sObjectIdValue); valueMap.put(SOBJECT_CLASS, sObjectClass); valueMap.put(SOBJECT_QUERY, sObjectQuery); + valueMap.put(STREAM_QUERY_RESULT, streamQueryResult); valueMap.put(SOBJECT_SEARCH, sObjectSearch); valueMap.put(APEX_METHOD, apexMethod); valueMap.put(APEX_URL, apexUrl); diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractQueryRecordsBase.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractQueryRecordsBase.java index 84848c0..3ff880c 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractQueryRecordsBase.java +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractQueryRecordsBase.java @@ -16,35 +16,17 @@ */ package org.apache.camel.component.salesforce.api.dto; +import java.util.List; + /** * Abstract base DTO for Salesforce SOQL Query records. - * <p> - * Derived classes must follow the template below: - * </p> - * - * <pre> - * { - * @code - * public class QueryResultMySObject extends AbstractQueryRecordsBase { - * private List<MySObject> records; - * - * public List<MySObject> getRecords() { - * return records; - * } - * - * public void setRecords(List<MySObject> records) { - * this.records = records; - * } - * - * } - * } - * </pre> */ -public abstract class AbstractQueryRecordsBase extends AbstractDTOBase { +public class AbstractQueryRecordsBase<T extends AbstractSObjectBase> extends AbstractDTOBase { private Boolean done; private int totalSize; private String nextRecordsUrl; + private List<T> records; public Boolean getDone() { return done; @@ -70,4 +52,11 @@ public abstract class AbstractQueryRecordsBase extends AbstractDTOBase { this.nextRecordsUrl = nextRecordsUrl; } + public List<T> getRecords() { + return records; + } + + public void setRecords(List<T> records) { + this.records = records; + } } diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/analytics/reports/QueryRecordsReport.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/analytics/reports/QueryRecordsReport.java index 4cbf669..d116ac5 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/analytics/reports/QueryRecordsReport.java +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/analytics/reports/QueryRecordsReport.java @@ -16,22 +16,10 @@ */ package org.apache.camel.component.salesforce.api.dto.analytics.reports; -import java.util.List; - import org.apache.camel.component.salesforce.api.dto.AbstractQueryRecordsBase; /** * Salesforce QueryRecords DTO for type Report */ -public class QueryRecordsReport extends AbstractQueryRecordsBase { - - private List<Report> records; - - public List<Report> getRecords() { - return records; - } - - public void setRecords(List<Report> records) { - this.records = records; - } +public class QueryRecordsReport extends AbstractQueryRecordsBase<Report> { } diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/QueryRecordsPushTopic.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/QueryRecordsPushTopic.java index 0d00556..78e08c8 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/QueryRecordsPushTopic.java +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/QueryRecordsPushTopic.java @@ -16,21 +16,10 @@ */ package org.apache.camel.component.salesforce.internal.dto; -import java.util.List; - import org.apache.camel.component.salesforce.api.dto.AbstractQueryRecordsBase; /** * Salesforce Query Records DTO for PushTopic */ -public class QueryRecordsPushTopic extends AbstractQueryRecordsBase { - private List<PushTopic> records; - - public List<PushTopic> getRecords() { - return records; - } - - public void setRecords(List<PushTopic> records) { - this.records = records; - } +public class QueryRecordsPushTopic extends AbstractQueryRecordsBase<PushTopic> { } diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractRestProcessor.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractRestProcessor.java index 0f0fdb2..c9a4a0e 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractRestProcessor.java +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractRestProcessor.java @@ -58,13 +58,16 @@ import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.SOB import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.SOBJECT_NAME; import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.SOBJECT_QUERY; import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.SOBJECT_SEARCH; +import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.STREAM_QUERY_RESULT; public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor { protected static final String RESPONSE_CLASS = AbstractRestProcessor.class.getName() + ".responseClass"; + protected static final String RESPONSE_TYPE = JsonRestProcessor.class.getName() + ".responseType"; + private static final Pattern URL_TEMPLATE = Pattern.compile("\\{([^\\{\\}]+)\\}"); - private RestClient restClient; + protected RestClient restClient; private NotFoundBehaviour notFoundBehaviour; // used in unit tests @@ -488,11 +491,16 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor private void processQuery(final Exchange exchange, final AsyncCallback callback) throws SalesforceException { final String sObjectQuery = getParameter(SOBJECT_QUERY, exchange, USE_BODY, NOT_OPTIONAL); + final boolean streamQueryResults = getParameter(STREAM_QUERY_RESULT, exchange, IGNORE_BODY, IS_OPTIONAL, Boolean.class); // use custom response class property setResponseClass(exchange, null); - restClient.query(sObjectQuery, determineHeaders(exchange), processWithResponseCallback(exchange, callback)); + if (streamQueryResults) { + restClient.query(sObjectQuery, determineHeaders(exchange), processWithStreamResultCallback(exchange, callback)); + } else { + restClient.query(sObjectQuery, determineHeaders(exchange), processWithResponseCallback(exchange, callback)); + } } private void processQueryMore(final Exchange exchange, final AsyncCallback callback) throws SalesforceException { @@ -507,11 +515,16 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor private void processQueryAll(final Exchange exchange, final AsyncCallback callback) throws SalesforceException { final String sObjectQuery = getParameter(SOBJECT_QUERY, exchange, USE_BODY, NOT_OPTIONAL); + final boolean streamQueryResults = getParameter(STREAM_QUERY_RESULT, exchange, IGNORE_BODY, IS_OPTIONAL, Boolean.class); // use custom response class property setResponseClass(exchange, null); - restClient.queryAll(sObjectQuery, determineHeaders(exchange), processWithResponseCallback(exchange, callback)); + if (streamQueryResults) { + restClient.queryAll(sObjectQuery, determineHeaders(exchange), processWithStreamResultCallback(exchange, callback)); + } else { + restClient.queryAll(sObjectQuery, determineHeaders(exchange), processWithResponseCallback(exchange, callback)); + } } private void processSearch(final Exchange exchange, final AsyncCallback callback) throws SalesforceException { @@ -730,13 +743,20 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor return (response, headers, exception) -> processResponse(exchange, response, headers, exception, callback); } + final ResponseCallback processWithStreamResultCallback(final Exchange exchange, final AsyncCallback callback) { + return (response, headers, exception) -> processStreamResultResponse(exchange, response, headers, exception, callback); + } + // process response entity and set out message in exchange protected abstract void processResponse( Exchange exchange, InputStream responseEntity, Map<String, String> headers, SalesforceException ex, AsyncCallback callback); + protected abstract void processStreamResultResponse( + Exchange exchange, InputStream responseEntity, Map<String, String> headers, SalesforceException ex, + AsyncCallback callback); + final boolean shouldReport(SalesforceException ex) { return !(ex instanceof NoSuchSObjectException && notFoundBehaviour == NotFoundBehaviour.NULL); } - } diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/JsonRestProcessor.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/JsonRestProcessor.java index b13f41a..0a3b024 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/JsonRestProcessor.java +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/JsonRestProcessor.java @@ -32,6 +32,7 @@ import org.apache.camel.component.salesforce.SalesforceEndpoint; import org.apache.camel.component.salesforce.api.SalesforceException; import org.apache.camel.component.salesforce.api.TypeReferences; import org.apache.camel.component.salesforce.api.dto.AbstractDTOBase; +import org.apache.camel.component.salesforce.api.dto.AbstractQueryRecordsBase; import org.apache.camel.component.salesforce.api.dto.CreateSObjectResult; import org.apache.camel.component.salesforce.api.dto.GlobalObjects; import org.apache.camel.component.salesforce.api.dto.Limits; @@ -45,8 +46,6 @@ import org.apache.camel.component.salesforce.api.utils.JsonUtils; public class JsonRestProcessor extends AbstractRestProcessor { - private static final String RESPONSE_TYPE = JsonRestProcessor.class.getName() + ".responseType"; - // it is ok to use a single thread safe ObjectMapper private final ObjectMapper objectMapper; @@ -185,7 +184,7 @@ public class JsonRestProcessor extends AbstractRestProcessor { out.getHeaders().putAll(headers); if (ex != null) { - // if an exception is reported we should not loose it + // if an exception is reported we should not lose it if (shouldReport(ex)) { exchange.setException(ex); } else { @@ -229,4 +228,51 @@ public class JsonRestProcessor extends AbstractRestProcessor { } } + + @Override + protected void processStreamResultResponse( + Exchange exchange, InputStream responseEntity, Map<String, String> headers, SalesforceException ex, + AsyncCallback callback) { + // process JSON response for TypeReference + try { + final Message out = exchange.getOut(); + final Message in = exchange.getIn(); + out.copyFrom(in); + out.getHeaders().putAll(headers); + + if (ex != null) { + // if an exception is reported we should not lose it + if (shouldReport(ex)) { + exchange.setException(ex); + } else { + out.setBody(null); + } + } else if (responseEntity != null) { + // do we need to un-marshal a response + final AbstractQueryRecordsBase<?> response; + Class<?> responseClass = exchange.getProperty(RESPONSE_CLASS, Class.class); + response = (AbstractQueryRecordsBase<?>) objectMapper.readValue(responseEntity, responseClass); + QueryResultIterator iterator + = new QueryResultIterator( + objectMapper, responseClass, restClient, determineHeaders(exchange), response); + out.setBody(iterator); + } + } catch (IOException e) { + String msg = "Error parsing JSON response: " + e.getMessage(); + exchange.setException(new SalesforceException(msg, e)); + } finally { + exchange.removeProperty(RESPONSE_CLASS); + exchange.removeProperty(RESPONSE_TYPE); + + try { + if (responseEntity != null) { + responseEntity.close(); + } + } catch (IOException ignored) { + } + + // notify callback that exchange is done + callback.done(false); + } + } } diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/QueryResultIterator.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/QueryResultIterator.java new file mode 100644 index 0000000..574bc62 --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/QueryResultIterator.java @@ -0,0 +1,95 @@ +/* + * 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.internal.processor; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.concurrent.CountDownLatch; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.component.salesforce.api.dto.AbstractQueryRecordsBase; +import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase; +import org.apache.camel.component.salesforce.internal.client.RestClient; + +public class QueryResultIterator<T extends AbstractSObjectBase> implements Iterator<T> { + + private final RestClient restClient; + private final Map<String, List<String>> requestHeaders; + private final ObjectMapper objectMapper; + private final Class<? extends AbstractQueryRecordsBase<T>> responseClass; + private AbstractQueryRecordsBase<T> queryRecords; + private Iterator<T> iterator; + + public QueryResultIterator( + ObjectMapper objectMapper, Class<? extends AbstractQueryRecordsBase<T>> responseClass, + RestClient restClient, Map<String, List<String>> headers, + AbstractQueryRecordsBase<T> queryRecords) { + this.objectMapper = objectMapper; + this.responseClass = responseClass; + this.restClient = restClient; + this.requestHeaders = headers; + this.queryRecords = queryRecords; + this.iterator = queryRecords.getRecords().iterator(); + } + + @Override + public boolean hasNext() { + return iterator.hasNext() || !queryRecords.getDone(); + } + + @Override + public T next() { + if (iterator.hasNext()) { + return iterator.next(); + } else if (!queryRecords.getDone()) { + final CountDownLatch latch = new CountDownLatch(1); + List<T> valueHolder = new ArrayList<T>(); + + restClient.queryMore(queryRecords.getNextRecordsUrl(), requestHeaders, (response, headers, exception) -> { + final AbstractQueryRecordsBase<T> qrb; + try { + queryRecords = objectMapper.readValue(response, responseClass); + iterator = queryRecords.getRecords().iterator(); + valueHolder.add(iterator.next()); + latch.countDown(); + } catch (IOException e) { + throw new RuntimeCamelException(e); + } finally { + if (response != null) { + try { + response.close(); + } catch (IOException ignored) { + } + } + } + }); + try { + latch.await(); + return valueHolder.get(0); + } catch (InterruptedException e) { + throw new RuntimeCamelException(e); + } + } else { + throw new NoSuchElementException(); + } + } +} diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/CompositeApiBatchIntegrationTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/CompositeApiBatchIntegrationTest.java index 33988a0..e009a2f 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/CompositeApiBatchIntegrationTest.java +++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/CompositeApiBatchIntegrationTest.java @@ -49,17 +49,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; @Parameterized public class CompositeApiBatchIntegrationTest extends AbstractSalesforceTestBase { - public static class Accounts extends AbstractQueryRecordsBase { - private List<Account> records; - - public List<Account> getRecords() { - return records; - } - - public void setRecords(final List<Account> records) { - this.records = records; - } - + public static class Accounts extends AbstractQueryRecordsBase<Account> { } private static final Set<String> VERSIONS diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/CompositeApiIntegrationTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/CompositeApiIntegrationTest.java index 58536bf..1bab76c 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/CompositeApiIntegrationTest.java +++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/CompositeApiIntegrationTest.java @@ -46,17 +46,7 @@ import org.junit.jupiter.api.BeforeEach; @Parameterized public class CompositeApiIntegrationTest extends AbstractSalesforceTestBase { - public static class Accounts extends AbstractQueryRecordsBase { - private List<Account> records; - - public List<Account> getRecords() { - return records; - } - - public void setRecords(final List<Account> records) { - this.records = records; - } - + public static class Accounts extends AbstractQueryRecordsBase<Account> { } private static final Set<String> VERSIONS = new HashSet<>(Arrays.asList("38.0", "50.0")); diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RecentIntegrationTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RecentIntegrationTest.java index 2617991..ccd41c2 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RecentIntegrationTest.java +++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RecentIntegrationTest.java @@ -34,17 +34,7 @@ import static org.apache.camel.test.junit5.TestSupport.assertListSize; @Tag("standalone") public class RecentIntegrationTest extends AbstractSalesforceTestBase { - public static class Accounts extends AbstractQueryRecordsBase { - private List<Account> records; - - public List<Account> getRecords() { - return records; - } - - public void setRecords(final List<Account> records) { - this.records = records; - } - + public static class Accounts extends AbstractQueryRecordsBase<Account> { } private static final Object NOT_USED = null; diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RestApiIntegrationTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RestApiIntegrationTest.java index 2814779..51bbb66 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RestApiIntegrationTest.java +++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RestApiIntegrationTest.java @@ -20,7 +20,9 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.time.ZoneId; import java.time.ZonedDateTime; +import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.UUID; @@ -30,6 +32,7 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.camel.CamelExecutionException; import org.apache.camel.Exchange; import org.apache.camel.Processor; +import org.apache.camel.builder.AggregationStrategies; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.salesforce.api.NoSuchSObjectException; import org.apache.camel.component.salesforce.api.SalesforceException; @@ -128,9 +131,7 @@ public class RestApiIntegrationTest extends AbstractSalesforceTestBase { template.request("salesforce:deleteSObject?sObjectName=Merchandise__c&sObjectId=" + merchandiseId, (Processor) e -> { // NOOP }); - template.request("direct:deleteLineItems", (Processor) e -> { - // NOOP - }); + template.requestBody("direct:deleteLineItems", ""); } @BeforeEach @@ -153,6 +154,17 @@ public class RestApiIntegrationTest extends AbstractSalesforceTestBase { CreateSObjectResult result = template().requestBody("direct:createLineItem", lineItem, CreateSObjectResult.class); } + private void createLineItems(int count) { + List<Line_Item__c> lineItems = new ArrayList<>(); + for (int i = 0; i < count; i++) { + Line_Item__c lineItem = new Line_Item__c(); + final String lineItemId = String.valueOf(TEST_LINE_ITEM_ID.incrementAndGet()); + lineItem.setName(lineItemId); + lineItems.add(lineItem); + } + template().requestBody("direct:createLineItems", lineItems); + } + private void createAccountAndContact() { final Account account = new Account(); account.setName("Child Test"); @@ -500,6 +512,20 @@ public class RestApiIntegrationTest extends AbstractSalesforceTestBase { } @Test + public void testQueryStreamResults() throws Exception { + final int createCount = 300; + createLineItems(createCount); + final Iterator<Line_Item__c> queryRecords + = template().requestBody("direct:queryStreamResult", "", Iterator.class); + int count = 0; + while (queryRecords.hasNext()) { + count = count + 1; + queryRecords.next(); + } + assertTrue(count >= createCount); + } + + @Test public void querySyncAsyncDoesntTimeout() throws Exception { final Object result = template.requestBody("direct:querySyncAsync", ""); assertNotNull(result); @@ -541,6 +567,20 @@ public class RestApiIntegrationTest extends AbstractSalesforceTestBase { } @Test + public void testQueryAllStreamResults() throws Exception { + final int createCount = 300; + createLineItems(createCount); + final Iterator<Line_Item__c> queryRecords + = template().requestBody("direct:queryAllStreamResult", "", Iterator.class); + int count = 0; + while (queryRecords.hasNext()) { + count = count + 1; + queryRecords.next(); + } + assertTrue(count >= createCount); + } + + @Test public void testRetry() throws Exception { final SalesforceComponent sf = context().getComponent("salesforce", SalesforceComponent.class); final String accessToken = sf.getSession().getAccessToken(); @@ -737,15 +777,24 @@ public class RestApiIntegrationTest extends AbstractSalesforceTestBase { from("direct:getSObject") .to("salesforce:getSObject?sObjectName=Merchandise__c&sObjectFields=Description__c,Price__c"); - // testUpsertSObject from("direct:deleteLineItems") .to("salesforce:query?sObjectQuery=SELECT Id FROM Line_Item__C&sObjectClass=" + QueryRecordsLine_Item__c.class.getName()) - .transform(simple("${body.records}")).split(body()).transform(simple("${body.id}")) - .to("salesforce:deleteSObject?sObjectName=Line_Item__c"); + .filter(simple("${body.records.size} > 0")) + .split(simple("${body.records}"), + AggregationStrategies.flexible().accumulateInCollection(ArrayList.class)) + .transform(simple("${body.id}")) + .end() + .split(simple("${collate(200)}")) + .to("salesforce:compositeDeleteSObjectCollections") + .end(); from("direct:createLineItem").to("salesforce:createSObject?sObjectName=Line_Item__c"); + from("direct:createLineItems") + .split(simple("${collate(200)}")) + .to("salesforce:compositeCreateSObjectCollections"); + from("direct:upsertSObject") .to("salesforce:upsertSObject?sObjectName=Line_Item__c&sObjectIdName=Name"); @@ -760,7 +809,21 @@ public class RestApiIntegrationTest extends AbstractSalesforceTestBase { // testQuery from("direct:query") .to("salesforce:query?sObjectQuery=SELECT Id, name, Typeof Owner WHEN User Then Username End, recordTypeId, RecordType.Name from Line_Item__c&sObjectClass=" - + QueryRecordsLine_Item__c.class.getName() + ""); + + QueryRecordsLine_Item__c.class.getName()); + + // testQuery + from("direct:queryStreamResult") + .setHeader("sObjectClass", constant(QueryRecordsLine_Item__c.class.getName())) + .setHeader("Sforce-Query-Options", constant("batchSize=200")) + .to("salesforce:query?sObjectQuery=SELECT Id, name, Typeof Owner WHEN User Then Username End, recordTypeId, RecordType.Name from Line_Item__c Order By Name" + + "&streamQueryResult=true"); + + // testQuery + from("direct:queryAllStreamResult") + .setHeader("sObjectClass", constant(QueryRecordsLine_Item__c.class.getName())) + .setHeader("Sforce-Query-Options", constant("batchSize=200")) + .to("salesforce:queryAll?sObjectQuery=SELECT Id, name, Typeof Owner WHEN User Then Username End, recordTypeId, RecordType.Name from Line_Item__c Order By Name" + + "&streamQueryResult=true"); // testParentRelationshipQuery from("direct:parentRelationshipQuery") diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/QueryRecordsAccount.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/QueryRecordsAccount.java index 51e1b97..43e93ef 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/QueryRecordsAccount.java +++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/QueryRecordsAccount.java @@ -16,18 +16,7 @@ */ package org.apache.camel.component.salesforce.dto.generated; -import java.util.List; - import org.apache.camel.component.salesforce.api.dto.AbstractQueryRecordsBase; -public class QueryRecordsAccount extends AbstractQueryRecordsBase { - private List<Account> records; - - public List<Account> getRecords() { - return records; - } - - public void setRecords(List<Account> records) { - this.records = records; - } +public class QueryRecordsAccount extends AbstractQueryRecordsBase<Account> { } diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/QueryRecordsContact.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/QueryRecordsContact.java index 6700921..52be4ed 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/QueryRecordsContact.java +++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/QueryRecordsContact.java @@ -16,18 +16,7 @@ */ package org.apache.camel.component.salesforce.dto.generated; -import java.util.List; - import org.apache.camel.component.salesforce.api.dto.AbstractQueryRecordsBase; -public class QueryRecordsContact extends AbstractQueryRecordsBase { - private List<Contact> records; - - public List<Contact> getRecords() { - return records; - } - - public void setRecords(List<Contact> records) { - this.records = records; - } +public class QueryRecordsContact extends AbstractQueryRecordsBase<Contact> { } diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/QueryRecordsLine_Item__c.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/QueryRecordsLine_Item__c.java index f5a7f6a..4a5eee9 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/QueryRecordsLine_Item__c.java +++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/QueryRecordsLine_Item__c.java @@ -16,20 +16,9 @@ */ package org.apache.camel.component.salesforce.dto.generated; -import java.util.List; - import org.apache.camel.component.salesforce.api.dto.AbstractQueryRecordsBase; //CHECKSTYLE:OFF -public class QueryRecordsLine_Item__c extends AbstractQueryRecordsBase { - private List<Line_Item__c> records; - - public List<Line_Item__c> getRecords() { - return records; - } - - public void setRecords(List<Line_Item__c> records) { - this.records = records; - } +public class QueryRecordsLine_Item__c extends AbstractQueryRecordsBase<Line_Item__c> { } //CHECKSTYLE:ON diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/internal/processor/AbstractRestProcessorApprovalTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/internal/processor/AbstractRestProcessorApprovalTest.java index 22df4c0..ba62ef0 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/internal/processor/AbstractRestProcessorApprovalTest.java +++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/internal/processor/AbstractRestProcessorApprovalTest.java @@ -94,6 +94,13 @@ public class AbstractRestProcessorApprovalTest { final SalesforceException ex, final AsyncCallback callback) { } + + @Override + protected void processStreamResultResponse( + Exchange exchange, InputStream responseEntity, Map<String, String> headers, SalesforceException ex, + AsyncCallback callback) { + + } } private static <T> T notUsed() { diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-query-records-optional.vm b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-query-records-optional.vm index aa468b9..53bb8e2 100644 --- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-query-records-optional.vm +++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-query-records-optional.vm @@ -30,15 +30,5 @@ import javax.annotation.Generated; */ #set( $descName = "${desc.Name}Optional" ) @Generated("org.apache.camel.maven.CamelSalesforceMojo") -public class QueryRecords$descName extends AbstractQueryRecordsBase { - - private List<$descName> records; - - public List<$descName> getRecords() { - return records; - } - - public void setRecords(List<$descName> records) { - this.records = records; - } +public class QueryRecords$descName extends AbstractQueryRecordsBase<$descName> { } diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-query-records.vm b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-query-records.vm index 747e73e..e7e87ad 100644 --- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-query-records.vm +++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-query-records.vm @@ -30,15 +30,5 @@ import javax.annotation.Generated; */ #set( $descName = $desc.Name ) @Generated("org.apache.camel.maven.CamelSalesforceMojo") -public class QueryRecords$descName extends AbstractQueryRecordsBase { - - private List<$descName> records; - - public List<$descName> getRecords() { - return records; - } - - public void setRecords(List<$descName> records) { - this.records = records; - } +public class QueryRecords$descName extends AbstractQueryRecordsBase<$descName> { } diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/QueryRecordsCase.java b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/QueryRecordsCase.java index fa71781..8daa5ab 100644 --- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/QueryRecordsCase.java +++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/QueryRecordsCase.java @@ -12,15 +12,5 @@ import javax.annotation.Generated; * Salesforce QueryRecords DTO for type Case */ @Generated("org.apache.camel.maven.CamelSalesforceMojo") -public class QueryRecordsCase extends AbstractQueryRecordsBase { - - private List<Case> records; - - public List<Case> getRecords() { - return records; - } - - public void setRecords(List<Case> records) { - this.records = records; - } +public class QueryRecordsCase extends AbstractQueryRecordsBase<Case> { } diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/QueryRecordsComplexCalculatedFormula.java b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/QueryRecordsComplexCalculatedFormula.java index b80536f..b6d4d7c 100644 --- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/QueryRecordsComplexCalculatedFormula.java +++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/generated/QueryRecordsComplexCalculatedFormula.java @@ -12,15 +12,5 @@ import javax.annotation.Generated; * Salesforce QueryRecords DTO for type ComplexCalculatedFormula */ @Generated("org.apache.camel.maven.CamelSalesforceMojo") -public class QueryRecordsComplexCalculatedFormula extends AbstractQueryRecordsBase { - - private List<ComplexCalculatedFormula> records; - - public List<ComplexCalculatedFormula> getRecords() { - return records; - } - - public void setRecords(List<ComplexCalculatedFormula> records) { - this.records = records; - } +public class QueryRecordsComplexCalculatedFormula extends AbstractQueryRecordsBase<ComplexCalculatedFormula> { }