Salesforce.com interface to directly access Salesforce.com

Dependencies:   HTTPClient-SSL MbedJSONValue

Dependents:   df-2014-salesforce-hrm-k64f

Fork of SalesforceInterface by Doug Anson

Committer:
ansond
Date:
Tue Sep 23 17:31:36 2014 +0000
Revision:
14:3c8d11b48814
Parent:
13:3088dd4b4bef
Child:
15:89044c68ad36
updates per SF feedback

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 0:518b1ca956fc 1 /* Copyright C2014 ARM, MIT License
ansond 0:518b1ca956fc 2 *
ansond 9:a254fcd904be 3 * Author: Doug Anson (doug.anson@arm.com)
ansond 9:a254fcd904be 4 *
ansond 0:518b1ca956fc 5 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
ansond 0:518b1ca956fc 6 * and associated documentation files the "Software", to deal in the Software without restriction,
ansond 0:518b1ca956fc 7 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
ansond 0:518b1ca956fc 8 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
ansond 0:518b1ca956fc 9 * furnished to do so, subject to the following conditions:
ansond 0:518b1ca956fc 10 *
ansond 0:518b1ca956fc 11 * The above copyright notice and this permission notice shall be included in all copies or
ansond 0:518b1ca956fc 12 * substantial portions of the Software.
ansond 0:518b1ca956fc 13 *
ansond 0:518b1ca956fc 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
ansond 0:518b1ca956fc 15 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
ansond 0:518b1ca956fc 16 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
ansond 0:518b1ca956fc 17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
ansond 0:518b1ca956fc 18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
ansond 0:518b1ca956fc 19 */
ansond 0:518b1ca956fc 20
ansond 0:518b1ca956fc 21 #ifndef _SALESFORCE_INTERFACE_H_
ansond 0:518b1ca956fc 22 #define _SALESFORCE_INTERFACE_H_
ansond 0:518b1ca956fc 23
ansond 0:518b1ca956fc 24 // ErrorHandler
ansond 0:518b1ca956fc 25 #include "ErrorHandler.h"
ansond 0:518b1ca956fc 26
ansond 0:518b1ca956fc 27 // SSL-based HTTP support
ansond 0:518b1ca956fc 28 #include "HTTPClient.h"
ansond 0:518b1ca956fc 29
ansond 0:518b1ca956fc 30 // JSON parsing support
ansond 0:518b1ca956fc 31 #include "MbedJSONValue.h"
ansond 0:518b1ca956fc 32
ansond 0:518b1ca956fc 33 // verbose debugging
ansond 0:518b1ca956fc 34 #if ENABLE_DEBUG_LOGGING
ansond 8:47db53cd5884 35 #define DEBUG(...) { this->logger()->logConsole(__VA_ARGS__); }
ansond 0:518b1ca956fc 36 #else
ansond 0:518b1ca956fc 37 #define DEBUG(...)
ansond 0:518b1ca956fc 38 #endif
ansond 7:97ea5ef906f7 39
ansond 7:97ea5ef906f7 40 // convenience macros
ansond 8:47db53cd5884 41 #define DEFINE_BUFFER(x) char x[MAX_BUFFER_LENGTH+1]
ansond 8:47db53cd5884 42 #define RESET_BUFFER(x) memset(x,0,MAX_BUFFER_LENGTH+1)
ansond 8:47db53cd5884 43 #define ALLOC_BUFFER(x) DEFINE_BUFFER(x);RESET_BUFFER(x)
ansond 8:47db53cd5884 44
ansond 8:47db53cd5884 45 #define DEFINE_SML_BUFFER(x) char x[MAX_SMALL_BUFFER_LENGTH+1]
ansond 8:47db53cd5884 46 #define RESET_SML_BUFFER(x) memset(x,0,MAX_SMALL_BUFFER_LENGTH+1)
ansond 8:47db53cd5884 47 #define ALLOC_SML_BUFFER(x) DEFINE_SML_BUFFER(x);RESET_SML_BUFFER(x)
ansond 8:47db53cd5884 48
ansond 8:47db53cd5884 49 // Default salesforce API version (must be in XX.Y format and must be a string)
ansond 8:47db53cd5884 50 #define SALESFORCE_API_VERSION_LENGTH 10
ansond 8:47db53cd5884 51 #ifndef SALESFORCE_API_VERSION
ansond 8:47db53cd5884 52 #define SALESFORCE_API_VERSION "28.0"
ansond 8:47db53cd5884 53 #endif
ansond 0:518b1ca956fc 54
ansond 0:518b1ca956fc 55 // HTTP Verbs
ansond 0:518b1ca956fc 56 typedef enum {
ansond 0:518b1ca956fc 57 GET,
ansond 0:518b1ca956fc 58 PUT,
ansond 0:518b1ca956fc 59 POST,
ansond 0:518b1ca956fc 60 DELETE,
ansond 0:518b1ca956fc 61 NUM_VERBS
ansond 0:518b1ca956fc 62 } HttpVerb;
ansond 0:518b1ca956fc 63
ansond 0:518b1ca956fc 64 // Supported input data types for PUT and POST (Defined by HTTPClient-SSL/data support...)
ansond 0:518b1ca956fc 65 typedef enum {
ansond 0:518b1ca956fc 66 JSON, // ContentType: application/json
ansond 0:518b1ca956fc 67 PLAIN_TEXT, // ContentType: plain/text
ansond 0:518b1ca956fc 68 FORM_MAPPED, // ContentType: application/x-www-form-urlencoded
ansond 0:518b1ca956fc 69 NUM_TYPES
ansond 0:518b1ca956fc 70 } InputDataTypes;
ansond 0:518b1ca956fc 71
ansond 7:97ea5ef906f7 72 // OAUTH structure
ansond 7:97ea5ef906f7 73 typedef struct {
ansond 7:97ea5ef906f7 74 bool valid;
ansond 7:97ea5ef906f7 75 string id;
ansond 7:97ea5ef906f7 76 string issued_at;
ansond 7:97ea5ef906f7 77 string token_type;
ansond 7:97ea5ef906f7 78 string instance_url;
ansond 7:97ea5ef906f7 79 string signature;
ansond 7:97ea5ef906f7 80 string access_token;
ansond 7:97ea5ef906f7 81 } OauthToken;
ansond 10:845ea6d00b65 82
ansond 13:3088dd4b4bef 83 /**
ansond 13:3088dd4b4bef 84 * Salesforce Interface
ansond 13:3088dd4b4bef 85 * SalesforceInterface provides a simple C++ API into the REST-based Salesforce.com APIs
ansond 13:3088dd4b4bef 86 *
ansond 13:3088dd4b4bef 87 * Example Project: http://mbed.org/users/ansond/code/df-2014-salesforce-testharness-k64f/
ansond 13:3088dd4b4bef 88 *
ansond 13:3088dd4b4bef 89 * @code
ansond 13:3088dd4b4bef 90 * #include "Definitions.h" // definitions including platform specifics...
ansond 13:3088dd4b4bef 91 * #include "ErrorHandler.h"
ansond 13:3088dd4b4bef 92 *
ansond 13:3088dd4b4bef 93 * // include salesforce.com credentials
ansond 13:3088dd4b4bef 94 * #include "sf_creds.h"
ansond 13:3088dd4b4bef 95 *
ansond 13:3088dd4b4bef 96 * // our Serial port
ansond 13:3088dd4b4bef 97 * #include "BufferedSerial.h"
ansond 13:3088dd4b4bef 98 * BufferedSerial pc(USBTX, USBRX);
ansond 13:3088dd4b4bef 99 *
ansond 13:3088dd4b4bef 100 * // Ethernet
ansond 13:3088dd4b4bef 101 * #include "EthernetInterface.h"
ansond 13:3088dd4b4bef 102 * EthernetInterface ethernet;
ansond 13:3088dd4b4bef 103 *
ansond 13:3088dd4b4bef 104 * // HTTP
ansond 13:3088dd4b4bef 105 * #include "HTTPClient.h"
ansond 13:3088dd4b4bef 106 * HTTPClient http;
ansond 13:3088dd4b4bef 107 *
ansond 13:3088dd4b4bef 108 * // Salesforce.com Interface
ansond 13:3088dd4b4bef 109 * #include "SalesforceInterface.h"
ansond 13:3088dd4b4bef 110 *
ansond 13:3088dd4b4bef 111 * // test case persistence
ansond 13:3088dd4b4bef 112 * char *object_name = NULL;
ansond 13:3088dd4b4bef 113 * char *account_name = NULL;
ansond 13:3088dd4b4bef 114 * char *updated_account_name = NULL;
ansond 14:3c8d11b48814 115 * DEFINE_SML_BUFFER(record_id);
ansond 13:3088dd4b4bef 116 *
ansond 13:3088dd4b4bef 117 * // *************** Test Cases ************************
ansond 13:3088dd4b4bef 118 *
ansond 14:3c8d11b48814 119 * void Test_getSalesforceToken(ErrorHandler *logger,SalesforceInterface *sf) {
ansond 14:3c8d11b48814 120 * logger->log("\r\n\r\nGetting Salesforce Token...");
ansond 13:3088dd4b4bef 121 * logger->turnLEDPurple();
ansond 13:3088dd4b4bef 122 *
ansond 13:3088dd4b4bef 123 * // get the salesforce ID
ansond 14:3c8d11b48814 124 * char *id = sf->getSalesforceToken();
ansond 13:3088dd4b4bef 125 * if (id != NULL && strlen(id) > 0)
ansond 13:3088dd4b4bef 126 * logger->log("Saleforce ID: %s",id);
ansond 13:3088dd4b4bef 127 * else
ansond 13:3088dd4b4bef 128 * logger->log("Unable to get Saleforce ID");
ansond 13:3088dd4b4bef 129 * logger->turnLEDGreen();
ansond 13:3088dd4b4bef 130 * }
ansond 13:3088dd4b4bef 131 *
ansond 13:3088dd4b4bef 132 * void Test_query(ErrorHandler *logger,SalesforceInterface *sf,char *query_str) {
ansond 13:3088dd4b4bef 133 * logger->log("\r\n\r\nExecuting test query: %s",query_str);
ansond 13:3088dd4b4bef 134 * logger->turnLEDPurple();
ansond 13:3088dd4b4bef 135 * if (query_str != NULL && strlen(query_str) > 0) {
ansond 13:3088dd4b4bef 136 * ALLOC_BUFFER(response);
ansond 13:3088dd4b4bef 137 * char *answer = sf->query(query_str,response,MAX_BUFFER_LENGTH);
ansond 13:3088dd4b4bef 138 * if (answer != NULL) logger->log("query result: %s",answer);
ansond 13:3088dd4b4bef 139 * else logger->log("query - NULL result");
ansond 13:3088dd4b4bef 140 * }
ansond 13:3088dd4b4bef 141 * else {
ansond 13:3088dd4b4bef 142 * logger->log("Unable to perform query as we do not have our salesforce ID");
ansond 13:3088dd4b4bef 143 * }
ansond 13:3088dd4b4bef 144 * logger->turnLEDGreen();
ansond 13:3088dd4b4bef 145 * }
ansond 13:3088dd4b4bef 146 *
ansond 13:3088dd4b4bef 147 * void Test_create(ErrorHandler *logger,SalesforceInterface *sf) {
ansond 13:3088dd4b4bef 148 * logger->log("\r\n\r\nExecuting create()");
ansond 13:3088dd4b4bef 149 * logger->turnLEDPurple();
ansond 13:3088dd4b4bef 150 *
ansond 14:3c8d11b48814 151 * // create a new record
ansond 14:3c8d11b48814 152 * MbedJSONValue new_record;
ansond 14:3c8d11b48814 153 * new_record["name"] = account_name;
ansond 13:3088dd4b4bef 154 *
ansond 13:3088dd4b4bef 155 * // DEBUG
ansond 14:3c8d11b48814 156 * logger->log("Create: new record: %s",new_record.serialize().c_str());
ansond 13:3088dd4b4bef 157 *
ansond 13:3088dd4b4bef 158 * // create...
ansond 14:3c8d11b48814 159 * MbedJSONValue response = sf->createRecord(object_name,new_record);
ansond 13:3088dd4b4bef 160 *
ansond 13:3088dd4b4bef 161 * // display the result
ansond 13:3088dd4b4bef 162 * char *result = (char *)response.serialize().c_str();
ansond 13:3088dd4b4bef 163 * if (result != NULL && strlen(result) > 0 && strcmp(result,"null") != 0) {
ansond 13:3088dd4b4bef 164 * // save off the ID if we succeeded
ansond 13:3088dd4b4bef 165 * logger->log("Create: result: %s",result);
ansond 13:3088dd4b4bef 166 * logger->log("Create: http_code=%d",sf->httpResponseCode());
ansond 14:3c8d11b48814 167 * RESET_SML_BUFFER(record_id);
ansond 14:3c8d11b48814 168 * strcpy(record_id,(char *)response["id"].get<std::string>().c_str());
ansond 13:3088dd4b4bef 169 * }
ansond 13:3088dd4b4bef 170 * else {
ansond 13:3088dd4b4bef 171 * // failure
ansond 13:3088dd4b4bef 172 * logger->log("Create: FAILED http_code=%d",sf->httpResponseCode());
ansond 13:3088dd4b4bef 173 * }
ansond 13:3088dd4b4bef 174 * logger->turnLEDGreen();
ansond 13:3088dd4b4bef 175 * }
ansond 13:3088dd4b4bef 176 *
ansond 13:3088dd4b4bef 177 * void Test_read(ErrorHandler *logger,SalesforceInterface *sf) {
ansond 13:3088dd4b4bef 178 * logger->log("\r\n\r\nExecuting read()");
ansond 13:3088dd4b4bef 179 * logger->turnLEDPurple();
ansond 13:3088dd4b4bef 180 *
ansond 13:3088dd4b4bef 181 * // DEBUG
ansond 14:3c8d11b48814 182 * logger->log("Read: reading: %s from %s",record_id,object_name);
ansond 13:3088dd4b4bef 183 *
ansond 13:3088dd4b4bef 184 * // read...
ansond 14:3c8d11b48814 185 * MbedJSONValue response = sf->readRecord(object_name,record_id);
ansond 13:3088dd4b4bef 186 *
ansond 13:3088dd4b4bef 187 * // display the result
ansond 13:3088dd4b4bef 188 * char *result = (char *)response.serialize().c_str();
ansond 13:3088dd4b4bef 189 * if (result != NULL && strlen(result) > 0 && strcmp(result,"null") != 0) {
ansond 13:3088dd4b4bef 190 * // save off the ID if we succeeded
ansond 13:3088dd4b4bef 191 * logger->log("Read: result: %s",result);
ansond 13:3088dd4b4bef 192 * logger->log("Read: http_code=%d",sf->httpResponseCode());
ansond 13:3088dd4b4bef 193 * }
ansond 13:3088dd4b4bef 194 * else {
ansond 13:3088dd4b4bef 195 * // failure
ansond 13:3088dd4b4bef 196 * logger->log("Read: FAILED http_code=%d",sf->httpResponseCode());
ansond 13:3088dd4b4bef 197 * }
ansond 13:3088dd4b4bef 198 *
ansond 13:3088dd4b4bef 199 * logger->turnLEDGreen();
ansond 13:3088dd4b4bef 200 * }
ansond 13:3088dd4b4bef 201 *
ansond 13:3088dd4b4bef 202 * void Test_update(ErrorHandler *logger,SalesforceInterface *sf) {
ansond 13:3088dd4b4bef 203 * logger->log("\r\n\r\nExecuting update()");
ansond 13:3088dd4b4bef 204 * logger->turnLEDPurple();
ansond 13:3088dd4b4bef 205 *
ansond 14:3c8d11b48814 206 * // update am existing record - assume "name" is the proper key for the record you wish to update...
ansond 14:3c8d11b48814 207 * MbedJSONValue changed_record;
ansond 14:3c8d11b48814 208 * changed_record["name"] = updated_account_name;
ansond 13:3088dd4b4bef 209 *
ansond 13:3088dd4b4bef 210 * // DEBUG
ansond 14:3c8d11b48814 211 * logger->log("Update: updated record: %s",changed_record.serialize().c_str());
ansond 13:3088dd4b4bef 212 *
ansond 13:3088dd4b4bef 213 * // update...
ansond 14:3c8d11b48814 214 * bool updated = sf->updateRecord(object_name,record_id,changed_record);
ansond 13:3088dd4b4bef 215 *
ansond 13:3088dd4b4bef 216 * // display the result
ansond 13:3088dd4b4bef 217 * if (updated) {
ansond 13:3088dd4b4bef 218 * // SUCCESS
ansond 13:3088dd4b4bef 219 * logger->log("Update: successful! http_code=%d",sf->httpResponseCode());
ansond 13:3088dd4b4bef 220 * }
ansond 13:3088dd4b4bef 221 * else {
ansond 13:3088dd4b4bef 222 * // failure
ansond 13:3088dd4b4bef 223 * logger->log("Update: FAILED http_code=%d",sf->httpResponseCode());
ansond 13:3088dd4b4bef 224 * }
ansond 13:3088dd4b4bef 225 * logger->turnLEDGreen();
ansond 13:3088dd4b4bef 226 * }
ansond 13:3088dd4b4bef 227 *
ansond 13:3088dd4b4bef 228 * void Test_delete(ErrorHandler *logger,SalesforceInterface *sf) {
ansond 13:3088dd4b4bef 229 * logger->log("\r\n\r\nExecuting delete()");
ansond 13:3088dd4b4bef 230 * logger->turnLEDPurple();
ansond 13:3088dd4b4bef 231 *
ansond 13:3088dd4b4bef 232 * // DEBUG
ansond 14:3c8d11b48814 233 * logger->log("Delete: deleting: %s from %s",record_id,object_name);
ansond 13:3088dd4b4bef 234 *
ansond 13:3088dd4b4bef 235 * // delete...
ansond 14:3c8d11b48814 236 * bool deleted = sf->deleteRecord(object_name,record_id);
ansond 13:3088dd4b4bef 237 *
ansond 13:3088dd4b4bef 238 * // display the result
ansond 13:3088dd4b4bef 239 * if (deleted) {
ansond 13:3088dd4b4bef 240 * // SUCCESS
ansond 13:3088dd4b4bef 241 * logger->log("Delete: successful! http_code=%d",sf->httpResponseCode());
ansond 13:3088dd4b4bef 242 * }
ansond 13:3088dd4b4bef 243 * else {
ansond 13:3088dd4b4bef 244 * // failure
ansond 13:3088dd4b4bef 245 * logger->log("Delete: FAILED http_code=%d",sf->httpResponseCode());
ansond 13:3088dd4b4bef 246 * }
ansond 13:3088dd4b4bef 247 *
ansond 13:3088dd4b4bef 248 * logger->turnLEDGreen();
ansond 13:3088dd4b4bef 249 * }
ansond 13:3088dd4b4bef 250 *
ansond 13:3088dd4b4bef 251 * void Test_reset_auth(ErrorHandler *logger,SalesforceInterface *sf) {
ansond 14:3c8d11b48814 252 * logger->log("\r\n\r\nForcing API to reset OAUTH token and Salesforce Token...");
ansond 13:3088dd4b4bef 253 * logger->turnLEDPurple();
ansond 14:3c8d11b48814 254 * sf->resetSalesforceToken();
ansond 13:3088dd4b4bef 255 * logger->turnLEDGreen();
ansond 13:3088dd4b4bef 256 * }
ansond 13:3088dd4b4bef 257 *
ansond 13:3088dd4b4bef 258 * // *************** Test Cases ************************
ansond 13:3088dd4b4bef 259 *
ansond 13:3088dd4b4bef 260 * // Main Task...
ansond 13:3088dd4b4bef 261 * void mainTask(void const *v) {
ansond 13:3088dd4b4bef 262 *
ansond 13:3088dd4b4bef 263 * // create our object instances
ansond 13:3088dd4b4bef 264 * ErrorHandler logger(&pc,NULL);
ansond 13:3088dd4b4bef 265 * SalesforceInterface *sf = NULL;
ansond 13:3088dd4b4bef 266 *
ansond 13:3088dd4b4bef 267 * // announce
ansond 13:3088dd4b4bef 268 * logger.log("\r\n\r\nARM Salesforce Interface TestHarness v%s",APP_VERSION);
ansond 13:3088dd4b4bef 269 * logger.turnLEDBlue();
ansond 13:3088dd4b4bef 270 *
ansond 13:3088dd4b4bef 271 * // initialize Ethernet
ansond 13:3088dd4b4bef 272 * logger.log("Initializing Ethernet...");
ansond 13:3088dd4b4bef 273 * ethernet.init();
ansond 13:3088dd4b4bef 274 *
ansond 13:3088dd4b4bef 275 * // get a DHCP address and bring the network interface up
ansond 13:3088dd4b4bef 276 * logger.log("Getting IP Address...");
ansond 13:3088dd4b4bef 277 * logger.turnLEDOrange();
ansond 13:3088dd4b4bef 278 * if (ethernet.connect() == 0) {
ansond 13:3088dd4b4bef 279 * // log our IP address (DHCP)
ansond 13:3088dd4b4bef 280 * logger.log("IP Address: %s",ethernet.getIPAddress());
ansond 13:3088dd4b4bef 281 *
ansond 13:3088dd4b4bef 282 * // allocate the Salesforce.com interface
ansond 13:3088dd4b4bef 283 * logger.log("Allocating Saleforce.com interface...");
ansond 13:3088dd4b4bef 284 * sf = new SalesforceInterface(&logger,&http);
ansond 13:3088dd4b4bef 285 *
ansond 13:3088dd4b4bef 286 * // set our Salesforce.com credentials
ansond 13:3088dd4b4bef 287 * sf->setCredentials(username,password,client_id,client_secret);
ansond 13:3088dd4b4bef 288 *
ansond 13:3088dd4b4bef 289 * // *************** BEGIN TEST CASES *****************
ansond 13:3088dd4b4bef 290 *
ansond 13:3088dd4b4bef 291 * // configuration for the test cases
ansond 13:3088dd4b4bef 292 * object_name = "Account"; // use the account object
ansond 14:3c8d11b48814 293 * account_name = "ARM"; // add this record (name)
ansond 14:3c8d11b48814 294 * updated_account_name = "ARM Holdings"; // update the existing record's name to this
ansond 14:3c8d11b48814 295 * RESET_SML_BUFFER(record_id); // buffer for the record's ID
ansond 13:3088dd4b4bef 296 *
ansond 13:3088dd4b4bef 297 * // Perform a Create
ansond 13:3088dd4b4bef 298 * Test_create(&logger,sf);
ansond 13:3088dd4b4bef 299 *
ansond 13:3088dd4b4bef 300 * // Perform a Read
ansond 13:3088dd4b4bef 301 * Test_read(&logger,sf);
ansond 13:3088dd4b4bef 302 *
ansond 13:3088dd4b4bef 303 * // Perform a Query
ansond 13:3088dd4b4bef 304 * Test_query(&logger,sf,"SELECT Id,Name FROM Account LIMIT 5");
ansond 13:3088dd4b4bef 305 *
ansond 13:3088dd4b4bef 306 * // Perform an Update
ansond 13:3088dd4b4bef 307 * Test_update(&logger,sf);
ansond 13:3088dd4b4bef 308 *
ansond 13:3088dd4b4bef 309 * // Perform a second Read to visually confirm the update above...
ansond 13:3088dd4b4bef 310 * Test_read(&logger,sf);
ansond 13:3088dd4b4bef 311 *
ansond 14:3c8d11b48814 312 * // force the API to re-acquire the OAUTH token and Salesforce Token
ansond 13:3088dd4b4bef 313 * Test_reset_auth(&logger,sf);
ansond 13:3088dd4b4bef 314 *
ansond 14:3c8d11b48814 315 * // Perform a Read (should re-acquire the OAUTH token and Salesforce Token)
ansond 13:3088dd4b4bef 316 * Test_read(&logger,sf);
ansond 13:3088dd4b4bef 317 *
ansond 13:3088dd4b4bef 318 * // Perform a Delete
ansond 13:3088dd4b4bef 319 * Test_delete(&logger,sf);
ansond 13:3088dd4b4bef 320 *
ansond 14:3c8d11b48814 321 * // reset the record ID buffer
ansond 14:3c8d11b48814 322 * // RESET_SML_BUFFER(record_id);
ansond 13:3088dd4b4bef 323 *
ansond 13:3088dd4b4bef 324 * // Perform a Read - should error out
ansond 13:3088dd4b4bef 325 * Test_read(&logger,sf);
ansond 13:3088dd4b4bef 326 *
ansond 14:3c8d11b48814 327 * // reset the record ID buffer
ansond 14:3c8d11b48814 328 * RESET_SML_BUFFER(record_id);
ansond 13:3088dd4b4bef 329 *
ansond 13:3088dd4b4bef 330 * // *************** BEGIN TEST CASES *****************
ansond 13:3088dd4b4bef 331 *
ansond 13:3088dd4b4bef 332 * // entering main loop
ansond 13:3088dd4b4bef 333 * logger.log("All tests complete...\r\nExiting...");
ansond 13:3088dd4b4bef 334 * logger.turnLEDBlue();
ansond 13:3088dd4b4bef 335 * exit(0);
ansond 13:3088dd4b4bef 336 * }
ansond 13:3088dd4b4bef 337 * else {
ansond 13:3088dd4b4bef 338 * logger.log("No Network... Exiting...");
ansond 13:3088dd4b4bef 339 * logger.turnLEDRed();
ansond 13:3088dd4b4bef 340 * exit(1);
ansond 13:3088dd4b4bef 341 * }
ansond 13:3088dd4b4bef 342 *
ansond 13:3088dd4b4bef 343 * }
ansond 13:3088dd4b4bef 344 *
ansond 13:3088dd4b4bef 345 * // main entry
ansond 13:3088dd4b4bef 346 * int main() {
ansond 13:3088dd4b4bef 347 * Thread workerTask(mainTask, NULL, osPriorityNormal, STACK_SIZE);
ansond 13:3088dd4b4bef 348 * while (true) {
ansond 13:3088dd4b4bef 349 * Thread::wait(10*WAIT_TIME_MS);
ansond 13:3088dd4b4bef 350 * }
ansond 13:3088dd4b4bef 351 * }
ansond 13:3088dd4b4bef 352 * @endcode
ansond 13:3088dd4b4bef 353 *
ansond 10:845ea6d00b65 354 */
ansond 0:518b1ca956fc 355 class SalesforceInterface {
ansond 0:518b1ca956fc 356 private:
ansond 0:518b1ca956fc 357 ErrorHandler *m_logger;
ansond 0:518b1ca956fc 358 HTTPClient *m_http;
ansond 0:518b1ca956fc 359 char *m_username;
ansond 0:518b1ca956fc 360 char *m_password;
ansond 0:518b1ca956fc 361 char *m_client_id;
ansond 0:518b1ca956fc 362 char *m_client_secret;
ansond 0:518b1ca956fc 363 bool m_have_creds;
ansond 7:97ea5ef906f7 364 OauthToken m_oauth_token;
ansond 7:97ea5ef906f7 365 HTTPResult m_http_status;
ansond 7:97ea5ef906f7 366 int m_http_response_code;
ansond 7:97ea5ef906f7 367 char m_http_redirection_url[MAX_BUFFER_LENGTH+1];
ansond 8:47db53cd5884 368 char m_salesforce_id[MAX_BUFFER_LENGTH+1];
ansond 8:47db53cd5884 369 char m_salesforce_api[SALESFORCE_API_VERSION_LENGTH];
ansond 0:518b1ca956fc 370
ansond 0:518b1ca956fc 371 public:
ansond 10:845ea6d00b65 372 /**
ansond 10:845ea6d00b65 373 Default constructor
ansond 10:845ea6d00b65 374 @param logger ErrorHandler instance
ansond 10:845ea6d00b65 375 @param http HTTPClient instance
ansond 10:845ea6d00b65 376 */
ansond 0:518b1ca956fc 377 SalesforceInterface(ErrorHandler *logger,HTTPClient *http);
ansond 10:845ea6d00b65 378
ansond 10:845ea6d00b65 379 /**
ansond 10:845ea6d00b65 380 Default destructor
ansond 10:845ea6d00b65 381 */
ansond 0:518b1ca956fc 382 virtual ~SalesforceInterface();
ansond 0:518b1ca956fc 383
ansond 10:845ea6d00b65 384 /**
ansond 10:845ea6d00b65 385 Establish salesforce.com credentials
ansond 10:845ea6d00b65 386 @param username salesforce.com account user name
ansond 12:0e7290e093df 387 @param password salesforce.com account password. The password must be of the form [password][security token]
ansond 10:845ea6d00b65 388 @param client_id salesforce.com connected application "customer key" value
ansond 12:0e7290e093df 389 @param client_secret salesforce.com connected application client secret value
ansond 10:845ea6d00b65 390 */
ansond 0:518b1ca956fc 391 void setCredentials(char *username,char *password,char *client_id,char *client_secret);
ansond 0:518b1ca956fc 392
ansond 10:845ea6d00b65 393 /**
ansond 10:845ea6d00b65 394 Get our salesforce.com ID
ansond 11:b6e6519688e8 395 @param fetch boolean that will direct the interface to fetch the ID if not already done (default = true)
ansond 10:845ea6d00b65 396 @return our salesforce ID in JSON format or NULL if in error
ansond 10:845ea6d00b65 397 */
ansond 14:3c8d11b48814 398 char *getSalesforceToken(bool fetch = true);
ansond 9:a254fcd904be 399
ansond 10:845ea6d00b65 400 /**
ansond 10:845ea6d00b65 401 Force the interface to re-acquire the OAUTH token and salesforce ID
ansond 10:845ea6d00b65 402 */
ansond 14:3c8d11b48814 403 void resetSalesforceToken();
ansond 8:47db53cd5884 404
ansond 10:845ea6d00b65 405 /**
ansond 10:845ea6d00b65 406 Set our salesforce.com API version
ansond 10:845ea6d00b65 407 @param version integer value (positive)
ansond 10:845ea6d00b65 408 */
ansond 8:47db53cd5884 409 void setSalesforceAPIVersion(int version);
ansond 10:845ea6d00b65 410
ansond 10:845ea6d00b65 411 /**
ansond 10:845ea6d00b65 412 Set our salesforce.com API version
ansond 10:845ea6d00b65 413 @param version string value (format "X.Y")
ansond 10:845ea6d00b65 414 */
ansond 8:47db53cd5884 415 void setSalesforceAPIVersion(char *version);
ansond 10:845ea6d00b65 416
ansond 10:845ea6d00b65 417 /**
ansond 10:845ea6d00b65 418 Get our salesforce.com API version
ansond 10:845ea6d00b65 419 @return string containing our salesforce.com API version or NULL if in error
ansond 10:845ea6d00b65 420 */
ansond 8:47db53cd5884 421 char *getSalesforceAPIVersion();
ansond 8:47db53cd5884 422
ansond 10:845ea6d00b65 423 /**
ansond 14:3c8d11b48814 424 Salesforce.com API SOQL QUERY method to invoke ad-hoc SOQL queries into salesforce.com
ansond 14:3c8d11b48814 425 @param query_str character string with the SOQL query to invoke
ansond 10:845ea6d00b65 426 @param output_buffer allocated result buffer to use
ansond 10:845ea6d00b65 427 @param output_buffer_length allocated result buffer length
ansond 14:3c8d11b48814 428 @return result of the SOQL query in JSON format or NULL if in error
ansond 10:845ea6d00b65 429 */
ansond 8:47db53cd5884 430 char *query(char *query_str,char *output_buffer,int output_buffer_length);
ansond 9:a254fcd904be 431
ansond 10:845ea6d00b65 432 /**
ansond 14:3c8d11b48814 433 Salesforce.com API record creation method to create a new record within a salesforce.com object
ansond 14:3c8d11b48814 434 @param object_name name of the salesforce.com object to create the record in (i.e. "Account")
ansond 14:3c8d11b48814 435 @param record MbedJSONValue json structure that the new record will be comprised with
ansond 10:845ea6d00b65 436 @return MbedJSONValue structure with the results of the creation operation in JSON format
ansond 10:845ea6d00b65 437 */
ansond 14:3c8d11b48814 438 MbedJSONValue createRecord(char *object_name,MbedJSONValue &record);
ansond 9:a254fcd904be 439
ansond 10:845ea6d00b65 440 /**
ansond 14:3c8d11b48814 441 Salesforce.com API record read method to read a record within a salesforce.com object
ansond 14:3c8d11b48814 442 @param object_name name of the salesforce.com object to create the record in (i.e. "Account")
ansond 14:3c8d11b48814 443 @param record_id salesforce.com ID of the record instance to read
ansond 10:845ea6d00b65 444 @return MbedJSONValue structure with the results of the read operation in JSON format
ansond 10:845ea6d00b65 445 */
ansond 14:3c8d11b48814 446 MbedJSONValue readRecord(char *object_name,char *record_id);
ansond 9:a254fcd904be 447
ansond 10:845ea6d00b65 448 /**
ansond 14:3c8d11b48814 449 Salesforce.com API record update method to update a record within a salesforce.com object
ansond 14:3c8d11b48814 450 @param object_name name of the salesforce.com object to create the record in (i.e. "Account")
ansond 14:3c8d11b48814 451 @param record_id salesforce.com ID of the record instance to read
ansond 14:3c8d11b48814 452 @param record MbedJSONValue instance with updated data for the record
ansond 10:845ea6d00b65 453 @return true - success, false - failure
ansond 10:845ea6d00b65 454 */
ansond 14:3c8d11b48814 455 bool updateRecord(char *object_name,char *record_id,MbedJSONValue &record);
ansond 9:a254fcd904be 456
ansond 10:845ea6d00b65 457 /**
ansond 14:3c8d11b48814 458 Salesforce.com API record delete method to delete a record within a salesforce.com object
ansond 14:3c8d11b48814 459 @param object_name name of the salesforce.com object to create the record in (i.e. "Account")
ansond 14:3c8d11b48814 460 @param record_id salesforce.com ID of the record instance to delete
ansond 10:845ea6d00b65 461 @return true - success, false - failure
ansond 10:845ea6d00b65 462 */
ansond 14:3c8d11b48814 463 bool deleteRecord(char *object_name,char *record_id);
ansond 9:a254fcd904be 464
ansond 10:845ea6d00b65 465 /**
ansond 10:845ea6d00b65 466 Salesforce.com API invocation HTTP response code to aid in debugging error conditions
ansond 10:845ea6d00b65 467 @return http response code
ansond 10:845ea6d00b65 468 */
ansond 9:a254fcd904be 469 // HTTP Error code access
ansond 9:a254fcd904be 470 int httpResponseCode();
ansond 9:a254fcd904be 471
ansond 9:a254fcd904be 472 protected:
ansond 9:a254fcd904be 473 // do we have a valid salesforce ID and OAUTH token?
ansond 14:3c8d11b48814 474 bool haveSalesforceToken(bool fetch = true);
ansond 9:a254fcd904be 475
ansond 14:3c8d11b48814 476 // CREATE: a record in Salesforce.com
ansond 14:3c8d11b48814 477 char *createRecord(char *object_name,char *json_data,char *output_buffer,int output_buffer_length);
ansond 9:a254fcd904be 478
ansond 14:3c8d11b48814 479 // READ: a specific record in Salesforce.com
ansond 14:3c8d11b48814 480 char *readRecord(char *object_name,char *record_id,char *output_buffer,int output_buffer_length);
ansond 9:a254fcd904be 481
ansond 14:3c8d11b48814 482 // UPDATE: a specific record in Salesforce.com
ansond 14:3c8d11b48814 483 bool updateRecord(char *object_name,char *record_id,char *json_data);
ansond 9:a254fcd904be 484
ansond 8:47db53cd5884 485 // raw invocation of REST calls into Salesforce.com
ansond 9:a254fcd904be 486 char *invoke(const char *url,char *output_buffer,int output_buffer_length); // defaults to GET
ansond 9:a254fcd904be 487 char *invoke(const char *url,char *output_buffer,int output_buffer_length,HttpVerb verb); // GET or DELETE with simple output
ansond 9:a254fcd904be 488 char *invoke(const char *url,const char *input_data,const int input_data_len,char *output_buffer,int output_buffer_length); // defaults to POST with JSON input data type
ansond 9:a254fcd904be 489 char *invoke(const char *url,const InputDataTypes input_type,const char *input_data,const int input_data_len,char *output_buffer,int output_buffer_length); // defaults to POST with variable input data type
ansond 9:a254fcd904be 490 char *invoke(const char *url,const InputDataTypes input_type,const char *input_data,const int input_data_len,char *output_buffer,int output_buffer_length,const HttpVerb verb); // full fidelity method
ansond 9:a254fcd904be 491
ansond 0:518b1ca956fc 492 // get our OAUTH Token
ansond 9:a254fcd904be 493 void checkAndGetOauthToken(bool fetch = true);
ansond 0:518b1ca956fc 494 char *getOauthToken(char *output_buffer,int output_buffer_length);
ansond 8:47db53cd5884 495
ansond 0:518b1ca956fc 496 // convenience accessors
ansond 0:518b1ca956fc 497 ErrorHandler *logger();
ansond 0:518b1ca956fc 498 HTTPClient *http();
ansond 7:97ea5ef906f7 499 OauthToken *oauth();
ansond 7:97ea5ef906f7 500 HTTPResult httpStatus();
ansond 7:97ea5ef906f7 501
ansond 7:97ea5ef906f7 502 // internal checkers
ansond 0:518b1ca956fc 503 bool haveCreds();
ansond 7:97ea5ef906f7 504 void resetOauthToken();
ansond 7:97ea5ef906f7 505 void fillOauthToken(char *token);
ansond 9:a254fcd904be 506 bool validOauthToken(bool fetch = true);
ansond 8:47db53cd5884 507
ansond 14:3c8d11b48814 508 // get the specified URL from our Salesforce Token
ansond 8:47db53cd5884 509 char *getSalesforceURL(char *key,char *url_buffer,int url_buffer_length);
ansond 9:a254fcd904be 510
ansond 8:47db53cd5884 511 // simple char array replacement (modifies input string!)
ansond 8:47db53cd5884 512 void replace(char *str,char orig_char,char new_char);
ansond 8:47db53cd5884 513
ansond 8:47db53cd5884 514 // needed to replace substrings within std::string
ansond 8:47db53cd5884 515 void replace(string& line, string& oldString, string& newString);
ansond 0:518b1ca956fc 516 };
ansond 0:518b1ca956fc 517
ansond 0:518b1ca956fc 518 #endif // _SALESFORCE_INTERFACE_H_