Class: SalesforceBulk2::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/salesforce_bulk2/client.rb

Overview

Interface for operating the Salesforce Bulk REST API

Constant Summary collapse

@@host =

Defaults

'login.salesforce.com'
@@version =
24.0
@@debugging =
false
@@api_path_prefix =
"/services/async/"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Client

Returns a new instance of Client.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/salesforce_bulk2/client.rb', line 35

def initialize options
  if options.is_a?(String)
    options = YAML.load_file(options)
    options.symbolize_keys!
  end
  
  options.assert_valid_keys(:username, :password, :token, :debugging, :host, :version)
  
  @username = options[:username]
  @password = "#{options[:password]}#{options[:token]}"
  @token    = options[:token] || ''
  @host     = options[:host] || @@host
  @version  = options[:version] || @@version
  @debugging = options[:debugging] || @@debugging

  @jobs = []
end

Instance Attribute Details

#debuggingObject

If true, print API debugging information to stdout. Defaults to false.



5
6
7
# File 'lib/salesforce_bulk2/client.rb', line 5

def debugging
  @debugging
end

#hostObject (readonly)

The host to use for authentication. Defaults to login.salesforce.com.



8
9
10
# File 'lib/salesforce_bulk2/client.rb', line 8

def host
  @host
end

#instance_hostObject (readonly)

The instance host to use for API calls. Determined from login response.



11
12
13
# File 'lib/salesforce_bulk2/client.rb', line 11

def instance_host
  @instance_host
end

#jobsObject

List of jobs associatd with this client



26
27
28
# File 'lib/salesforce_bulk2/client.rb', line 26

def jobs
  @jobs
end

#passwordObject (readonly)

The Salesforce password



14
15
16
# File 'lib/salesforce_bulk2/client.rb', line 14

def password
  @password
end

#tokenObject (readonly)

The Salesforce security token



17
18
19
# File 'lib/salesforce_bulk2/client.rb', line 17

def token
  @token
end

#usernameObject (readonly)

The Salesforce username



20
21
22
# File 'lib/salesforce_bulk2/client.rb', line 20

def username
  @username
end

#versionObject (readonly)

The API version the client is using



23
24
25
# File 'lib/salesforce_bulk2/client.rb', line 23

def version
  @version
end

Instance Method Details

#abort_jobsObject



184
185
186
# File 'lib/salesforce_bulk2/client.rb', line 184

def abort_jobs
  @jobs.map(&:abort)
end

#close_jobsObject



180
181
182
# File 'lib/salesforce_bulk2/client.rb', line 180

def close_jobs
  @jobs.map(&:close)
end

#connect(options = {}) ⇒ Object

Raises:

  • (Error)


53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/salesforce_bulk2/client.rb', line 53

def connect options = {}
  raise Error.new("Already connected") if connected?

  @username = options[:username] || @username
  @password = options[:password] || @password
  @version  = options[:version] || @version

  xml  = '<?xml version="1.0" encoding="utf-8"?>'
  xml += '<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"'
  xml += ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
  xml += ' xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">'
  xml += '  <env:Body>'
  xml += '    <n1:login xmlns:n1="urn:partner.soap.sforce.com">'
  xml += "      <n1:username>#{@username}</n1:username>"
  xml += "      <n1:password>#{@password}</n1:password>"
  xml += "    </n1:login>"
  xml += "  </env:Body>"
  xml += "</env:Envelope>"
  
  data = http_post_xml("/services/Soap/u/#{@version}", xml, 'Content-Type' => 'text/xml', 'SOAPAction' => 'login')
  result = data['Body']['loginResponse']['result']
  
  @session_id = result['sessionId']
  @server_url = result['serverUrl']
  @instance_id = instance_id(@server_url)
  @instance_host = "#{@instance_id}.salesforce.com"
  
  @api_path_prefix = "#{@@api_path_prefix}/#{@version}/"

  result
end

#connected?Boolean

Returns:

  • (Boolean)


106
107
108
# File 'lib/salesforce_bulk2/client.rb', line 106

def connected?
  !!@session_id
end

#delete(sobject, data, batch_size = nil) ⇒ Object

Operations



189
190
191
# File 'lib/salesforce_bulk2/client.rb', line 189

def delete(sobject, data, batch_size = nil)
  perform_operation(:delete, sobject, data, :batch_size => batch_size)
end

#disconnectObject



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/salesforce_bulk2/client.rb', line 85

def disconnect
  xml  = '<?xml version="1.0" encoding="utf-8"?>'
  xml += '<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"'
  xml += ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
  xml += ' xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">'
  xml += '  <env:Body>'
  xml += '    <n1:logout xmlns:n1="urn:partner.soap.sforce.com" />'
  xml += '  </env:Body>'
  xml += '</env:Envelope>'
  
  result = http_post_xml("/services/Soap/u/#{@version}", xml, 'Content-Type' => 'text/xml', 'SOAPAction' => 'logout')

  @session_id = nil
  @server_url = nil
  @instance_id = nil
  @instance_host = nil
  @api_path_prefix = nil

  result
end

#find_job(id) ⇒ Object



174
175
176
177
178
# File 'lib/salesforce_bulk2/client.rb', line 174

def find_job id
  job = Job.find(connection, id)
  @jobs << job
  job
end

#http_get(path, headers = {}) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/salesforce_bulk2/client.rb', line 131

def http_get(path, headers={})
  path = "#{@api_path_prefix}#{path}"
  
  headers = {'Content-Type' => 'application/xml'}.merge(headers)
  
  headers['X-SFDC-Session'] = @session_id if @session_id
  
  response = https_request(@instance_host).get(path, headers)
  
  if response.is_a?(Net::HTTPSuccess)
    response
  else
    raise SalesforceError.new(response)
  end
end

#http_get_xml(path, headers = {}) ⇒ Object



151
152
153
# File 'lib/salesforce_bulk2/client.rb', line 151

def http_get_xml(path, headers = {})
  XmlSimple.xml_in(http_get(path, headers).body, :ForceArray => false)
end

#http_post(path, body, headers = {}) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/salesforce_bulk2/client.rb', line 110

def http_post(path, body, headers={})
  headers = {'Content-Type' => 'application/xml'}.merge(headers)
  
  #Are we connected?
  if connected?
    headers['X-SFDC-Session'] = @session_id
    host = @instance_host
    path = "#{@api_path_prefix}#{path}"
  else
    host = @host
  end

  response = https_request(host).post(path, body, headers)
  
  if response.is_a?(Net::HTTPSuccess)
    response
  else
    raise SalesforceError.new(response)
  end
end

#http_post_xml(path, body, headers = {}) ⇒ Object



147
148
149
# File 'lib/salesforce_bulk2/client.rb', line 147

def http_post_xml(path, body, headers = {})
  XmlSimple.xml_in(http_post(path, body, headers).body, :ForceArray => false)
end

#https_request(host) ⇒ Object



155
156
157
158
159
160
# File 'lib/salesforce_bulk2/client.rb', line 155

def https_request(host)
  req = Net::HTTP.new(host, 443)
  req.use_ssl = true
  req.verify_mode = OpenSSL::SSL::VERIFY_NONE
  req
end

#insert(sobject, data, batch_size = nil) ⇒ Object



193
194
195
# File 'lib/salesforce_bulk2/client.rb', line 193

def insert(sobject, data, batch_size = nil)
  perform_operation(:insert, sobject, data, :batch_size => batch_size)
end

#instance_id(url) ⇒ Object



162
163
164
# File 'lib/salesforce_bulk2/client.rb', line 162

def instance_id(url)
  url.match(/:\/\/([a-zA-Z0-9-]{2,}).salesforce/)[1]
end

#new_job(options = {}) ⇒ Object

Job related



168
169
170
171
172
# File 'lib/salesforce_bulk2/client.rb', line 168

def new_job options = {}
  job = Job.create(self, options)
  @jobs << job
  job
end

#perform_operation(operation, sobject, data, options = {}) ⇒ Object



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/salesforce_bulk2/client.rb', line 209

def perform_operation(operation, sobject, data, options = {})
  job = new_job(operation: operation, object: sobject, :external_id => options[:external_id])

  if data.is_a?(Array)
    job.add_data(data, options[:batch_size])
  else
    job.new_batch(data)
  end

  job.close
  
  until job.finished?
    job.refresh
    sleep 2
  end
  
  return job.get_results
end

#query(sobject, query, batch_size = nil) ⇒ Object



197
198
199
# File 'lib/salesforce_bulk2/client.rb', line 197

def query(sobject, query, batch_size = nil)
  perform_operation(:query, sobject, query, :batch_size => batch_size)
end

#update(sobject, data, batch_size = nil) ⇒ Object



201
202
203
# File 'lib/salesforce_bulk2/client.rb', line 201

def update(sobject, data, batch_size = nil)
  perform_operation(:update, sobject, data, :batch_size => batch_size)
end

#upsert(sobject, data, external_id, batch_size = nil) ⇒ Object



205
206
207
# File 'lib/salesforce_bulk2/client.rb', line 205

def upsert(sobject, data, external_id, batch_size = nil)
  perform_operation(:upsert, sobject, data, :external_id => external_id, :batch_size => batch_size)
end