logstash-input-salesforce 3.2.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +50 -9
- data/docs/index.asciidoc +143 -32
- data/lib/logstash/inputs/salesforce.rb +125 -26
- data/logstash-input-salesforce.gemspec +2 -2
- data/spec/fixtures/vcr_cassettes/load_some_lead_objects_order_by_lastmodifieddate.yml +124 -0
- data/spec/fixtures/vcr_cassettes/load_some_lead_objects_twice.yml +161 -0
- data/spec/fixtures/vcr_cassettes/load_some_lead_objects_with_lastmodifieddate_filter.yml +123 -0
- data/spec/fixtures/vcr_cassettes/load_some_lead_objects_with_lastmodifieddate_filter_order_by_lastmodifieddate.yml +123 -0
- data/spec/fixtures/vcr_cassettes/load_some_lead_objects_with_lastmodifieddate_filter_order_by_lastmodifieddate_no_filters.yml +123 -0
- data/spec/inputs/salesforce_spec.rb +285 -25
- metadata +30 -24
- data/DEVELOPER.md +0 -2
@@ -0,0 +1,123 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://login.salesforce.com/services/oauth2/token
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: grant_type=password&client_id=xxxx&client_secret=xxxx&username=xxxx&password=xxxx
|
9
|
+
headers:
|
10
|
+
User-Agent:
|
11
|
+
- Faraday v0.9.1
|
12
|
+
Content-Type:
|
13
|
+
- application/x-www-form-urlencoded
|
14
|
+
Accept:
|
15
|
+
- '*/*'
|
16
|
+
response:
|
17
|
+
status:
|
18
|
+
code: 200
|
19
|
+
message: OK
|
20
|
+
headers:
|
21
|
+
Date:
|
22
|
+
- Thu, 27 Aug 2015 23:57:42 GMT
|
23
|
+
Set-Cookie:
|
24
|
+
- BrowserId=xxxx;Path=/;Domain=.salesforce.com;Expires=Mon, 26-Oct-2015 23:57:42 GMT
|
25
|
+
Expires:
|
26
|
+
- Thu, 01 Jan 1970 00:00:00 GMT
|
27
|
+
Pragma:
|
28
|
+
- no-cache
|
29
|
+
Cache-Control:
|
30
|
+
- no-cache, no-store
|
31
|
+
Content-Type:
|
32
|
+
- application/json;charset=UTF-8
|
33
|
+
Transfer-Encoding:
|
34
|
+
- chunked
|
35
|
+
body:
|
36
|
+
encoding: US-ASCII
|
37
|
+
string: '{"id":"https://login.salesforce.com/id/xxxx/xxxx","issued_at":"1440719862904","token_type":"Bearer","instance_url":"https://eu2.salesforce.com","signature":"xxxx","access_token":"xxxx"}'
|
38
|
+
http_version:
|
39
|
+
recorded_at: Thu, 27 Aug 2015 23:57:43 GMT
|
40
|
+
- request:
|
41
|
+
method: get
|
42
|
+
uri: https://eu2.salesforce.com/services/data/v26.0/sobjects/Lead/describe
|
43
|
+
body:
|
44
|
+
encoding: US-ASCII
|
45
|
+
string: ''
|
46
|
+
headers:
|
47
|
+
User-Agent:
|
48
|
+
- Faraday v0.9.1
|
49
|
+
Authorization:
|
50
|
+
- OAuth xxxx
|
51
|
+
Accept-Encoding:
|
52
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
53
|
+
Accept:
|
54
|
+
- '*/*'
|
55
|
+
response:
|
56
|
+
status:
|
57
|
+
code: 200
|
58
|
+
message: OK
|
59
|
+
headers:
|
60
|
+
Date:
|
61
|
+
- Thu, 27 Aug 2015 23:57:44 GMT
|
62
|
+
Set-Cookie:
|
63
|
+
- BrowserId=xxxx;Path=/;Domain=.salesforce.com;Expires=Mon, 26-Oct-2015 23:57:44 GMT
|
64
|
+
Expires:
|
65
|
+
- Thu, 01 Jan 1970 00:00:00 GMT
|
66
|
+
Sforce-Limit-Info:
|
67
|
+
- api-usage=211068/451000
|
68
|
+
Org.eclipse.jetty.server.include.etag:
|
69
|
+
- 5fb54cb6
|
70
|
+
Last-Modified:
|
71
|
+
- Thu, 27 Aug 2015 22:36:55 GMT
|
72
|
+
Content-Type:
|
73
|
+
- application/json;charset=UTF-8
|
74
|
+
Etag:
|
75
|
+
- 5fb54cb-gzip"
|
76
|
+
Transfer-Encoding:
|
77
|
+
- chunked
|
78
|
+
body:
|
79
|
+
encoding: UTF-8
|
80
|
+
string: '{"activateable":false,"childRelationships":[],"createable":true,"custom":false,"customSetting":false,"deletable":true,"deprecatedAndHidden":false,"feedEnabled":true,"fields":[{"autoNumber":false,"byteLength":18,"calculated":false,"calculatedFormula":null,"cascadeDelete":false,"caseSensitive":false,"controllerName":null,"createable":false,"custom":false,"defaultValue":null,"defaultValueFormula":null,"defaultedOnCreate":true,"dependentPicklist":false,"deprecatedAndHidden":false,"digits":0,"displayLocationInDecimal":false,"externalId":false,"filterable":true,"groupable":true,"htmlFormatted":false,"idLookup":true,"inlineHelpText":null,"label":"Lead
|
81
|
+
ID","length":18,"name":"Id","nameField":false,"namePointing":false,"nillable":false,"permissionable":false,"picklistValues":[],"precision":0,"referenceTo":[],"relationshipName":null,"relationshipOrder":null,"restrictedDelete":false,"restrictedPicklist":false,"scale":0,"soapType":"tns:ID","sortable":true,"type":"id","unique":false,"updateable":false,"writeRequiresMasterRead":false},{"autoNumber":false,"byteLength":0,"calculated":false,"calculatedFormula":null,"cascadeDelete":false,"caseSensitive":false,"controllerName":null,"createable":false,"custom":false,"defaultValue":null,"defaultValueFormula":null,"defaultedOnCreate":true,"dependentPicklist":false,"deprecatedAndHidden":false,"digits":0,"displayLocationInDecimal":false,"externalId":false,"filterable":true,"groupable":true,"htmlFormatted":false,"idLookup":false,"inlineHelpText":null,"label":"Deleted","length":0,"name":"IsDeleted","nameField":false,"namePointing":false,"nillable":false,"permissionable":false,"picklistValues":[],"precision":0,"referenceTo":[],"relationshipName":null,"relationshipOrder":null,"restrictedDelete":false,"restrictedPicklist":false,"scale":0,"soapType":"xsd:boolean","sortable":true,"type":"boolean","unique":false,"updateable":false,"writeRequiresMasterRead":false},{"autoNumber":false,"byteLength":240,"calculated":false,"calculatedFormula":null,"cascadeDelete":false,"caseSensitive":false,"controllerName":null,"createable":true,"custom":false,"defaultValue":null,"defaultValueFormula":null,"defaultedOnCreate":false,"dependentPicklist":false,"deprecatedAndHidden":false,"digits":0,"displayLocationInDecimal":false,"externalId":false,"filterable":true,"groupable":true,"htmlFormatted":false,"idLookup":false,"inlineHelpText":null,"label":"Last
|
82
|
+
Name","length":80,"name":"LastName","nameField":false,"namePointing":false,"nillable":false,"permissionable":false,"picklistValues":[],"precision":0,"referenceTo":[],"relationshipName":null,"relationshipOrder":null,"restrictedDelete":false,"restrictedPicklist":false,"scale":0,"soapType":"xsd:string","sortable":true,"type":"string","unique":false,"updateable":true,"writeRequiresMasterRead":false},{"autoNumber":false,"byteLength":120,"calculated":false,"calculatedFormula":null,"cascadeDelete":false,"caseSensitive":false,"controllerName":null,"createable":true,"custom":false,"defaultValue":null,"defaultValueFormula":null,"defaultedOnCreate":false,"dependentPicklist":false,"deprecatedAndHidden":false,"digits":0,"displayLocationInDecimal":false,"externalId":false,"filterable":true,"groupable":true,"htmlFormatted":false,"idLookup":false,"inlineHelpText":null,"label":"First
|
83
|
+
Name","length":40,"name":"FirstName","nameField":false,"namePointing":false,"nillable":true,"permissionable":false,"picklistValues":[],"precision":0,"referenceTo":[],"relationshipName":null,"relationshipOrder":null,"restrictedDelete":false,"restrictedPicklist":false,"scale":0,"soapType":"xsd:string","sortable":true,"type":"string","unique":false,"updateable":true,"writeRequiresMasterRead":false},{"autoNumber":false,"byteLength":120,"calculated":false,"calculatedFormula":null,"cascadeDelete":false,"caseSensitive":false,"controllerName":null,"createable":true,"custom":false,"defaultValue":null,"defaultValueFormula":null,"defaultedOnCreate":false,"dependentPicklist":false,"deprecatedAndHidden":false,"digits":0,"displayLocationInDecimal":false,"externalId":false,"filterable":true,"groupable":true,"htmlFormatted":false,"idLookup":false,"inlineHelpText":null,"label":"Salutation","length":40,"name":"Salutation","nameField":false,"namePointing":false,"nillable":true,"permissionable":false,"picklistValues":[{"active":true,"defaultValue":false,"label":"Mr.","validFor":null,"value":"Mr."},{"active":true,"defaultValue":false,"label":"Ms.","validFor":null,"value":"Ms."},{"active":true,"defaultValue":false,"label":"Mrs.","validFor":null,"value":"Mrs."},{"active":true,"defaultValue":false,"label":"Dr.","validFor":null,"value":"Dr."},{"active":true,"defaultValue":false,"label":"Prof.","validFor":null,"value":"Prof."}],"precision":0,"referenceTo":[],"relationshipName":null,"relationshipOrder":null,"restrictedDelete":false,"restrictedPicklist":false,"scale":0,"soapType":"xsd:string","sortable":true,"type":"picklist","unique":false,"updateable":true,"writeRequiresMasterRead":false}],"keyPrefix":"00Q","label":"Lead","labelPlural":"Leads","layoutable":true,"listviewable":null,"lookupLayoutable":null,"mergeable":true,"name":"Lead","queryable":true,"recordTypeInfos":[{"available":true,"defaultRecordTypeMapping":true,"name":"Marketing","recordTypeId":"xxxx"},{"available":true,"defaultRecordTypeMapping":false,"name":"Partner
|
84
|
+
Deal","recordTypeId":"xxxx"},{"available":true,"defaultRecordTypeMapping":false,"name":"Sales","recordTypeId":"xxxx"},{"available":true,"defaultRecordTypeMapping":false,"name":"Master","recordTypeId":"xxxx"}],"replicateable":true,"retrieveable":true,"searchLayoutable":null,"searchable":true,"triggerable":true,"undeletable":true,"updateable":true,"urls":{"uiEditTemplate":"https://xxx.salesforce.com/{ID}/e","sobject":"/services/data/v26.0/sobjects/Lead","uiDetailTemplate":"https://xxx.salesforce.com/{ID}","describe":"/services/data/v26.0/sobjects/Lead/describe","rowTemplate":"/services/data/v26.0/sobjects/Lead/{ID}","uiNewRecord":"https://xxx.salesforce.com/00Q/e"}}'
|
85
|
+
http_version:
|
86
|
+
recorded_at: Thu, 27 Aug 2015 23:57:44 GMT
|
87
|
+
- request:
|
88
|
+
method: get
|
89
|
+
uri: https://eu2.salesforce.com/services/data/v26.0/query?q=SELECT%20Id,IsDeleted,LastName,FirstName,Salutation,LastModifiedDate%20FROM%20Lead%20WHERE%20LastModifiedDate%20%3E%202025-05-07T14:32:17Z%20ORDER%20BY%20LastModifiedDate%20ASC
|
90
|
+
body:
|
91
|
+
encoding: US-ASCII
|
92
|
+
string: ''
|
93
|
+
headers:
|
94
|
+
User-Agent:
|
95
|
+
- Faraday v0.9.1
|
96
|
+
Authorization:
|
97
|
+
- OAuth xxx
|
98
|
+
Accept-Encoding:
|
99
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
100
|
+
Accept:
|
101
|
+
- '*/*'
|
102
|
+
response:
|
103
|
+
status:
|
104
|
+
code: 200
|
105
|
+
message: OK
|
106
|
+
headers:
|
107
|
+
Date:
|
108
|
+
- Thu, 27 Aug 2015 23:57:45 GMT
|
109
|
+
Set-Cookie:
|
110
|
+
- BrowserId=xxxx;Path=/;Domain=.salesforce.com;Expires=Mon, 26-Oct-2015 23:57:45 GMT
|
111
|
+
Expires:
|
112
|
+
- Thu, 01 Jan 1970 00:00:00 GMT
|
113
|
+
Sforce-Limit-Info:
|
114
|
+
- api-usage=211063/451000
|
115
|
+
Content-Type:
|
116
|
+
- application/json;charset=UTF-8
|
117
|
+
Transfer-Encoding:
|
118
|
+
- chunked
|
119
|
+
body:
|
120
|
+
encoding: UTF-8
|
121
|
+
string: '{"totalSize":3,"done":true,"records":[{"attributes":{"type":"Lead","url":"/services/data/v26.0/sobjects/Lead/xxxx"},"Id":"xxxx","IsDeleted":false,"LastName":"Katz","FirstName":"Aaron","Salutation":"Mr."},{"attributes":{"type":"Lead","url":"/services/data/v26.0/sobjects/Lead/xxxx"},"Id":"xxxx","IsDeleted":false,"LastName":"Grand","FirstName":"Adrien","Salutation":"Dr."},{"attributes":{"type":"Lead","url":"/services/data/v26.0/sobjects/Lead/xxxx"},"Id":"xxxx","IsDeleted":false,"LastName":"Hardy","FirstName":"Alan","Salutation":"Overlord"}]}'
|
122
|
+
http_version:
|
123
|
+
recorded_at: Thu, 27 Aug 2015 23:57:45 GMT
|
@@ -8,10 +8,10 @@ RSpec.describe LogStash::Inputs::Salesforce do
|
|
8
8
|
let(:options) do
|
9
9
|
{
|
10
10
|
"client_id" => "",
|
11
|
-
"client_secret" => "",
|
11
|
+
"client_secret" => ::LogStash::Util::Password.new("secret-key"),
|
12
12
|
"username" => "",
|
13
|
-
"password" => "",
|
14
|
-
"security_token" => "",
|
13
|
+
"password" => ::LogStash::Util::Password.new("secret-password"),
|
14
|
+
"security_token" => ::LogStash::Util::Password.new("secret-token"),
|
15
15
|
"sfdc_object_name" => ""
|
16
16
|
}
|
17
17
|
end
|
@@ -35,10 +35,10 @@ RSpec.describe LogStash::Inputs::Salesforce do
|
|
35
35
|
let(:options) do
|
36
36
|
{
|
37
37
|
"client_id" => "",
|
38
|
-
"client_secret" => "",
|
38
|
+
"client_secret" => ::LogStash::Util::Password.new("secret-key"),
|
39
39
|
"username" => "",
|
40
|
-
"password" => "",
|
41
|
-
"security_token" => "",
|
40
|
+
"password" => ::LogStash::Util::Password.new("secret-password"),
|
41
|
+
"security_token" => ::LogStash::Util::Password.new("secret-token"),
|
42
42
|
"sfdc_object_name" => "Lead",
|
43
43
|
"sfdc_fields" => ["Something"]
|
44
44
|
}
|
@@ -67,10 +67,10 @@ RSpec.describe LogStash::Inputs::Salesforce do
|
|
67
67
|
let(:options) do
|
68
68
|
{
|
69
69
|
"client_id" => "",
|
70
|
-
"client_secret" => "",
|
70
|
+
"client_secret" => ::LogStash::Util::Password.new("secret-key"),
|
71
71
|
"username" => "",
|
72
|
-
"password" => "",
|
73
|
-
"security_token" => "",
|
72
|
+
"password" => ::LogStash::Util::Password.new("secret-password"),
|
73
|
+
"security_token" => ::LogStash::Util::Password.new("secret-token"),
|
74
74
|
"sfdc_object_name" => "Lead"
|
75
75
|
}
|
76
76
|
end
|
@@ -84,7 +84,7 @@ RSpec.describe LogStash::Inputs::Salesforce do
|
|
84
84
|
["Salutation", "picklist"]] }
|
85
85
|
subject { input }
|
86
86
|
it "loads the Lead object fields" do
|
87
|
-
VCR.use_cassette("
|
87
|
+
VCR.use_cassette("describe lead object",:decode_compressed_response => true) do
|
88
88
|
subject.register
|
89
89
|
expect(subject.instance_variable_get(:@sfdc_field_types)).to match_array(expected_types_result)
|
90
90
|
expect(subject.instance_variable_get(:@sfdc_fields)).to match_array(expected_fields_result)
|
@@ -94,10 +94,10 @@ RSpec.describe LogStash::Inputs::Salesforce do
|
|
94
94
|
let(:options) do
|
95
95
|
{
|
96
96
|
"client_id" => "",
|
97
|
-
"client_secret" => "",
|
97
|
+
"client_secret" => ::LogStash::Util::Password.new("secret-key"),
|
98
98
|
"username" => "",
|
99
|
-
"password" => "",
|
100
|
-
"security_token" => "",
|
99
|
+
"password" => ::LogStash::Util::Password.new("secret-password"),
|
100
|
+
"security_token" => ::LogStash::Util::Password.new("secret-token"),
|
101
101
|
"sfdc_object_name" => "Lead",
|
102
102
|
"sfdc_fields" => ["Id", "IsDeleted", "LastName", "FirstName", "Salutation"],
|
103
103
|
"sfdc_filters" => "Email LIKE '%@elastic.co'"
|
@@ -107,7 +107,7 @@ RSpec.describe LogStash::Inputs::Salesforce do
|
|
107
107
|
subject { input }
|
108
108
|
let(:queue) { [] }
|
109
109
|
it "loads some lead records" do
|
110
|
-
VCR.use_cassette("load some lead objects"
|
110
|
+
VCR.use_cassette("load some lead objects", :decode_compressed_response => true) do
|
111
111
|
subject.register
|
112
112
|
subject.run(queue)
|
113
113
|
expect(queue.length).to eq(3)
|
@@ -137,10 +137,10 @@ RSpec.describe LogStash::Inputs::Salesforce do
|
|
137
137
|
let(:options) do
|
138
138
|
{
|
139
139
|
"client_id" => "",
|
140
|
-
"client_secret" => "",
|
140
|
+
"client_secret" => ::LogStash::Util::Password.new("secret-key"),
|
141
141
|
"username" => "",
|
142
|
-
"password" => "",
|
143
|
-
"security_token" => "",
|
142
|
+
"password" => ::LogStash::Util::Password.new("secret-password"),
|
143
|
+
"security_token" => ::LogStash::Util::Password.new("secret-token"),
|
144
144
|
"sfdc_instance_url" => "my-domain.my.salesforce.com",
|
145
145
|
"sfdc_object_name" => "Lead"
|
146
146
|
}
|
@@ -155,7 +155,7 @@ RSpec.describe LogStash::Inputs::Salesforce do
|
|
155
155
|
["Salutation", "picklist"]] }
|
156
156
|
subject { input }
|
157
157
|
it "logs into sfdc instance url" do
|
158
|
-
VCR.use_cassette("
|
158
|
+
VCR.use_cassette("login into mydomain", :decode_compressed_response => true) do
|
159
159
|
subject.register
|
160
160
|
expect(subject.instance_variable_get(:@sfdc_field_types)).to match_array(expected_types_result)
|
161
161
|
expect(subject.instance_variable_get(:@sfdc_fields)).to match_array(expected_fields_result)
|
@@ -165,10 +165,10 @@ RSpec.describe LogStash::Inputs::Salesforce do
|
|
165
165
|
let(:options) do
|
166
166
|
{
|
167
167
|
"client_id" => "",
|
168
|
-
"client_secret" => "",
|
168
|
+
"client_secret" => ::LogStash::Util::Password.new("secret-key"),
|
169
169
|
"username" => "",
|
170
|
-
"password" => "",
|
171
|
-
"security_token" => "",
|
170
|
+
"password" => ::LogStash::Util::Password.new("secret-password"),
|
171
|
+
"security_token" => ::LogStash::Util::Password.new("secret-token"),
|
172
172
|
"sfdc_instance_url" => "my-domain.my.salesforce.com",
|
173
173
|
"sfdc_object_name" => "Lead",
|
174
174
|
"use_test_sandbox" => true
|
@@ -200,10 +200,10 @@ RSpec.describe LogStash::Inputs::Salesforce do
|
|
200
200
|
{
|
201
201
|
"api_version" => "52.0",
|
202
202
|
"client_id" => "",
|
203
|
-
"client_secret" => "",
|
203
|
+
"client_secret" => ::LogStash::Util::Password.new("secret-key"),
|
204
204
|
"username" => "",
|
205
|
-
"password" => "",
|
206
|
-
"security_token" => "",
|
205
|
+
"password" => ::LogStash::Util::Password.new("secret-password"),
|
206
|
+
"security_token" => ::LogStash::Util::Password.new("secret-token"),
|
207
207
|
"use_tooling_api" => true,
|
208
208
|
"sfdc_object_name" => "ApexTestRunResult"
|
209
209
|
}
|
@@ -211,11 +211,271 @@ RSpec.describe LogStash::Inputs::Salesforce do
|
|
211
211
|
let(:input) { LogStash::Inputs::Salesforce.new(options) }
|
212
212
|
subject { input }
|
213
213
|
it "should use the Tooling Api Query resource path" do
|
214
|
-
VCR.use_cassette("
|
214
|
+
VCR.use_cassette("describe apex test run result object", :decode_compressed_response => true) do
|
215
215
|
subject.register
|
216
216
|
expect(subject.send(:client).send(:api_path, "query")).to eq('/services/data/v52.0/tooling/query')
|
217
217
|
end
|
218
218
|
end
|
219
219
|
end
|
220
|
+
|
221
|
+
context "run continuously at interval" do
|
222
|
+
VCR.configure do |config|
|
223
|
+
config.cassette_library_dir = File.join(File.dirname(__FILE__), '..', 'fixtures', 'vcr_cassettes')
|
224
|
+
config.hook_into :webmock
|
225
|
+
config.before_record do |i|
|
226
|
+
if i.response.body.encoding.to_s == 'ASCII-8BIT'
|
227
|
+
# required because sfdc doesn't send back the content encoding and it
|
228
|
+
# confuses the yaml parser
|
229
|
+
json_body = JSON.load(i.response.body.encode("ASCII-8BIT").force_encoding("utf-8"))
|
230
|
+
i.response.body = json_body.to_json
|
231
|
+
i.response.update_content_length_header
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
let(:options) do
|
236
|
+
{
|
237
|
+
"client_id" => "",
|
238
|
+
"client_secret" => ::LogStash::Util::Password.new("secret-key"),
|
239
|
+
"username" => "",
|
240
|
+
"password" => ::LogStash::Util::Password.new("secret-password"),
|
241
|
+
"security_token" => ::LogStash::Util::Password.new("secret-token"),
|
242
|
+
"use_tooling_api" => false,
|
243
|
+
"sfdc_object_name" => "Lead",
|
244
|
+
"sfdc_fields" => ["Id", "IsDeleted", "LastName", "FirstName", "Salutation"],
|
245
|
+
"sfdc_filters" => "Email LIKE '%@elastic.co'",
|
246
|
+
"interval" => 3
|
247
|
+
}
|
248
|
+
end
|
249
|
+
let(:input) { LogStash::Inputs::Salesforce.new(options) }
|
250
|
+
subject { input }
|
251
|
+
let(:queue) { [] }
|
252
|
+
it "loads some lead records" do
|
253
|
+
VCR.use_cassette("load some lead objects twice", :decode_compressed_response => true) do
|
254
|
+
subject.register
|
255
|
+
# Run a background thread to set the stop flag after 7 seconds, i.e. after the second run of the plugin
|
256
|
+
thr = Thread.new {
|
257
|
+
sleep(4) # more than 3, less than 6
|
258
|
+
subject.do_stop
|
259
|
+
}
|
260
|
+
subject.run(queue)
|
261
|
+
thr.join
|
262
|
+
expect(queue.length).to eq(8) # 3 + 5
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
context "run with last modified time from range field file" do
|
268
|
+
VCR.configure do |config|
|
269
|
+
config.cassette_library_dir = File.join(File.dirname(__FILE__), '..', 'fixtures', 'vcr_cassettes')
|
270
|
+
config.hook_into :webmock
|
271
|
+
config.before_record do |i|
|
272
|
+
if i.response.body.encoding.to_s == 'ASCII-8BIT'
|
273
|
+
# required because sfdc doesn't send back the content encoding and it
|
274
|
+
# confuses the yaml parser
|
275
|
+
json_body = JSON.load(i.response.body.encode("ASCII-8BIT").force_encoding("utf-8"))
|
276
|
+
i.response.body = json_body.to_json
|
277
|
+
i.response.update_content_length_header
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
let(:options) do
|
282
|
+
{
|
283
|
+
"client_id" => "",
|
284
|
+
"client_secret" => ::LogStash::Util::Password.new("secret-key"),
|
285
|
+
"username" => "",
|
286
|
+
"password" => ::LogStash::Util::Password.new("secret-password"),
|
287
|
+
"security_token" => ::LogStash::Util::Password.new("secret-token"),
|
288
|
+
"use_tooling_api" => false,
|
289
|
+
"sfdc_object_name" => "Lead",
|
290
|
+
"sfdc_fields" => ["Id", "IsDeleted", "LastName", "FirstName", "Salutation"],
|
291
|
+
"sfdc_filters" => "Email LIKE '%@elastic.co'",
|
292
|
+
"changed_data_filter" => "LastModifiedDate > %{last_tracking_field_value}",
|
293
|
+
"tracking_field_value_file" => "last_tracking_field_value.txt"
|
294
|
+
}
|
295
|
+
end
|
296
|
+
let(:input) { LogStash::Inputs::Salesforce.new(options) }
|
297
|
+
subject { input }
|
298
|
+
let(:queue) { [] }
|
299
|
+
it "loads some lead records modified after 2025-05-07 14:32:17 UTC" do
|
300
|
+
VCR.use_cassette("load some lead objects with lastmodifieddate filter", :decode_compressed_response => true) do
|
301
|
+
subject.register
|
302
|
+
File.write("last_tracking_field_value.txt", "2025-05-07T14:32:17Z")
|
303
|
+
subject.run(queue)
|
304
|
+
expect(queue.length).to eq(3)
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
context "run with last modified time from range field file when file doesn't yet exist" do
|
310
|
+
VCR.configure do |config|
|
311
|
+
config.cassette_library_dir = File.join(File.dirname(__FILE__), '..', 'fixtures', 'vcr_cassettes')
|
312
|
+
config.hook_into :webmock
|
313
|
+
config.before_record do |i|
|
314
|
+
if i.response.body.encoding.to_s == 'ASCII-8BIT'
|
315
|
+
# required because sfdc doesn't send back the content encoding and it
|
316
|
+
# confuses the yaml parser
|
317
|
+
json_body = JSON.load(i.response.body.encode("ASCII-8BIT").force_encoding("utf-8"))
|
318
|
+
i.response.body = json_body.to_json
|
319
|
+
i.response.update_content_length_header
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
let(:options) do
|
324
|
+
{
|
325
|
+
"client_id" => "",
|
326
|
+
"client_secret" => ::LogStash::Util::Password.new("secret-key"),
|
327
|
+
"username" => "",
|
328
|
+
"password" => ::LogStash::Util::Password.new("secret-password"),
|
329
|
+
"security_token" => ::LogStash::Util::Password.new("secret-token"),
|
330
|
+
"use_tooling_api" => false,
|
331
|
+
"sfdc_object_name" => "Lead",
|
332
|
+
"sfdc_fields" => ["Id", "IsDeleted", "LastName", "FirstName", "Salutation"],
|
333
|
+
"sfdc_filters" => "Email LIKE '%@elastic.co'",
|
334
|
+
"changed_data_filter" => "LastModifiedDate > %{last_tracking_field_value}",
|
335
|
+
"tracking_field_value_file" => "last_tracking_field_value.txt"
|
336
|
+
}
|
337
|
+
end
|
338
|
+
let(:input) { LogStash::Inputs::Salesforce.new(options) }
|
339
|
+
subject { input }
|
340
|
+
let(:queue) { [] }
|
341
|
+
it "loads some lead records" do
|
342
|
+
VCR.use_cassette("load some lead objects", :decode_compressed_response => true) do
|
343
|
+
subject.register
|
344
|
+
File.exist?("last_tracking_field_value.txt") && File.delete("last_tracking_field_value.txt")
|
345
|
+
subject.run(queue)
|
346
|
+
expect(queue.length).to eq(3)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
context "run with last modified time from range field file with range field" do
|
352
|
+
VCR.configure do |config|
|
353
|
+
config.cassette_library_dir = File.join(File.dirname(__FILE__), '..', 'fixtures', 'vcr_cassettes')
|
354
|
+
config.hook_into :webmock
|
355
|
+
config.before_record do |i|
|
356
|
+
if i.response.body.encoding.to_s == 'ASCII-8BIT'
|
357
|
+
# required because sfdc doesn't send back the content encoding and it
|
358
|
+
# confuses the yaml parser
|
359
|
+
json_body = JSON.load(i.response.body.encode("ASCII-8BIT").force_encoding("utf-8"))
|
360
|
+
i.response.body = json_body.to_json
|
361
|
+
i.response.update_content_length_header
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|
365
|
+
let(:options) do
|
366
|
+
{
|
367
|
+
"client_id" => "",
|
368
|
+
"client_secret" => ::LogStash::Util::Password.new("secret-key"),
|
369
|
+
"username" => "",
|
370
|
+
"password" => ::LogStash::Util::Password.new("secret-password"),
|
371
|
+
"security_token" => ::LogStash::Util::Password.new("secret-token"),
|
372
|
+
"use_tooling_api" => false,
|
373
|
+
"sfdc_object_name" => "Lead",
|
374
|
+
"sfdc_fields" => ["Id", "IsDeleted", "LastName", "FirstName", "Salutation"],
|
375
|
+
"sfdc_filters" => "Email LIKE '%@elastic.co'",
|
376
|
+
"tracking_field" => "LastModifiedDate",
|
377
|
+
"changed_data_filter" => "LastModifiedDate > %{last_tracking_field_value}",
|
378
|
+
"tracking_field_value_file" => "last_tracking_field_value.txt"
|
379
|
+
}
|
380
|
+
end
|
381
|
+
let(:input) { LogStash::Inputs::Salesforce.new(options) }
|
382
|
+
subject { input }
|
383
|
+
let(:queue) { [] }
|
384
|
+
it "loads some lead records modified after 2025-05-07 14:32:17 UTC" do
|
385
|
+
VCR.use_cassette("load some lead objects with lastmodifieddate filter order by lastmodifieddate", :decode_compressed_response => true) do
|
386
|
+
subject.register
|
387
|
+
File.write("last_tracking_field_value.txt", "2025-05-07T14:32:17Z")
|
388
|
+
subject.run(queue)
|
389
|
+
expect(queue.length).to eq(3)
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
context "run with last modified time from range field file with range field and no other filters" do
|
395
|
+
VCR.configure do |config|
|
396
|
+
config.cassette_library_dir = File.join(File.dirname(__FILE__), '..', 'fixtures', 'vcr_cassettes')
|
397
|
+
config.hook_into :webmock
|
398
|
+
config.before_record do |i|
|
399
|
+
if i.response.body.encoding.to_s == 'ASCII-8BIT'
|
400
|
+
# required because sfdc doesn't send back the content encoding and it
|
401
|
+
# confuses the yaml parser
|
402
|
+
json_body = JSON.load(i.response.body.encode("ASCII-8BIT").force_encoding("utf-8"))
|
403
|
+
i.response.body = json_body.to_json
|
404
|
+
i.response.update_content_length_header
|
405
|
+
end
|
406
|
+
end
|
407
|
+
end
|
408
|
+
let(:options) do
|
409
|
+
{
|
410
|
+
"client_id" => "",
|
411
|
+
"client_secret" => ::LogStash::Util::Password.new("secret-key"),
|
412
|
+
"username" => "",
|
413
|
+
"password" => ::LogStash::Util::Password.new("secret-password"),
|
414
|
+
"security_token" => ::LogStash::Util::Password.new("secret-token"),
|
415
|
+
"use_tooling_api" => false,
|
416
|
+
"sfdc_object_name" => "Lead",
|
417
|
+
"sfdc_fields" => ["Id", "IsDeleted", "LastName", "FirstName", "Salutation"],
|
418
|
+
"tracking_field" => "LastModifiedDate",
|
419
|
+
"changed_data_filter" => "LastModifiedDate > %{last_tracking_field_value}",
|
420
|
+
"tracking_field_value_file" => "last_tracking_field_value.txt"
|
421
|
+
}
|
422
|
+
end
|
423
|
+
let(:input) { LogStash::Inputs::Salesforce.new(options) }
|
424
|
+
subject { input }
|
425
|
+
let(:queue) { [] }
|
426
|
+
it "loads some lead records modified after 2025-05-07 14:32:17 UTC" do
|
427
|
+
VCR.use_cassette("load some lead objects with lastmodifieddate filter order by lastmodifieddate no filters", :decode_compressed_response => true) do
|
428
|
+
subject.register
|
429
|
+
File.write("last_tracking_field_value.txt", "2025-05-07T14:32:17Z")
|
430
|
+
subject.run(queue)
|
431
|
+
expect(queue.length).to eq(3)
|
432
|
+
end
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
context "run with last modified time from range field file when file doesn't yet exist with range field" do
|
437
|
+
VCR.configure do |config|
|
438
|
+
config.cassette_library_dir = File.join(File.dirname(__FILE__), '..', 'fixtures', 'vcr_cassettes')
|
439
|
+
config.hook_into :webmock
|
440
|
+
config.before_record do |i|
|
441
|
+
if i.response.body.encoding.to_s == 'ASCII-8BIT'
|
442
|
+
# required because sfdc doesn't send back the content encoding and it
|
443
|
+
# confuses the yaml parser
|
444
|
+
json_body = JSON.load(i.response.body.encode("ASCII-8BIT").force_encoding("utf-8"))
|
445
|
+
i.response.body = json_body.to_json
|
446
|
+
i.response.update_content_length_header
|
447
|
+
end
|
448
|
+
end
|
449
|
+
end
|
450
|
+
let(:options) do
|
451
|
+
{
|
452
|
+
"client_id" => "",
|
453
|
+
"client_secret" => ::LogStash::Util::Password.new("secret-key"),
|
454
|
+
"username" => "",
|
455
|
+
"password" => ::LogStash::Util::Password.new("secret-password"),
|
456
|
+
"security_token" => ::LogStash::Util::Password.new("secret-token"),
|
457
|
+
"use_tooling_api" => false,
|
458
|
+
"sfdc_object_name" => "Lead",
|
459
|
+
"sfdc_fields" => ["Id", "IsDeleted", "LastName", "FirstName", "Salutation"],
|
460
|
+
"sfdc_filters" => "Email LIKE '%@elastic.co'",
|
461
|
+
"tracking_field" => "LastModifiedDate",
|
462
|
+
"changed_data_filter" => "LastModifiedDate > %{last_tracking_field_value}",
|
463
|
+
"tracking_field_value_file" => "last_tracking_field_value.txt"
|
464
|
+
}
|
465
|
+
end
|
466
|
+
let(:input) { LogStash::Inputs::Salesforce.new(options) }
|
467
|
+
subject { input }
|
468
|
+
let(:queue) { [] }
|
469
|
+
it "loads some lead records" do
|
470
|
+
VCR.use_cassette("load some lead objects order by lastmodifieddate", :decode_compressed_response => true) do
|
471
|
+
subject.register
|
472
|
+
File.exist?("last_tracking_field_value.txt") && File.delete("last_tracking_field_value.txt")
|
473
|
+
subject.run(queue)
|
474
|
+
expect(queue.length).to eq(3)
|
475
|
+
tracking_field_value = File.read("last_tracking_field_value.txt")
|
476
|
+
expect(tracking_field_value).to eq("2025-05-07T14:32:17Z")
|
477
|
+
end
|
478
|
+
end
|
479
|
+
end
|
220
480
|
end
|
221
481
|
end
|