logstash-input-sfdc_elf 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rubocop.yml +41 -0
  4. data/Gemfile +9 -0
  5. data/LICENSE.md +12 -0
  6. data/README.md +1 -0
  7. data/Rakefile +13 -0
  8. data/lib/logstash/inputs/sfdc_elf.rb +147 -0
  9. data/lib/logstash/inputs/sfdc_elf/client_with_streaming_support.rb +61 -0
  10. data/lib/logstash/inputs/sfdc_elf/queue_util.rb +176 -0
  11. data/lib/logstash/inputs/sfdc_elf/scheduler.rb +73 -0
  12. data/lib/logstash/inputs/sfdc_elf/state_persistor.rb +49 -0
  13. data/logstash-input-sfdc_elf.gemspec +29 -0
  14. data/spec/fixtures/auth_success_response.json +7 -0
  15. data/spec/fixtures/describe.json +3526 -0
  16. data/spec/fixtures/org_query_response.json +11 -0
  17. data/spec/fixtures/queue_util/create_event_ELF_list1.json +19 -0
  18. data/spec/fixtures/queue_util/create_event_ELF_list2.json +29 -0
  19. data/spec/fixtures/queue_util/create_event_ELF_list3.json +29 -0
  20. data/spec/fixtures/queue_util/create_event_sampledata1.csv +31 -0
  21. data/spec/fixtures/queue_util/create_event_sampledata2.csv +2 -0
  22. data/spec/fixtures/queue_util/create_event_sampledata3.csv +2 -0
  23. data/spec/fixtures/queue_util/eventlogfile_describe.json +990 -0
  24. data/spec/fixtures/queue_util/eventlogfile_list.json +62 -0
  25. data/spec/fixtures/queue_util/sample_data1.csv +5 -0
  26. data/spec/fixtures/queue_util/sample_data2.csv +5 -0
  27. data/spec/fixtures/queue_util/sample_data3.csv +1467 -0
  28. data/spec/fixtures/queue_util/sample_data4.csv +2 -0
  29. data/spec/fixtures/queue_util/sample_data5.csv +309 -0
  30. data/spec/inputs/sfdc_elf/queue_util_spec.rb +176 -0
  31. data/spec/inputs/sfdc_elf/scheduler_spec.rb +56 -0
  32. data/spec/inputs/sfdc_elf/state_persistor_spec.rb +58 -0
  33. data/spec/inputs/sfdc_elf_spec.rb +101 -0
  34. data/spec/spec_helper.rb +38 -0
  35. metadata +180 -0
@@ -0,0 +1,56 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe Scheduler do
4
+ let(:hour_interval) { hour_interval = 3600 }
5
+
6
+ after do
7
+ Timecop.return
8
+ end
9
+
10
+ describe '#stall_schedule' do
11
+ # Precondition:
12
+ # - none
13
+ it 'Missed the next scheduled time' do
14
+ # Start time is 1:00pm.
15
+ start_time = Time.local(2015, 9, 1, 13, 00, 0)
16
+
17
+ # Freeze the time at the current time, which is 2:30pm.
18
+ current_time = Time.local(2015, 9, 1, 14, 30, 0)
19
+ Timecop.freeze(current_time)
20
+
21
+ # Set the interval in to every hour.
22
+ scheduler = Scheduler.new(hour_interval)
23
+
24
+ # The next schedule time should be based on the start time + the interval, which would be 2:00pm.
25
+ next_schedule_time = start_time + hour_interval
26
+
27
+ # Since the start time is 1:00pm and next schedule time is 2:00pm, but the current time is 2:30pm we missed the
28
+ # schedule time. So then we expect the there is no sleep and the next schedule is 3:00pm.
29
+ next_schedule_time = scheduler.stall_schedule(next_schedule_time)
30
+ expect(next_schedule_time).to eq Time.local(2015, 9, 1, 15, 00, 0)
31
+ end
32
+
33
+ # Precondition:
34
+ # - none
35
+ it 'Within the next scheduled time' do
36
+ # Start time is 1:00pm.
37
+ start_time = Time.local(2015, 9, 1, 13, 00, 0)
38
+
39
+ # Freeze the time at the current time, which is 1:30pm.
40
+ current_time = Time.local(2015, 9, 1, 13, 59, 55)
41
+ Timecop.freeze(current_time)
42
+
43
+ # Set the interval in to every hour.
44
+ scheduler = Scheduler.new(hour_interval)
45
+
46
+ # The next schedule time should be based on the start time + the interval, which would be 2:00pm.
47
+ next_schedule_time = start_time + hour_interval
48
+
49
+ # Since the start time is 1:00pm and next schedule time is 2:00pm, but the current time is 1:59:55pm, so we are
50
+ # within the scheduled time. So then we expect to sleep for 5 seconds and the next schedule is 3:00pm.
51
+ next_schedule_time = scheduler.stall_schedule(next_schedule_time)
52
+
53
+ expect(next_schedule_time).to eq Time.local(2015, 9, 1, 15, 00, 0)
54
+ end
55
+ end # stall_schedule
56
+ end # describe Scheduler
@@ -0,0 +1,58 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe StatePersistor do
4
+ let(:provided_path) { provided_path = Dir.tmpdir }
5
+ let(:provided_org_id) { provided_org_id = 'some_org_id' }
6
+ let(:provided_path_with_file) { provided_path_with_file = "#{provided_path}/.sfdc_info_logstash_#{provided_org_id}" }
7
+
8
+ after do
9
+ # Delete the .sfdc_info_logstash file.
10
+ File.delete(provided_path_with_file) if File.exist?(provided_path_with_file)
11
+ end
12
+
13
+
14
+
15
+ describe '#get_last_indexed_log_date' do
16
+ # Precondition:
17
+ # - .sfdc_info_logstash file does not exist in the system temp directory.
18
+ it 'creates .sdfc_info_logstash file because it does not exist' do
19
+ # I expect the sfdc_info_logstash file to not exist.
20
+ expect(File.exist?(provided_path_with_file)).to eq false
21
+
22
+ # I expect the file to exist now.
23
+ state_persistor = StatePersistor.new(provided_path, provided_org_id)
24
+ state_persistor.get_last_indexed_log_date
25
+ expect(File.exist?(provided_path_with_file)).to eq true
26
+ end
27
+
28
+
29
+ # Precondition:
30
+ # - .sfdc_info_logstash file exist in the provided directory and with the default date in it which is
31
+ # created in this IT block.
32
+ it 'read from .sdfc_info_logstash file which as the default date in it' do
33
+ state_persistor = StatePersistor.new(provided_path, provided_org_id)
34
+
35
+ # I expect the .sfdc_info_logstash file to not exist with default date in it.
36
+ expect(state_persistor.get_last_indexed_log_date).to eq '0001-01-01T00:00:00Z'
37
+ end
38
+ end # get_last_indexed_log_date
39
+
40
+
41
+
42
+
43
+ describe '#update_last_indexed_log_date' do
44
+ # Precondition:
45
+ # - .sfdc_info_logstash file exist in the provided directory and with the default date in it which is
46
+ # created in this IT block.
47
+ it 'updates the last indexed LogDate on the .sdfc_info_logstash file' do
48
+ state_persistor = StatePersistor.new(provided_path, provided_org_id)
49
+
50
+ # I expect the .sfdc_info_logstash file having default date in it.
51
+ expect(state_persistor.get_last_indexed_log_date).to eq '0001-01-01T00:00:00Z'
52
+
53
+ # I expect the .sfdc_info_logstash file having the new date.
54
+ state_persistor.update_last_indexed_log_date('3672-21-11T23:59:342Z')
55
+ expect(state_persistor.get_last_indexed_log_date).to eq '3672-21-11T23:59:342Z'
56
+ end
57
+ end
58
+ end # describe StatePersistor
@@ -0,0 +1,101 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe LogStash::Inputs::SfdcElf do
4
+ describe 'Path config' do
5
+ let(:provided_path_with_file) { provided_path_with_file = "#{Dir.home}/.sfdc_info_logstash_ThisIsATestID00000" }
6
+
7
+ # Apply this stub_request to all test cases in this describe block because the suffix for the .sfdc_info_logstash
8
+ # is based on the the client org id, so a successful login is needed.
9
+ before do
10
+ # Stub authentication
11
+ stub_request(:post, /login.salesforce.com/).
12
+ with(headers: { Accept: '*/*', User_Agent: 'Ruby' }).
13
+ to_return(status: 200, body: fixture('auth_success_response.json'), headers: {})
14
+
15
+ # Stub organization query
16
+ stub_request(:get, 'https://na1.salesforce.com/services/data/v33.0/query?q=select%20id%20from%20Organization').
17
+ with(headers: { Accept: '*/*', Authorization: 'OAuth access_token', User_Agent: 'Ruby' }).
18
+ to_return(status: 200, body: fixture('org_query_response.json'), headers: {})
19
+
20
+ # Stub describe query
21
+ stub_request(:get, 'https://na1.salesforce.com/services/data/v33.0/sobjects/Organization/describe').
22
+ with(headers: { Accept: '*/*', Authorization: 'OAuth access_token', User_Agent: 'Ruby' }).
23
+ to_return(status: 200, body: fixture('describe.json'), headers: {})
24
+ end
25
+
26
+
27
+
28
+
29
+ # Precondition:
30
+ # - .sfdc_info_logstash file does not exist in the home directory.
31
+ # - Successful client login.
32
+ it 'sets .sfdc_info_logstash file in the home directory because no path was specified' do
33
+ config =
34
+ {
35
+ 'username' => 'me@example.com',
36
+ 'password' => 'password',
37
+ 'security_token' => 'security_token'
38
+ }
39
+
40
+ # Push config though the plugin life cycle of register and teardown only.
41
+ plugin = LogStash::Inputs::SfdcElf.new(config)
42
+ plugin.register
43
+ expect(plugin.path).to eq Dir.home
44
+ plugin.teardown
45
+
46
+ # Delete the .sfdc_info_logstash file.
47
+ File.delete(provided_path_with_file)
48
+ end
49
+
50
+
51
+
52
+
53
+ # Precondition:
54
+ # - .sfdc_info_logstash file does not exist in the home directory.
55
+ # - Successful client login.
56
+ it 'sets .sfdc_info_logstash file in the home directory because the provided path is does not exist' do
57
+ config =
58
+ {
59
+ 'username' => 'me@example.com',
60
+ 'password' => 'password',
61
+ 'security_token' => 'security_token',
62
+ 'path' => 'This/is/an/incorrect/path'
63
+ }
64
+
65
+ # Push config though the plugin life cycle of register and teardown only.
66
+ plugin = LogStash::Inputs::SfdcElf.new(config)
67
+ plugin.register
68
+ expect(plugin.path).to eq Dir.home
69
+ plugin.teardown
70
+
71
+ # Delete the .sfdc_info_logstash file.
72
+ File.delete(provided_path_with_file)
73
+ end
74
+
75
+
76
+
77
+
78
+ # Precondition:
79
+ # - .sfdc_info_logstash file does not exist in the provided directory.
80
+ # - Successful client login
81
+ it 'sets sfdc_info_path to the provided path' do
82
+ provided_path = Dir.tmpdir
83
+
84
+ config =
85
+ {
86
+ 'username' => 'me@example.com',
87
+ 'password' => 'password',
88
+ 'security_token' => 'security_token',
89
+ 'path' => provided_path
90
+ }
91
+
92
+ plugin = LogStash::Inputs::SfdcElf.new(config)
93
+ plugin.register
94
+ expect(plugin.path).to eq provided_path
95
+ plugin.teardown
96
+
97
+ # Delete the .sfdc_info_logstash file.
98
+ File.delete("#{provided_path}/.sfdc_info_logstash_ThisIsATestID00000")
99
+ end
100
+ end # Path for .sfdc_info_logstash
101
+ end # describe SfdcElf
@@ -0,0 +1,38 @@
1
+ # SimpleCov must be at the top of test class.
2
+ require 'simplecov'
3
+ SimpleCov.start
4
+
5
+ require 'logstash/devutils/rspec/spec_helper'
6
+ require 'lib/logstash/inputs/sfdc_elf'
7
+ require 'webmock/rspec'
8
+ require 'timecop'
9
+
10
+
11
+
12
+ # Set up color and formatting for Rspec tests.
13
+ RSpec.configure do |config|
14
+ # Use color in STDOUT
15
+ config.color = true
16
+
17
+ # Use color not only in STDOUT but also in pagers and files
18
+ config.tty = true
19
+
20
+ # Use the specified formatter
21
+ config.formatter = :documentation # :progress, :html, :textmate
22
+ end
23
+
24
+
25
+
26
+ # Turn off all connection to the internet.
27
+ WebMock.disable_net_connect!(allow_localhost: true)
28
+
29
+
30
+
31
+ # Helper methods to make it simple getting fixture data.
32
+ def fixture_path
33
+ File.expand_path('../fixtures', __FILE__)
34
+ end
35
+
36
+ def fixture(file)
37
+ File.new(fixture_path + '/' + file)
38
+ end
metadata ADDED
@@ -0,0 +1,180 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logstash-input-sfdc_elf
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Abhishek Sreenivasa
8
+ - Mohammed Islam
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-09-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: logstash-core
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: 1.4.0
21
+ - - "<"
22
+ - !ruby/object:Gem::Version
23
+ version: 2.0.0
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ version: 1.4.0
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.0.0
34
+ - !ruby/object:Gem::Dependency
35
+ name: logstash-codec-plain
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ type: :runtime
42
+ prerelease: false
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ - !ruby/object:Gem::Dependency
49
+ name: activesupport
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: databasedotcom
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ type: :runtime
70
+ prerelease: false
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ - !ruby/object:Gem::Dependency
77
+ name: logstash-devutils
78
+ requirement: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ description: |-
91
+ This gem is a logstash plugin required to be installed on top of the Logstash core pipeline
92
+ using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program
93
+ email:
94
+ - asreenivasa@salesforce.com
95
+ - mislam@salesforce.com
96
+ executables: []
97
+ extensions: []
98
+ extra_rdoc_files: []
99
+ files:
100
+ - ".gitignore"
101
+ - ".rubocop.yml"
102
+ - Gemfile
103
+ - LICENSE.md
104
+ - README.md
105
+ - Rakefile
106
+ - lib/logstash/inputs/sfdc_elf.rb
107
+ - lib/logstash/inputs/sfdc_elf/client_with_streaming_support.rb
108
+ - lib/logstash/inputs/sfdc_elf/queue_util.rb
109
+ - lib/logstash/inputs/sfdc_elf/scheduler.rb
110
+ - lib/logstash/inputs/sfdc_elf/state_persistor.rb
111
+ - logstash-input-sfdc_elf.gemspec
112
+ - spec/fixtures/auth_success_response.json
113
+ - spec/fixtures/describe.json
114
+ - spec/fixtures/org_query_response.json
115
+ - spec/fixtures/queue_util/create_event_ELF_list1.json
116
+ - spec/fixtures/queue_util/create_event_ELF_list2.json
117
+ - spec/fixtures/queue_util/create_event_ELF_list3.json
118
+ - spec/fixtures/queue_util/create_event_sampledata1.csv
119
+ - spec/fixtures/queue_util/create_event_sampledata2.csv
120
+ - spec/fixtures/queue_util/create_event_sampledata3.csv
121
+ - spec/fixtures/queue_util/eventlogfile_describe.json
122
+ - spec/fixtures/queue_util/eventlogfile_list.json
123
+ - spec/fixtures/queue_util/sample_data1.csv
124
+ - spec/fixtures/queue_util/sample_data2.csv
125
+ - spec/fixtures/queue_util/sample_data3.csv
126
+ - spec/fixtures/queue_util/sample_data4.csv
127
+ - spec/fixtures/queue_util/sample_data5.csv
128
+ - spec/inputs/sfdc_elf/queue_util_spec.rb
129
+ - spec/inputs/sfdc_elf/scheduler_spec.rb
130
+ - spec/inputs/sfdc_elf/state_persistor_spec.rb
131
+ - spec/inputs/sfdc_elf_spec.rb
132
+ - spec/spec_helper.rb
133
+ homepage: http://www.salesforce.com
134
+ licenses:
135
+ - Salesforce EULA
136
+ metadata:
137
+ logstash_plugin: 'true'
138
+ logstash_group: input
139
+ post_install_message:
140
+ rdoc_options: []
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ requirements: []
154
+ rubyforge_project:
155
+ rubygems_version: 2.2.2
156
+ signing_key:
157
+ specification_version: 4
158
+ summary: A Logstash plugin the receives events from Salesforce EventLogFile
159
+ test_files:
160
+ - spec/fixtures/auth_success_response.json
161
+ - spec/fixtures/describe.json
162
+ - spec/fixtures/org_query_response.json
163
+ - spec/fixtures/queue_util/create_event_ELF_list1.json
164
+ - spec/fixtures/queue_util/create_event_ELF_list2.json
165
+ - spec/fixtures/queue_util/create_event_ELF_list3.json
166
+ - spec/fixtures/queue_util/create_event_sampledata1.csv
167
+ - spec/fixtures/queue_util/create_event_sampledata2.csv
168
+ - spec/fixtures/queue_util/create_event_sampledata3.csv
169
+ - spec/fixtures/queue_util/eventlogfile_describe.json
170
+ - spec/fixtures/queue_util/eventlogfile_list.json
171
+ - spec/fixtures/queue_util/sample_data1.csv
172
+ - spec/fixtures/queue_util/sample_data2.csv
173
+ - spec/fixtures/queue_util/sample_data3.csv
174
+ - spec/fixtures/queue_util/sample_data4.csv
175
+ - spec/fixtures/queue_util/sample_data5.csv
176
+ - spec/inputs/sfdc_elf/queue_util_spec.rb
177
+ - spec/inputs/sfdc_elf/scheduler_spec.rb
178
+ - spec/inputs/sfdc_elf/state_persistor_spec.rb
179
+ - spec/inputs/sfdc_elf_spec.rb
180
+ - spec/spec_helper.rb