Added Salesforce component
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/72a1767e Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/72a1767e Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/72a1767e Branch: refs/heads/trunk Commit: 72a1767eb44fbb03fc29691e80509f21e6e65233 Parents: b0ccd94 Author: Dhiraj Bokde <dbo...@fusesource.com> Authored: Wed Jun 5 00:51:21 2013 -0700 Committer: Dhiraj Bokde <dbo...@fusesource.com> Committed: Wed Jun 5 02:04:16 2013 -0700 ---------------------------------------------------------------------- .gitignore | 1 + .../camel-salesforce-component/.gitignore | 6 + .../camel-salesforce-component/README.md | 68 ++ .../camel-salesforce-component/pom.xml | 121 ++++ .../salesforce/SalesforceComponent.java | 233 +++++++ .../salesforce/SalesforceConsumer.java | 215 ++++++ .../salesforce/SalesforceEndpoint.java | 96 +++ .../salesforce/SalesforceEndpointConfig.java | 276 ++++++++ .../salesforce/SalesforceLoginConfig.java | 99 +++ .../salesforce/SalesforceProducer.java | 102 +++ .../salesforce/api/JodaTimeConverter.java | 64 ++ .../salesforce/api/PicklistEnumConverter.java | 80 +++ .../salesforce/api/SalesforceException.java | 104 +++ .../salesforce/api/dto/AbstractDTOBase.java | 40 ++ .../api/dto/AbstractQueryRecordsBase.java | 72 ++ .../salesforce/api/dto/AbstractSObjectBase.java | 172 +++++ .../salesforce/api/dto/Attributes.java | 38 ++ .../salesforce/api/dto/ChildRelationShip.java | 74 ++ .../salesforce/api/dto/CreateSObjectResult.java | 57 ++ .../salesforce/api/dto/GlobalObjects.java | 57 ++ .../salesforce/api/dto/PickListValue.java | 70 ++ .../salesforce/api/dto/RecentItem.java | 56 ++ .../salesforce/api/dto/RecordTypeInfo.java | 56 ++ .../component/salesforce/api/dto/RestError.java | 68 ++ .../salesforce/api/dto/RestResources.java | 100 +++ .../component/salesforce/api/dto/SObject.java | 237 +++++++ .../salesforce/api/dto/SObjectBasicInfo.java | 46 ++ .../salesforce/api/dto/SObjectDescription.java | 67 ++ .../api/dto/SObjectDescriptionUrls.java | 47 ++ .../salesforce/api/dto/SObjectField.java | 414 ++++++++++++ .../salesforce/api/dto/SObjectUrls.java | 56 ++ .../salesforce/api/dto/SearchResult.java | 49 ++ .../salesforce/api/dto/SearchResults.java | 41 ++ .../component/salesforce/api/dto/Version.java | 52 ++ .../component/salesforce/api/dto/Versions.java | 40 ++ .../salesforce/api/dto/bulk/BatchInfo.java | 342 ++++++++++ .../salesforce/api/dto/bulk/BatchInfoList.java | 82 +++ .../salesforce/api/dto/bulk/BatchResult.java | 82 +++ .../salesforce/api/dto/bulk/BatchStateEnum.java | 75 +++ .../api/dto/bulk/ConcurrencyModeEnum.java | 66 ++ .../salesforce/api/dto/bulk/ContentType.java | 57 ++ .../salesforce/api/dto/bulk/Error.java | 105 +++ .../salesforce/api/dto/bulk/JobInfo.java | 673 +++++++++++++++++++ .../salesforce/api/dto/bulk/JobStateEnum.java | 72 ++ .../salesforce/api/dto/bulk/ObjectFactory.java | 200 ++++++ .../salesforce/api/dto/bulk/OperationEnum.java | 78 +++ .../salesforce/api/dto/bulk/QueryResult.java | 84 +++ .../api/dto/bulk/QueryResultList.java | 82 +++ .../salesforce/api/dto/bulk/Result.java | 147 ++++ .../salesforce/api/dto/bulk/ResultError.java | 140 ++++ .../salesforce/api/dto/bulk/SObject.java | 138 ++++ .../salesforce/api/dto/bulk/StatusCode.java | 395 +++++++++++ .../salesforce/api/dto/bulk/package-info.java | 18 + .../salesforce/internal/OperationName.java | 71 ++ .../salesforce/internal/PayloadFormat.java | 22 + .../salesforce/internal/SalesforceSession.java | 336 +++++++++ .../internal/client/AbstractClientBase.java | 196 ++++++ .../internal/client/BulkApiClient.java | 92 +++ .../internal/client/DefaultBulkApiClient.java | 481 +++++++++++++ .../internal/client/DefaultRestClient.java | 364 ++++++++++ .../salesforce/internal/client/RestClient.java | 177 +++++ .../internal/client/SalesforceExchange.java | 36 + .../client/SalesforceSecurityListener.java | 162 +++++ .../internal/client/SyncResponseCallback.java | 57 ++ .../salesforce/internal/dto/LoginError.java | 47 ++ .../salesforce/internal/dto/LoginToken.java | 81 +++ .../internal/dto/NotifyForFieldsEnum.java | 53 ++ .../internal/dto/NotifyForOperationsEnum.java | 52 ++ .../salesforce/internal/dto/PushTopic.java | 100 +++ .../internal/dto/QueryRecordsPushTopic.java | 38 ++ .../salesforce/internal/dto/RestErrors.java | 41 ++ .../processor/AbstractRestProcessor.java | 538 +++++++++++++++ .../processor/AbstractSalesforceProcessor.java | 84 +++ .../internal/processor/BulkApiProcessor.java | 377 +++++++++++ .../internal/processor/JsonRestProcessor.java | 180 +++++ .../internal/processor/SalesforceProcessor.java | 27 + .../internal/processor/XmlRestProcessor.java | 240 +++++++ .../internal/streaming/PushTopicHelper.java | 206 ++++++ .../internal/streaming/SubscriptionHelper.java | 372 ++++++++++ .../org/apache/camel/component/salesforce | 1 + .../salesforce/AbstractBulkApiTestBase.java | 105 +++ .../salesforce/AbstractSalesforceTestBase.java | 60 ++ .../salesforce/BulkApiBatchIntegrationTest.java | 109 +++ .../salesforce/BulkApiJobIntegrationTest.java | 111 +++ .../salesforce/BulkApiQueryIntegrationTest.java | 85 +++ .../component/salesforce/LoginConfigHelper.java | 43 ++ .../salesforce/RestApiIntegrationTest.java | 408 +++++++++++ .../salesforce/StreamingApiIntegrationTest.java | 109 +++ .../component/salesforce/dto/Document.java | 201 ++++++ .../component/salesforce/dto/Line_Item__c.java | 74 ++ .../salesforce/dto/Merchandise__c.java | 61 ++ .../dto/QueryRecordsLine_Item__c.java | 35 + .../internal/SessionIntegrationTest.java | 63 ++ .../src/test/resources/log4j.properties | 18 + .../src/test/resources/test-request.csv | 3 + .../src/test/resources/test-request.xml | 15 + .../camel-salesforce-maven-plugin/.gitignore | 5 + .../camel-salesforce-maven-plugin/README.md | 26 + .../camel-salesforce-maven-plugin/pom.xml | 78 +++ .../apache/camel/maven/CamelSalesforceMojo.java | 569 ++++++++++++++++ .../src/main/resources/sobject-picklist.vm | 52 ++ .../src/main/resources/sobject-pojo.vm | 60 ++ .../src/main/resources/sobject-query-records.vm | 29 + .../CamelSalesforceMojoIntegrationTest.java | 85 +++ .../src/test/resources/log4j.properties | 19 + components/camel-salesforce/pom.xml | 38 ++ components/pom.xml | 1 + parent/pom.xml | 6 + .../features/src/main/resources/features.xml | 16 + 109 files changed, 13125 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/.gitignore ---------------------------------------------------------------------- diff --git a/.gitignore b/.gitignore index 394c174..b74e107 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ target .settings .checkstyle *.log +test-salesforce-login.properties dependency-reduced-pom.xml http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/.gitignore ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/.gitignore b/components/camel-salesforce/camel-salesforce-component/.gitignore new file mode 100644 index 0000000..acf55cc --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/.gitignore @@ -0,0 +1,6 @@ +target +*.ipr +*.iml +*.iws +# Salesforce login properties +*test-login.properties* http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/README.md ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/README.md b/components/camel-salesforce/camel-salesforce-component/README.md new file mode 100644 index 0000000..9bf9845 --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/README.md @@ -0,0 +1,68 @@ +# Camel Salesforce component # + +This component supports producer and consumer endpoints to communicate with Salesforce using Java DTOs. +There is a companion maven plugin [camel-salesforce-plugin](https://github.com/dhirajsb/camel-salesforce-maven-plugin) that generates these DTOs. + +The component supports the following Salesforce APIs + +## REST API ## + +Producer endpoints can use the following APIs. Most of the APIs process one record at a time, the Query API can retrieve multiple Records. + +* getVersions - Gets supported Salesforce REST API versions +* getResources - Gets available Salesforce REST Resource endpoints +* getGlobalObjects - Gets metadata for all available SObject types +* getBasicInfo - Gets basic metadata for a specific SObject type +* getDescription - Gets comprehensive metadata for a specific SObject type +* getSObject - Gets an SObject using its Salesforce Id +* createSObject - Creates an SObject +* updateSObject - Updates an SObject using Id +* deleteSObject - Deletes an SObject using Id +* getSObjectWithId - Gets an SObject using an external (user defined) id field +* upsertSObject - Updates or inserts an SObject using an external id +* deleteSObjectWithId - Deletes an SObject using an external id +* query - Runs a Salesforce SOQL query +* queryMore - Retrieves more results (in case of large number of results) using result link returned from the 'query' API +* search - Runs a Salesforce SOSL query + +For example, the following producer endpoint uses the upsertSObject API, with the sObjectIdName parameter specifying 'Name' as the external id field. +The request message body should be an SObject DTO generated using the maven plugin. +The response message will either be NULL if an existing record was updated, or [CreateSObjectResult] with an id of the new record, or a list of errors while creating the new object. + + ...to("force:upsertSObject?sObjectIdName=Name")... + +## Bulk API ## + +Producer endpoints can use the following APIs. All Job data formats, i.e. xml, csv, zip/xml, and zip/csv are supported. +The request and response have to be marshalled/unmarshalled by the route. Usually the request will be some stream source like a CSV file, +and the response may also be saved to a file to be correlated with the request. + +* createJob - Creates a Salesforce Bulk Job +* getJob - Gets a Job using its Salesforce Id +* closeJob - Closes a Job +* abortJob - Aborts a Job +* createBatch - Submits a Batch within a Bulk Job +* getBatch - Gets a Batch using Id +* getAllBatches - Gets all Batches for a Bulk Job Id +* getRequest - Gets Request data (XML/CSV) for a Batch +* getResults - Gets the results of the Batch when its complete +* createBatchQuery - Creates a Batch from an SOQL query +* getQueryResultIds - Gets a list of Result Ids for a Batch Query +* getQueryResult - Gets results for a Result Id + +For example, the following producer endpoint uses the createBatch API to create a Job Batch. +The in message must contain a body that can be converted into an InputStream (usually UTF-8 CSV or XML content from a file, etc.) and header fields 'jobId' for the Job and 'contentType' for the Job content type, which can be XML, CSV, ZIP\_XML or ZIP\_CSV. The put message body will contain [BatchInfo] on success, or throw a [SalesforceException] on error. + + ...to("force:createBatchJob").. + +## Streaming API ## + +Consumer endpoints can use the following sytax for streaming endpoints to receive Salesforce notifications on create/update. + +To create and subscribe to a topic + + from("force:CamelTestTopic?notifyForFields=ALL¬ifyForOperations=ALL&sObjectName=Merchandise__c&updateTopic=true&sObjectQuery=SELECT Id, Name FROM Merchandise__c")... + +To subscribe to an existing topic + + from("force:CamelTestTopic&sObjectName=Merchandise__c")... http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/pom.xml ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/pom.xml b/components/camel-salesforce/camel-salesforce-component/pom.xml new file mode 100644 index 0000000..3a811f5 --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/pom.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.camel</groupId> + <artifactId>camel-salesforce</artifactId> + <version>2.12-SNAPSHOT</version> + </parent> + + <artifactId>camel-salesforce-component</artifactId> + <packaging>bundle</packaging> + <name>Camel :: Salesforce component</name> + <description>Camel Salesforce support</description> + + <properties> + <camel.osgi.export.pkg/> + <camel.osgi.export> + org.apache.camel.component.salesforce;version=${project.version}, + org.apache.camel.component.salesforce.api.*;version=${project.version} + </camel.osgi.export> + <camel.osgi.private.pkg>org.apache.camel.component.salesforce.internal.*</camel.osgi.private.pkg> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-client</artifactId> + <version>${jetty-version}</version> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-util</artifactId> + <version>${jetty-version}</version> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-io</artifactId> + <version>${jetty-version}</version> + </dependency> + <dependency> + <groupId>org.codehaus.jackson</groupId> + <artifactId>jackson-mapper-asl</artifactId> + <version>${jackson-version}</version> + </dependency> + <dependency> + <groupId>com.thoughtworks.xstream</groupId> + <artifactId>xstream</artifactId> + <version>${xstream-version}</version> + </dependency> + <dependency> + <groupId>org.cometd.java</groupId> + <artifactId>cometd-java-client</artifactId> + <version>${cometd-java-client-version}</version> + <exclusions> + <exclusion> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-util</artifactId> + </exclusion> + <exclusion> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-io</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>joda-time</groupId> + <artifactId>joda-time</artifactId> + <version>${jodatime2-bundle-version}</version> + </dependency> + <!-- logging --> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j-api-version}</version> + </dependency> + + <!-- testing --> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + <version>${slf4j-api-version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <version>${log4j-version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-test</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + +</project> http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceComponent.java ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceComponent.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceComponent.java new file mode 100644 index 0000000..a48502a --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceComponent.java @@ -0,0 +1,233 @@ +/** + * 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 org.apache.camel.Endpoint; +import org.apache.camel.impl.DefaultComponent; +import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.ServiceHelper; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.RedirectListener; +import org.apache.camel.component.salesforce.api.SalesforceException; +import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase; +import org.apache.camel.component.salesforce.internal.OperationName; +import org.apache.camel.component.salesforce.internal.SalesforceSession; +import org.apache.camel.component.salesforce.internal.streaming.SubscriptionHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * Represents the component that manages {@link SalesforceEndpoint}. + */ +public class SalesforceComponent extends DefaultComponent { + + private static final Logger LOG = LoggerFactory.getLogger(SalesforceComponent.class); + + private static final int MAX_CONNECTIONS_PER_ADDRESS = 20; + private static final int CONNECTION_TIMEOUT = 60000; + private static final int RESPONSE_TIMEOUT = 60000; + + private SalesforceLoginConfig loginConfig; + private SalesforceEndpointConfig config; + private String[] packages; + + // component state + private HttpClient httpClient; + private SalesforceSession session; + private Map<String, Class<?>> classMap; + + // Lazily created helper for consumer endpoints + private SubscriptionHelper subscriptionHelper; + + protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { + // get Operation from remaining URI + OperationName operationName = null; + String topicName = null; + try { + LOG.debug("Creating endpoint for ", remaining); + operationName = OperationName.fromValue(remaining); + } catch (IllegalArgumentException ex) { + // if its not an operation name, treat is as topic name for consumer endpoints + topicName = remaining; + } + + // create endpoint config + if (config == null) { + config = new SalesforceEndpointConfig(); + } + if (config.getHttpClient() == null) { + // set the component's httpClient as default + config.setHttpClient(httpClient); + } + + // create a deep copy and map parameters + final SalesforceEndpointConfig copy = config.copy(); + setProperties(copy, parameters); + + final SalesforceEndpoint endpoint = new SalesforceEndpoint(uri, this, copy, + operationName, topicName); + + // map remaining parameters to endpoint (specifically, synchronous) + setProperties(endpoint, parameters); + + return endpoint; + } + + @Override + protected void doStart() throws Exception { + super.doStart(); + + // validate properties + ObjectHelper.notNull(loginConfig, "loginConfig"); + + // create a Jetty HttpClient if not already set + if (null == httpClient) { + if (config != null && config.getHttpClient() != null) { + httpClient = config.getHttpClient(); + } else { + httpClient = new HttpClient(); + httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL); + httpClient.setMaxConnectionsPerAddress(MAX_CONNECTIONS_PER_ADDRESS); + httpClient.setConnectTimeout(CONNECTION_TIMEOUT); + httpClient.setTimeout(RESPONSE_TIMEOUT); + } + } + + // add redirect listener to handle Salesforce redirects + // this is ok to do since the RedirectListener is in the same classloader as Jetty client + String listenerClass = RedirectListener.class.getName(); + if (httpClient.getRegisteredListeners() == null || + !httpClient.getRegisteredListeners().contains(listenerClass)) { + httpClient.registerListener(listenerClass); + } + // SalesforceSecurityListener can't be registered the same way + // since Jetty HttpClient's Class.forName() can't see it + + // start the Jetty client to initialize thread pool, etc. + httpClient.start(); + + // support restarts + if (null == this.session) { + this.session = new SalesforceSession(httpClient, loginConfig); + } + + // login at startup if lazyLogin is disabled + if (!loginConfig.isLazyLogin()) { + ServiceHelper.startService(session); + } + + if (packages != null && packages.length > 0) { + // parse the packages to create SObject name to class map + classMap = parsePackages(); + } else { + // use an empty map to avoid NPEs later + LOG.warn("Missing property packages, getSObject* operations will NOT work"); + classMap = Collections.unmodifiableMap(new HashMap<String, Class<?>>()); + } + + if (subscriptionHelper != null) { + ServiceHelper.startService(subscriptionHelper); + } + } + + private Map<String, Class<?>> parsePackages() { + Map<String, Class<?>> result = new HashMap<String, Class<?>>(); + Set<Class<?>> classes = getCamelContext().getPackageScanClassResolver().findImplementations(AbstractSObjectBase.class, packages); + for (Class<?> aClass : classes) { + // findImplementations also returns AbstractSObjectBase for some reason!!! + if (AbstractSObjectBase.class != aClass) { + result.put(aClass.getSimpleName(), aClass); + } + } + + return Collections.unmodifiableMap(result); + } + + @Override + protected void doStop() throws Exception { + super.doStop(); + + try { + if (subscriptionHelper != null) { + // shutdown all streaming connections + // note that this is done in the component, and not in consumer + ServiceHelper.stopService(subscriptionHelper); + } + if (session != null && session.getAccessToken() != null) { + try { + // logout of Salesforce + ServiceHelper.stopService(session); + } catch (SalesforceException ignored) { + } + } + } finally { + if (httpClient != null) { + // shutdown http client connections + httpClient.stop(); + } + } + } + + public SubscriptionHelper getSubscriptionHelper() throws Exception { + if (subscriptionHelper == null) { + // lazily create subscription helper + subscriptionHelper = new SubscriptionHelper(this); + + // also start the helper to connect to Salesforce + ServiceHelper.startService(subscriptionHelper); + } + return subscriptionHelper; + } + + public SalesforceLoginConfig getLoginConfig() { + return loginConfig; + } + + public void setLoginConfig(SalesforceLoginConfig loginConfig) { + this.loginConfig = loginConfig; + } + + public SalesforceEndpointConfig getConfig() { + return config; + } + + public void setConfig(SalesforceEndpointConfig config) { + this.config = config; + } + + public String[] getPackages() { + return packages; + } + + public void setPackages(String[] packages) { + this.packages = packages; + } + + public SalesforceSession getSession() { + return session; + } + + public Map<String, Class<?>> getClassMap() { + return classMap; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceConsumer.java ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceConsumer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceConsumer.java new file mode 100644 index 0000000..9fa1b91 --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceConsumer.java @@ -0,0 +1,215 @@ +/** + * 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 org.apache.camel.AsyncCallback; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.impl.DefaultConsumer; +import org.apache.camel.util.ServiceHelper; +import org.codehaus.jackson.map.ObjectMapper; +import org.cometd.bayeux.Message; +import org.cometd.bayeux.client.ClientSessionChannel; +import org.apache.camel.component.salesforce.internal.client.DefaultRestClient; +import org.apache.camel.component.salesforce.internal.streaming.PushTopicHelper; +import org.apache.camel.component.salesforce.internal.client.RestClient; +import org.apache.camel.component.salesforce.internal.streaming.SubscriptionHelper; + +import java.io.IOException; +import java.io.StringReader; +import java.util.HashMap; +import java.util.Map; + +/** + * The Salesforce consumer. + */ +public class SalesforceConsumer extends DefaultConsumer { + + private static final ObjectMapper objectMapper = new ObjectMapper(); + private static final String EVENT_PROPERTY = "event"; + private static final String TYPE_PROPERTY = "type"; + private static final String CREATED_DATE_PROPERTY = "createdDate"; + private static final String SOBJECT_PROPERTY = "sobject"; + private static final double MINIMUM_VERSION = 24.0; + + private final SalesforceEndpoint endpoint; + public final SubscriptionHelper subscriptionHelper; + + private final String topicName; + private final Class<?> sObjectClass; + private boolean subscribed; + + public SalesforceConsumer(SalesforceEndpoint endpoint, Processor processor, SubscriptionHelper helper) { + super(endpoint, processor); + this.endpoint = endpoint; + + // check minimum supported API version + if (Double.valueOf(endpoint.getConfiguration().getApiVersion()) < MINIMUM_VERSION) { + throw new IllegalArgumentException("Minimum supported API version for consumer endpoints is " + 24.0); + } + + this.topicName = endpoint.getTopicName(); + this.subscriptionHelper = helper; + + // get sObjectClass to convert to + final String sObjectName = endpoint.getConfiguration().getSObjectName(); + if (sObjectName != null) { + sObjectClass = endpoint.getComponent().getClassMap().get(sObjectName); + if (sObjectClass == null) { + throw new IllegalArgumentException(String.format("SObject Class not found for %s", sObjectName)); + } + } else { + final String className = endpoint.getConfiguration().getSObjectClass(); + if (className != null) { + sObjectClass = endpoint.getComponent().getCamelContext().getClassResolver().resolveClass(className); + if (sObjectClass == null) { + throw new IllegalArgumentException(String.format("SObject Class not found %s", className)); + } + } else { + log.warn("Property sObjectName or sObjectClass NOT set, messages will be of type java.lang.Map"); + sObjectClass = null; + } + } + + } + + @Override + protected void doStart() throws Exception { + super.doStart(); + + final SalesforceEndpointConfig config = endpoint.getConfiguration(); + + // is a query configured in the endpoint? + if (config.getSObjectQuery() != null) { + // Note that we don't lookup topic if the query is not specified + // create REST client for PushTopic operations + SalesforceComponent component = endpoint.getComponent(); + RestClient restClient = new DefaultRestClient(component.getConfig().getHttpClient(), + endpoint.getConfiguration().getApiVersion(), "json", component.getSession()); + // don't forget to start the client + ServiceHelper.startService(restClient); + + try { + PushTopicHelper helper = new PushTopicHelper(config, topicName, restClient); + helper.createOrUpdateTopic(); + } finally { + // don't forget to stop the client + ServiceHelper.stopService(restClient); + } + } + + // subscribe to topic + subscriptionHelper.subscribe(topicName, this); + subscribed = true; + } + + @Override + protected void doStop() throws Exception { + super.doStop(); + + if (subscribed) { + subscribed = false; + // unsubscribe from topic + subscriptionHelper.unsubscribe(topicName, this); + } + } + + public void processMessage(ClientSessionChannel channel, Message message) { + final Exchange exchange = endpoint.createExchange(); + org.apache.camel.Message in = exchange.getIn(); + setHeaders(in, message); + + // get event data + // TODO do we need to add NPE checks for message/data.get***??? + Map<String, Object> data = message.getDataAsMap(); + + @SuppressWarnings("unchecked") final + Map<String, Object> event = (Map<String, Object>) data.get(EVENT_PROPERTY); + final Object eventType = event.get(TYPE_PROPERTY); + Object createdDate = event.get(CREATED_DATE_PROPERTY); + if (log.isDebugEnabled()) { + log.debug(String.format("Received event %s on channel %s created on %s", + eventType, channel.getChannelId(), createdDate)); + } + + in.setHeader("CamelSalesforceEventType", eventType); + in.setHeader("CamelSalesforceCreatedDate", createdDate); + + // get SObject + @SuppressWarnings("unchecked") + final Map<String, Object> sObject = (Map<String, Object>) data.get(SOBJECT_PROPERTY); + try { + + final String sObjectString = objectMapper.writeValueAsString(sObject); + log.debug("Received SObject: {}", sObjectString); + + if (sObjectClass == null) { + // return sobject map as exchange body + in.setBody(sObject); + } else { + // create the expected SObject + in.setBody(objectMapper.readValue( + new StringReader(sObjectString), sObjectClass)); + } + } catch (IOException e) { + final String msg = String.format("Error parsing message [%s] from Topic %s: %s", + message, topicName, e.getMessage()); + handleException(msg, new RuntimeCamelException(msg, e)); + } + + try { + getAsyncProcessor().process(exchange, new AsyncCallback() { + public void done(boolean doneSync) { + // noop + if (log.isTraceEnabled()) { + log.trace("Done processing event: {} {}", eventType.toString(), + doneSync ? "synchronously" : "asynchronously"); + } + } + }); + } catch (Exception e) { + handleException(String.format("Error processing %s: %s", exchange, e.getMessage()), e); + } finally { + Exception ex = exchange.getException(); + if (ex != null) { + handleException(String.format("Unhandled exception: %s", ex.getMessage()), ex); + } + } + } + + private void setHeaders(org.apache.camel.Message in, Message message) { + Map<String, Object> headers = new HashMap<String, Object>(); + // set topic name + headers.put("CamelSalesforceTopicName", topicName); + // set message properties as headers + headers.put("CamelSalesforceChannel", message.getChannel()); + headers.put("CamelSalesforceClientId", message.getClientId()); + + in.setHeaders(headers); + } + + @Override + public void handleException(String message, Throwable t) { + super.handleException(message, t); + } + + public String getTopicName() { + return topicName; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpoint.java ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpoint.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpoint.java new file mode 100644 index 0000000..24874bb --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpoint.java @@ -0,0 +1,96 @@ +/** + * 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 org.apache.camel.Consumer; +import org.apache.camel.Processor; +import org.apache.camel.Producer; +import org.apache.camel.impl.DefaultEndpoint; +import org.apache.camel.impl.SynchronousDelegateProducer; +import org.apache.camel.component.salesforce.internal.OperationName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Represents a Salesforce endpoint. + */ +public class SalesforceEndpoint extends DefaultEndpoint { + + private static final Logger LOG = LoggerFactory.getLogger(SalesforceEndpoint.class); + + private final SalesforceEndpointConfig config; + private final OperationName operationName; + private final String topicName; + + public SalesforceEndpoint(String uri, SalesforceComponent salesforceComponent, + SalesforceEndpointConfig config, OperationName operationName, String topicName) { + super(uri, salesforceComponent); + + this.config = config; + this.operationName = operationName; + this.topicName = topicName; + } + + public Producer createProducer() throws Exception { + // producer requires an operation, topicName must be the invalid operation name + if (operationName == null) { + throw new IllegalArgumentException(String.format("Invalid Operation %s", topicName)); + } + + SalesforceProducer producer = new SalesforceProducer(this); + if (isSynchronous()) { + return new SynchronousDelegateProducer(producer); + } else { + return producer; + } + } + + public Consumer createConsumer(Processor processor) throws Exception { + // consumer requires a topicName, operation name must be the invalid topic name + if (topicName == null) { + throw new IllegalArgumentException(String.format("Invalid topic name %s, matches a producer operation name", + operationName.value())); + } + + return new SalesforceConsumer(this, processor, + getComponent().getSubscriptionHelper()); + } + + @Override + public SalesforceComponent getComponent() { + return (SalesforceComponent) super.getComponent(); + } + + public boolean isSingleton() { + // re-use endpoint instance across multiple threads + // the description of this method is a little confusing + return true; + } + + public SalesforceEndpointConfig getConfiguration() { + return config; + } + + public OperationName getOperationName() { + return operationName; + } + + public String getTopicName() { + return topicName; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpointConfig.java ---------------------------------------------------------------------- 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 new file mode 100644 index 0000000..065f2f1 --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpointConfig.java @@ -0,0 +1,276 @@ +package org.apache.camel.component.salesforce; + +import org.apache.camel.RuntimeCamelException; +import org.eclipse.jetty.client.HttpClient; +import org.apache.camel.component.salesforce.api.dto.bulk.ContentType; +import org.apache.camel.component.salesforce.api.dto.bulk.OperationEnum; +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 java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public class SalesforceEndpointConfig implements Cloneable { + + // default API version + static final String DEFAULT_VERSION = "27.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"; + + // parameters for Bulk API + public static final String BULK_OPERATION = "bulkOperation"; + 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 Streaming API + public static final String UPDATE_TOPIC = "updateTopic"; + + // general properties + private String apiVersion = DEFAULT_VERSION; + + // Rest API properties + private PayloadFormat format = PayloadFormat.JSON; + private String sObjectName; + private String sObjectId; + private String sObjectFields; + private String sObjectIdName; + private String sObjectIdValue; + private String sObjectBlobFieldName; + private String sObjectClass; + private String sObjectQuery; + private String sObjectSearch; + + // Bulk API properties + private OperationEnum bulkOperation; + private ContentType contentType; + private String jobId; + private String batchId; + private String resultId; + + // Streaming API properties + private boolean updateTopic; + private NotifyForFieldsEnum notifyForFields; + private NotifyForOperationsEnum notifyForOperations; + + // Jetty HttpClient, set using reference + private HttpClient httpClient; + + public SalesforceEndpointConfig copy() { + try { + final SalesforceEndpointConfig copy = (SalesforceEndpointConfig) super.clone(); + // nothing to deep copy + return copy; + } catch (CloneNotSupportedException ex) { + throw new RuntimeCamelException(ex); + } + } + + public PayloadFormat getPayloadFormat() { + return format; + } + + public void setFormat(String format) { + this.format = PayloadFormat.valueOf(format.toUpperCase()); + } + + public String getApiVersion() { + return apiVersion; + } + + public void setApiVersion(String apiVersion) { + this.apiVersion = apiVersion; + } + + public String getSObjectName() { + return sObjectName; + } + + public void setSObjectName(String sObjectName) { + this.sObjectName = sObjectName; + } + + public String getSObjectId() { + return sObjectId; + } + + public void setSObjectId(String sObjectId) { + this.sObjectId = sObjectId; + } + + public String getSObjectFields() { + return sObjectFields; + } + + public void setSObjectFields(String sObjectFields) { + this.sObjectFields = sObjectFields; + } + + public String getSObjectIdName() { + return sObjectIdName; + } + + public void setSObjectIdName(String sObjectIdName) { + this.sObjectIdName = sObjectIdName; + } + + public String getSObjectIdValue() { + return sObjectIdValue; + } + + public void setSObjectIdValue(String sObjectIdValue) { + this.sObjectIdValue = sObjectIdValue; + } + + public String getSObjectBlobFieldName() { + return sObjectBlobFieldName; + } + + public void setSObjectBlobFieldName(String sObjectBlobFieldName) { + this.sObjectBlobFieldName = sObjectBlobFieldName; + } + + public String getSObjectClass() { + return sObjectClass; + } + + public void setSObjectClass(String sObjectClass) { + this.sObjectClass = sObjectClass; + } + + public String getSObjectQuery() { + return sObjectQuery; + } + + public void setSObjectQuery(String sObjectQuery) { + this.sObjectQuery = sObjectQuery; + } + + public String getSObjectSearch() { + return sObjectSearch; + } + + public void setSObjectSearch(String sObjectSearch) { + this.sObjectSearch = sObjectSearch; + } + + public OperationEnum getBulkOperation() { + return bulkOperation; + } + + public void setBulkOperation(OperationEnum bulkOperation) { + this.bulkOperation = bulkOperation; + } + + public ContentType getContentType() { + return contentType; + } + + public void setContentType(ContentType contentType) { + this.contentType = contentType; + } + + public String getJobId() { + return jobId; + } + + public void setJobId(String jobId) { + this.jobId = jobId; + } + + public String getBatchId() { + return batchId; + } + + public void setBatchId(String batchId) { + this.batchId = batchId; + } + + public String getResultId() { + return resultId; + } + + public void setResultId(String resultId) { + this.resultId = resultId; + } + + public boolean isUpdateTopic() { + return updateTopic; + } + + public void setUpdateTopic(boolean updateTopic) { + this.updateTopic = updateTopic; + } + + public NotifyForFieldsEnum getNotifyForFields() { + return notifyForFields; + } + + public void setNotifyForFields(NotifyForFieldsEnum notifyForFields) { + this.notifyForFields = notifyForFields; + } + + public NotifyForOperationsEnum getNotifyForOperations() { + return notifyForOperations; + } + + public void setNotifyForOperations(NotifyForOperationsEnum notifyForOperations) { + this.notifyForOperations = notifyForOperations; + } + + public void setHttpClient(HttpClient httpClient) { + this.httpClient = httpClient; + } + + public HttpClient getHttpClient() { + return httpClient; + } + + public Map<String, String> toValueMap() { + + final Map<String, String> valueMap = new HashMap<String, String>(); + 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); + + // add bulk API properties + if (bulkOperation != null) { + valueMap.put(BULK_OPERATION, bulkOperation.value()); + } + if (contentType != null) { + valueMap.put(CONTENT_TYPE, contentType.value()); + } + valueMap.put(JOB_ID, jobId); + valueMap.put(BATCH_ID, batchId); + valueMap.put(RESULT_ID, resultId); + + valueMap.put(UPDATE_TOPIC, String.valueOf(updateTopic)); + + return Collections.unmodifiableMap(valueMap); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceLoginConfig.java ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceLoginConfig.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceLoginConfig.java new file mode 100644 index 0000000..a6a097f --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceLoginConfig.java @@ -0,0 +1,99 @@ +/** + * 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; + +/** + * Configuration object for Salesforce login properties + */ +public class SalesforceLoginConfig { + + public static final String DEFAULT_LOGIN_URL = "https://login.salesforce.com"; + + private String loginUrl; + private String clientId; + private String clientSecret; + private String userName; + private String password; + // allow lazy login into Salesforce + // note that login issues may not surface until a message needs to be processed + private boolean lazyLogin; + + public SalesforceLoginConfig() { + loginUrl = DEFAULT_LOGIN_URL; + lazyLogin = false; + } + + public SalesforceLoginConfig(String loginUrl, + String clientId, String clientSecret, + String userName, String password, boolean lazyLogin) { + this.loginUrl = loginUrl; + this.clientId = clientId; + this.clientSecret = clientSecret; + this.userName = userName; + this.password = password; + this.lazyLogin = lazyLogin; + } + + public String getLoginUrl() { + return loginUrl; + } + + public void setLoginUrl(String loginUrl) { + this.loginUrl = loginUrl; + } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getClientSecret() { + return clientSecret; + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public boolean isLazyLogin() { + return lazyLogin; + } + + public void setLazyLogin(boolean lazyLogin) { + this.lazyLogin = lazyLogin; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceProducer.java ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceProducer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceProducer.java new file mode 100644 index 0000000..5cc4547 --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceProducer.java @@ -0,0 +1,102 @@ +/** + * 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 org.apache.camel.AsyncCallback; +import org.apache.camel.Exchange; +import org.apache.camel.impl.DefaultAsyncProducer; +import org.apache.camel.util.ServiceHelper; +import org.apache.camel.component.salesforce.api.SalesforceException; +import org.apache.camel.component.salesforce.internal.OperationName; +import org.apache.camel.component.salesforce.internal.PayloadFormat; +import org.apache.camel.component.salesforce.internal.processor.BulkApiProcessor; +import org.apache.camel.component.salesforce.internal.processor.JsonRestProcessor; +import org.apache.camel.component.salesforce.internal.processor.SalesforceProcessor; +import org.apache.camel.component.salesforce.internal.processor.XmlRestProcessor; + +/** + * The Salesforce producer. + */ +public class SalesforceProducer extends DefaultAsyncProducer { + + private final SalesforceProcessor processor; + + public SalesforceProducer(SalesforceEndpoint endpoint) throws SalesforceException { + super(endpoint); + + final SalesforceEndpointConfig endpointConfig = endpoint.getConfiguration(); + final PayloadFormat payloadFormat = endpointConfig.getPayloadFormat(); + + // check if its a Bulk Operation + if (isBulkOperation(endpoint.getOperationName())) { + processor = new BulkApiProcessor(endpoint); + } else { + // create an appropriate processor + if (payloadFormat == PayloadFormat.JSON) { + // create a JSON exchange processor + processor = new JsonRestProcessor(endpoint); + } else { + processor = new XmlRestProcessor(endpoint); + } + } + } + + private boolean isBulkOperation(OperationName operationName) { + switch (operationName) { + case CREATE_JOB: + case GET_JOB: + case CLOSE_JOB: + case ABORT_JOB: + case CREATE_BATCH: + case GET_BATCH: + case GET_ALL_BATCHES: + case GET_REQUEST: + case GET_RESULTS: + case CREATE_BATCH_QUERY: + case GET_QUERY_RESULT_IDS: + case GET_QUERY_RESULT: + return true; + + default: + return false; + } + } + + @Override + public boolean process(Exchange exchange, AsyncCallback callback) { + log.debug("Processing {}", + ((SalesforceEndpoint) getEndpoint()).getOperationName()); + return processor.process(exchange, callback); + } + + @Override + protected void doStart() throws Exception { + super.doStart(); + + // start Salesforce processor + ServiceHelper.startService(processor); + } + + @Override + protected void doStop() throws Exception { + // stop Salesforce processor + ServiceHelper.stopService(processor); + + super.doStop(); + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/JodaTimeConverter.java ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/JodaTimeConverter.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/JodaTimeConverter.java new file mode 100644 index 0000000..372e7a4 --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/JodaTimeConverter.java @@ -0,0 +1,64 @@ +/** + * 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.api; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Constructor; + +public class JodaTimeConverter implements Converter { + private static final Logger LOG = LoggerFactory.getLogger(JodaTimeConverter.class); + private final DateTimeFormatter formatter = ISODateTimeFormat.dateTime(); + + @Override + public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext context) { + DateTime dateTime = (DateTime) o; + writer.setValue(formatter.print(dateTime)); + } + + @Override + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + String dateTimeStr = reader.getValue(); + Class<?> requiredType = context.getRequiredType(); + try { + Constructor<?> constructor = requiredType.getConstructor(Object.class, DateTimeZone.class); + // normalize date time to UTC + return constructor.newInstance(dateTimeStr, DateTimeZone.UTC); + } catch (Exception e) { + throw new IllegalArgumentException( + String.format("Error reading Joda DateTime from value %s: %s", + dateTimeStr, e.getMessage()), + e); + } + } + + @Override + public boolean canConvert(Class aClass) { + return DateTime.class.isAssignableFrom(aClass); + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/PicklistEnumConverter.java ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/PicklistEnumConverter.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/PicklistEnumConverter.java new file mode 100644 index 0000000..06d0ca5 --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/PicklistEnumConverter.java @@ -0,0 +1,80 @@ +/** + * 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.api; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Method; + +public class PicklistEnumConverter implements Converter { + private static final Logger LOG = LoggerFactory.getLogger(PicklistEnumConverter.class); + private static final String FACTORY_METHOD = "fromValue"; + + @SuppressWarnings("unchecked") + @Override + public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext context) { + Class<?> aClass = o.getClass(); + try { + Method getterMethod = aClass.getMethod("value"); + writer.setValue((String) getterMethod.invoke(o)); + } catch (ReflectiveOperationException e) { + throw new IllegalArgumentException( + String.format("Exception writing pick list value %s of type %s: %s", + o, o.getClass().getName(), e.getMessage()), + e); + } + } + + @Override + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + String value = reader.getValue(); + Class<?> requiredType = context.getRequiredType(); + try { + Method factoryMethod = requiredType.getMethod(FACTORY_METHOD, String.class); + // use factory method to create object + return factoryMethod.invoke(null, value); + } catch (ReflectiveOperationException e) { + throw new IllegalArgumentException( + String.format("Exception reading pick list value %s of type %s: %s", + value, context.getRequiredType().getName(), e.getMessage()), + e); + } catch (SecurityException e) { + throw new IllegalArgumentException( + String.format("Security Exception reading pick list value %s of type %s: %s", + value, context.getRequiredType().getName(), e.getMessage()), + e); + } + } + + @Override + @SuppressWarnings("unchecked") + public boolean canConvert(Class aClass) { + try { + return Enum.class.isAssignableFrom(aClass) && + aClass.getMethod(FACTORY_METHOD, String.class) != null; + } catch (NoSuchMethodException e) { + return false; + } + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/SalesforceException.java ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/SalesforceException.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/SalesforceException.java new file mode 100644 index 0000000..760eebe --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/SalesforceException.java @@ -0,0 +1,104 @@ +/** + * 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.api; + +import org.apache.camel.CamelException; +import org.apache.camel.component.salesforce.api.dto.RestError; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class SalesforceException extends CamelException { + + private List<RestError> errors; + private int statusCode; + + public SalesforceException(List<RestError> errors, int statusCode) { + this(toErrorMessage(errors, statusCode), statusCode); + + this.errors = errors; + } + + public SalesforceException(String message, int statusCode) { + super(message); + + this.statusCode = statusCode; + } + + public SalesforceException(String message, Throwable cause) { + super(message, cause); + } + + public SalesforceException(Throwable cause) { + super(cause); + } + + public List<RestError> getErrors() { + return Collections.unmodifiableList(errors); + } + + public void setErrors(List<RestError> errors) { + if (this.errors != null) { + this.errors.clear(); + } else { + this.errors = new ArrayList<RestError>(); + } + this.errors.addAll(errors); + } + + public int getStatusCode() { + return statusCode; + } + + public void setStatusCode(int statusCode) { + this.statusCode = statusCode; + } + + @Override + public String toString() { + if (errors != null) { + return toErrorMessage(errors, statusCode); + } else { + // make sure we include the custom message + final StringBuilder builder = new StringBuilder("{ "); + builder.append(getMessage()); + builder.append(", statusCode: "); + builder.append(statusCode); + builder.append("}"); + + return builder.toString(); + } + } + + private static String toErrorMessage(List<RestError> errors, int statusCode) { + StringBuilder builder = new StringBuilder("{ "); + if (errors != null) { + builder.append(" errors: ["); + for (RestError error : errors) { + builder.append(error.toString()); + } + builder.append("], "); + } + builder.append("statusCode: "); + builder.append(statusCode); + builder.append("}"); + + return builder.toString(); + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractDTOBase.java ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractDTOBase.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractDTOBase.java new file mode 100644 index 0000000..e4723ae --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractDTOBase.java @@ -0,0 +1,40 @@ +/** + * 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.api.dto; + +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.annotate.JsonSerialize; + +import java.io.IOException; +import java.io.StringWriter; + +// disable null values in json output +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +public abstract class AbstractDTOBase { + private final static ObjectMapper mapper = new ObjectMapper(); + + @Override + public String toString() { + try { + StringWriter writer = new StringWriter(); + mapper.writeValue(writer, this); + return writer.toString(); + } catch (IOException e) { + return "Error in toString " + e.getMessage(); + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractQueryRecordsBase.java ---------------------------------------------------------------------- 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 new file mode 100644 index 0000000..ddfa6bf --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractQueryRecordsBase.java @@ -0,0 +1,72 @@ +/** + * 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.api.dto; + +/** + * Abstract base DTO for Salesforce SOQL Query records. + * <p> + * Derived classes must follow the template below: + * </p> + * <pre> + * {@code + * public class QueryResultMySObject extends AbstractQueryRecordsBase { + * @XStreamImplicit + * 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 { + + private Boolean done; + private int totalSize; + private String nextRecordsUrl; + + public Boolean getDone() { + return done; + } + + public void setDone(Boolean done) { + this.done = done; + } + + public int getTotalSize() { + return totalSize; + } + + public void setTotalSize(int totalSize) { + this.totalSize = totalSize; + } + + public String getNextRecordsUrl() { + return nextRecordsUrl; + } + + public void setNextRecordsUrl(String nextRecordsUrl) { + this.nextRecordsUrl = nextRecordsUrl; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractSObjectBase.java ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractSObjectBase.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractSObjectBase.java new file mode 100644 index 0000000..c236872 --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractSObjectBase.java @@ -0,0 +1,172 @@ +/** + * 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.api.dto; + +import org.codehaus.jackson.annotate.JsonProperty; +import org.joda.time.DateTime; + +public class AbstractSObjectBase extends AbstractDTOBase { + + private Attributes attributes; + + private String Id; + + private String OwnerId; + + private Boolean IsDeleted; + + private String Name; + + private DateTime CreatedDate; + + private String CreatedById; + + private DateTime LastModifiedDate; + + private String LastModifiedById; + + private DateTime SystemModstamp; + + private String LastActivityDate; + + /** + * Utility method to clear all {@link AbstractSObjectBase} fields. + * <p>Used when reusing a DTO for a new record.</p> + */ + public final void clearBaseFields() { + attributes = null; + Id = null; + OwnerId = null; + IsDeleted = null; + Name = null; + CreatedDate = null; + CreatedById = null; + LastModifiedDate = null; + LastModifiedById = null; + SystemModstamp = null; + LastActivityDate = null; + } + + public Attributes getAttributes() { + return attributes; + } + + public void setAttributes(Attributes attributes) { + this.attributes = attributes; + } + + @JsonProperty("Id") + public String getId() { + return Id; + } + + @JsonProperty("Id") + public void setId(String id) { + Id = id; + } + + @JsonProperty("OwnerId") + public String getOwnerId() { + return OwnerId; + } + + @JsonProperty("OwnerId") + public void setOwnerId(String ownerId) { + OwnerId = ownerId; + } + + @JsonProperty("IsDeleted") + public Boolean isIsDeleted() { + return IsDeleted; + } + + @JsonProperty("IsDeleted") + public void setIsDeleted(Boolean isDeleted) { + IsDeleted = isDeleted; + } + + @JsonProperty("Name") + public String getName() { + return Name; + } + + @JsonProperty("Name") + public void setName(String name) { + Name = name; + } + + @JsonProperty("CreatedDate") + public DateTime getCreatedDate() { + return CreatedDate; + } + + @JsonProperty("CreatedDate") + public void setCreatedDate(DateTime createdDate) { + CreatedDate = createdDate; + } + + @JsonProperty("CreatedById") + public String getCreatedById() { + return CreatedById; + } + + @JsonProperty("CreatedById") + public void setCreatedById(String createdById) { + CreatedById = createdById; + } + + @JsonProperty("LastModifiedDate") + public DateTime getLastModifiedDate() { + return LastModifiedDate; + } + + @JsonProperty("LastModifiedDate") + public void setLastModifiedDate(DateTime lastModifiedDate) { + LastModifiedDate = lastModifiedDate; + } + + @JsonProperty("LastModifiedById") + public String getLastModifiedById() { + return LastModifiedById; + } + + @JsonProperty("LastModifiedById") + public void setLastModifiedById(String lastModifiedById) { + LastModifiedById = lastModifiedById; + } + + @JsonProperty("SystemModstamp") + public DateTime getSystemModstamp() { + return SystemModstamp; + } + + @JsonProperty("SystemModstamp") + public void setSystemModstamp(DateTime systemModstamp) { + SystemModstamp = systemModstamp; + } + + @JsonProperty("LastActivityDate") + public String getLastActivityDate() { + return LastActivityDate; + } + + @JsonProperty("LastActivityDate") + public void setLastActivityDate(String lastActivityDate) { + LastActivityDate = lastActivityDate; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Attributes.java ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Attributes.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Attributes.java new file mode 100644 index 0000000..439f4c3 --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Attributes.java @@ -0,0 +1,38 @@ +/** + * 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.api.dto; + +public class Attributes extends AbstractDTOBase { + private String type; + private String url; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/ChildRelationShip.java ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/ChildRelationShip.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/ChildRelationShip.java new file mode 100644 index 0000000..4c2d58e --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/ChildRelationShip.java @@ -0,0 +1,74 @@ +/** + * 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.api.dto; + +public class ChildRelationShip extends AbstractDTOBase { + private String field; + private Boolean deprecatedAndHidden; + private String relationshipName; + private Boolean cascadeDelete; + private Boolean restrictedDelete; + private String childSObject; + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } + + public Boolean isDeprecatedAndHidden() { + return deprecatedAndHidden; + } + + public void setDeprecatedAndHidden(Boolean deprecatedAndHidden) { + this.deprecatedAndHidden = deprecatedAndHidden; + } + + public String getRelationshipName() { + return relationshipName; + } + + public void setRelationshipName(String relationshipName) { + this.relationshipName = relationshipName; + } + + public Boolean isCascadeDelete() { + return cascadeDelete; + } + + public void setCascadeDelete(Boolean cascadeDelete) { + this.cascadeDelete = cascadeDelete; + } + + public Boolean isRestrictedDelete() { + return restrictedDelete; + } + + public void setRestrictedDelete(Boolean restrictedDelete) { + this.restrictedDelete = restrictedDelete; + } + + public String getChildSObject() { + return childSObject; + } + + public void setChildSObject(String childSObject) { + this.childSObject = childSObject; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/CreateSObjectResult.java ---------------------------------------------------------------------- diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/CreateSObjectResult.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/CreateSObjectResult.java new file mode 100644 index 0000000..bc9fdaa --- /dev/null +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/CreateSObjectResult.java @@ -0,0 +1,57 @@ +/** + * 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.api.dto; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamImplicit; + +import java.util.List; + +@XStreamAlias("Result") +public class CreateSObjectResult extends AbstractDTOBase { + + private String id; + + @XStreamImplicit + private List<RestError> errors; + + private Boolean success; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public List<RestError> getErrors() { + return errors; + } + + public void setErrors(List<RestError> errors) { + this.errors = errors; + } + + public Boolean getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } +}