salesforce_streamer 2.0.0 → 2.4.0.rc1
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/.bundler-version +1 -0
- data/.dependabot/config.yml +7 -2
- data/.github/workflows/auto-approve.yml +3 -3
- data/.github/workflows/auto-merge.yml +19 -0
- data/CHANGELOG.md +32 -0
- data/Gemfile.lock +59 -50
- data/README.md +50 -3
- data/lib/core_extensions/cookiejar/cookie_validation.rb +59 -17
- data/lib/salesforce_streamer/cli.rb +1 -1
- data/lib/salesforce_streamer/configuration.rb +8 -2
- data/lib/salesforce_streamer/push_topic.rb +6 -6
- data/lib/salesforce_streamer/salesforce_client.rb +2 -4
- data/lib/salesforce_streamer/server.rb +22 -17
- data/lib/salesforce_streamer/version.rb +1 -1
- data/salesforce_streamer.gemspec +2 -2
- metadata +16 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6ae6f1fa912c4ac13fca440f74cef9b7a5952f0f555d1c41a193d1ed3d338c1
|
4
|
+
data.tar.gz: 6c9d4655567a7373777b3d1d224488ecebc48fb046f98d930f05171e0199468c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9548b2f8f714b701c8055ba63be30bd5f5057f8e87420c59c7504f438ab3ef15b4f3c986768bb19f70f57310539a8e695636a7c4540f3f00dc1d73e8ff6eed77
|
7
|
+
data.tar.gz: 706ea71664fb1b7b9f28501f3525050d2d651f1189e4360c34df332cc71af01b79997b0aca144de0f6bce4a969837232982afcecb60d8378a3257264b2c39642
|
data/.bundler-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.16
|
data/.dependabot/config.yml
CHANGED
@@ -3,9 +3,14 @@ version: 1
|
|
3
3
|
update_configs:
|
4
4
|
- package_manager: "ruby:bundler"
|
5
5
|
directory: "/"
|
6
|
-
update_schedule: "
|
6
|
+
update_schedule: "daily"
|
7
7
|
commit_message:
|
8
8
|
prefix: "[dependabot]"
|
9
9
|
allowed_updates:
|
10
10
|
- match:
|
11
|
-
|
11
|
+
dependency_type: "all"
|
12
|
+
update_type: "security"
|
13
|
+
automerged_updates:
|
14
|
+
- match:
|
15
|
+
dependency_type: "all"
|
16
|
+
update_type: "security:patch"
|
@@ -1,7 +1,7 @@
|
|
1
|
-
# automatically approve PRs submitted by Dependabot
|
1
|
+
# automatically approve PRs submitted by Dependabot or Renofidev
|
2
2
|
# this will allow Dependabot to automatically merge dependency update PRs where CI passes
|
3
3
|
# from: https://github.com/hmarr/auto-approve-action
|
4
|
-
name: Auto approve
|
4
|
+
name: Auto approve dependency upgrades PRs
|
5
5
|
|
6
6
|
on:
|
7
7
|
pull_request
|
@@ -11,6 +11,6 @@ jobs:
|
|
11
11
|
runs-on: ubuntu-latest
|
12
12
|
steps:
|
13
13
|
- uses: hmarr/auto-approve-action@v2.0.0
|
14
|
-
if: github.actor == 'dependabot[bot]' || github.actor == 'dependabot-preview[bot]'
|
14
|
+
if: github.actor == 'dependabot[bot]' || github.actor == 'dependabot-preview[bot]' || github.actor == 'renofidev'
|
15
15
|
with:
|
16
16
|
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
name: automerge
|
2
|
+
on:
|
3
|
+
pull_request_review:
|
4
|
+
types:
|
5
|
+
- submitted
|
6
|
+
check_suite:
|
7
|
+
types:
|
8
|
+
- completed
|
9
|
+
status: {}
|
10
|
+
jobs:
|
11
|
+
automerge:
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
steps:
|
14
|
+
- name: automerge
|
15
|
+
uses: "pascalgn/automerge-action@v0.12.0"
|
16
|
+
env:
|
17
|
+
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
18
|
+
MERGE_METHOD: squash
|
19
|
+
MERGE_DELETE_BRANCH: true
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,38 @@
|
|
3
3
|
Sorted so that the most recent change logs are near the top. Only significant
|
4
4
|
changes are logged in the change log.
|
5
5
|
|
6
|
+
## 2020-08-17 Scott Serok [scott@renofi.com](mailto:scott@renofi.com)
|
7
|
+
|
8
|
+
v2.1 changes the expected interface of `Configuration#replay_adapter`.
|
9
|
+
|
10
|
+
Normally this breaking change would require a major version bump, but since the
|
11
|
+
functionality today is quiet broken we can call this a major bug fix.
|
12
|
+
|
13
|
+
The `config.replay_adapter` should be an object that has an interface like Hash.
|
14
|
+
It must respond to `[]` and `[]=`. By default the adapter is an empty hash. If
|
15
|
+
you want your push topic replayId to persist between restarts, then you should
|
16
|
+
implement a class with an appropriate interface.
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
class MyReplayAdapter
|
20
|
+
def [](channel)
|
21
|
+
MyPersistence.get(channel)
|
22
|
+
end
|
23
|
+
|
24
|
+
def []=(channel, replay_id)
|
25
|
+
MyPersistence.set(channel, replay_id)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
```
|
29
|
+
|
30
|
+
This change was sparked by a misunderstanding of the
|
31
|
+
`Restforce::Concerns::Streaming::ReplayExtension` replay handlers.
|
32
|
+
SalesforceStreamer can eliminate some complexity and fix a bug by delegating the
|
33
|
+
responsibility of maintaining the current replayId to that ReplayExtension. The
|
34
|
+
object will be used on each request/response cycle to record and read the latest
|
35
|
+
replayId as long as the object assigned to `config.replay_adapter` responds to
|
36
|
+
`[]` and `[]=`.
|
37
|
+
|
6
38
|
## 2020-08-04 Scott Serok [scott@renofi.com](mailto:scott@renofi.com)
|
7
39
|
|
8
40
|
v2.0 is released as a major simplification of this library. There are 2
|
data/Gemfile.lock
CHANGED
@@ -1,28 +1,25 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
salesforce_streamer (2.0.
|
4
|
+
salesforce_streamer (2.4.0.rc1)
|
5
5
|
dry-initializer (~> 3.0)
|
6
6
|
faye (~> 1.4)
|
7
|
-
restforce (
|
7
|
+
restforce (~> 5.0)
|
8
8
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
12
|
addressable (2.7.0)
|
13
13
|
public_suffix (>= 2.0.2, < 5.0)
|
14
|
-
ast (2.4.
|
14
|
+
ast (2.4.2)
|
15
15
|
byebug (11.1.3)
|
16
|
-
codecov (0.2
|
17
|
-
|
18
|
-
json
|
19
|
-
simplecov
|
20
|
-
colorize (0.8.1)
|
16
|
+
codecov (0.5.2)
|
17
|
+
simplecov (>= 0.15, < 0.22)
|
21
18
|
cookiejar (0.3.3)
|
22
19
|
diff-lcs (1.4.4)
|
23
|
-
docile (1.3.
|
24
|
-
dry-initializer (3.0.
|
25
|
-
em-http-request (1.1.
|
20
|
+
docile (1.3.5)
|
21
|
+
dry-initializer (3.0.4)
|
22
|
+
em-http-request (1.1.7)
|
26
23
|
addressable (>= 2.3.4)
|
27
24
|
cookiejar (!= 0.3.1)
|
28
25
|
em-socksify (>= 0.3)
|
@@ -31,8 +28,15 @@ GEM
|
|
31
28
|
em-socksify (0.3.2)
|
32
29
|
eventmachine (>= 1.0.0.beta.4)
|
33
30
|
eventmachine (1.2.7)
|
34
|
-
faraday (1.
|
31
|
+
faraday (1.4.1)
|
32
|
+
faraday-excon (~> 1.1)
|
33
|
+
faraday-net_http (~> 1.0)
|
34
|
+
faraday-net_http_persistent (~> 1.1)
|
35
35
|
multipart-post (>= 1.2, < 3)
|
36
|
+
ruby2_keywords (>= 0.0.4)
|
37
|
+
faraday-excon (1.1.0)
|
38
|
+
faraday-net_http (1.0.1)
|
39
|
+
faraday-net_http_persistent (1.1.0)
|
36
40
|
faraday_middleware (1.0.0)
|
37
41
|
faraday (~> 1.0)
|
38
42
|
faye (1.4.0)
|
@@ -48,64 +52,69 @@ GEM
|
|
48
52
|
websocket-driver (>= 0.5.1)
|
49
53
|
hashie (4.1.0)
|
50
54
|
http_parser.rb (0.6.0)
|
51
|
-
|
52
|
-
jwt (2.2.1)
|
55
|
+
jwt (2.2.3)
|
53
56
|
multi_json (1.15.0)
|
54
57
|
multipart-post (2.1.1)
|
55
|
-
parallel (1.
|
56
|
-
parser (
|
58
|
+
parallel (1.20.1)
|
59
|
+
parser (3.0.1.1)
|
57
60
|
ast (~> 2.4.1)
|
58
|
-
public_suffix (4.0.
|
61
|
+
public_suffix (4.0.6)
|
59
62
|
rack (2.2.3)
|
60
63
|
rainbow (3.0.0)
|
61
|
-
rake (13.0.
|
62
|
-
regexp_parser (1.
|
63
|
-
restforce (5.0.
|
64
|
+
rake (13.0.3)
|
65
|
+
regexp_parser (2.1.1)
|
66
|
+
restforce (5.0.5)
|
64
67
|
faraday (>= 0.9.0, <= 2.0)
|
65
68
|
faraday_middleware (>= 0.8.8, <= 2.0)
|
66
69
|
hashie (>= 1.2.0, < 5.0)
|
67
70
|
jwt (>= 1.5.6)
|
68
|
-
rexml (3.2.
|
69
|
-
rspec (3.
|
70
|
-
rspec-core (~> 3.
|
71
|
-
rspec-expectations (~> 3.
|
72
|
-
rspec-mocks (~> 3.
|
73
|
-
rspec-core (3.
|
74
|
-
rspec-support (~> 3.
|
75
|
-
rspec-expectations (3.
|
71
|
+
rexml (3.2.5)
|
72
|
+
rspec (3.10.0)
|
73
|
+
rspec-core (~> 3.10.0)
|
74
|
+
rspec-expectations (~> 3.10.0)
|
75
|
+
rspec-mocks (~> 3.10.0)
|
76
|
+
rspec-core (3.10.1)
|
77
|
+
rspec-support (~> 3.10.0)
|
78
|
+
rspec-expectations (3.10.1)
|
76
79
|
diff-lcs (>= 1.2.0, < 2.0)
|
77
|
-
rspec-support (~> 3.
|
78
|
-
rspec-mocks (3.
|
80
|
+
rspec-support (~> 3.10.0)
|
81
|
+
rspec-mocks (3.10.2)
|
79
82
|
diff-lcs (>= 1.2.0, < 2.0)
|
80
|
-
rspec-support (~> 3.
|
81
|
-
rspec-support (3.
|
82
|
-
rubocop (
|
83
|
+
rspec-support (~> 3.10.0)
|
84
|
+
rspec-support (3.10.2)
|
85
|
+
rubocop (1.14.0)
|
83
86
|
parallel (~> 1.10)
|
84
|
-
parser (>=
|
87
|
+
parser (>= 3.0.0.0)
|
85
88
|
rainbow (>= 2.2.2, < 4.0)
|
86
|
-
regexp_parser (>= 1.
|
89
|
+
regexp_parser (>= 1.8, < 3.0)
|
87
90
|
rexml
|
88
|
-
rubocop-ast (>=
|
91
|
+
rubocop-ast (>= 1.5.0, < 2.0)
|
89
92
|
ruby-progressbar (~> 1.7)
|
90
|
-
unicode-display_width (>= 1.4.0, <
|
91
|
-
rubocop-ast (
|
92
|
-
parser (>=
|
93
|
-
rubocop-
|
94
|
-
rubocop
|
95
|
-
rubocop-rspec (
|
96
|
-
rubocop (
|
97
|
-
|
98
|
-
|
93
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
94
|
+
rubocop-ast (1.5.0)
|
95
|
+
parser (>= 3.0.1.1)
|
96
|
+
rubocop-rake (0.5.1)
|
97
|
+
rubocop
|
98
|
+
rubocop-rspec (2.3.0)
|
99
|
+
rubocop (~> 1.0)
|
100
|
+
rubocop-ast (>= 1.1.0)
|
101
|
+
ruby-progressbar (1.11.0)
|
102
|
+
ruby2_keywords (0.0.4)
|
103
|
+
simplecov (0.21.2)
|
99
104
|
docile (~> 1.1)
|
100
105
|
simplecov-html (~> 0.11)
|
101
|
-
|
102
|
-
|
106
|
+
simplecov_json_formatter (~> 0.1)
|
107
|
+
simplecov-html (0.12.3)
|
108
|
+
simplecov_json_formatter (0.1.3)
|
109
|
+
unicode-display_width (2.0.0)
|
103
110
|
websocket-driver (0.7.3)
|
104
111
|
websocket-extensions (>= 0.1.0)
|
105
112
|
websocket-extensions (0.1.5)
|
106
113
|
|
107
114
|
PLATFORMS
|
108
|
-
|
115
|
+
x86_64-darwin-19
|
116
|
+
x86_64-darwin-20
|
117
|
+
x86_64-linux
|
109
118
|
|
110
119
|
DEPENDENCIES
|
111
120
|
byebug
|
@@ -113,9 +122,9 @@ DEPENDENCIES
|
|
113
122
|
rake
|
114
123
|
rspec
|
115
124
|
rubocop
|
116
|
-
rubocop-
|
125
|
+
rubocop-rake
|
117
126
|
rubocop-rspec
|
118
127
|
salesforce_streamer!
|
119
128
|
|
120
129
|
BUNDLED WITH
|
121
|
-
2.
|
130
|
+
2.2.16
|
data/README.md
CHANGED
@@ -89,10 +89,9 @@ Configure the `SalesforceStreamer` module.
|
|
89
89
|
SalesforceStreamer.configure do |config|
|
90
90
|
config.logger = Logger.new(STDERR, level: 'INFO')
|
91
91
|
config.exception_adapter = proc { |e| puts e }
|
92
|
-
config.replay_adapter =
|
93
|
-
(ReplayStore.get(topic.name) || topic.replay).to_i
|
94
|
-
}
|
92
|
+
config.replay_adapter = MyReplayAdapter
|
95
93
|
config.use_middleware AfterMessageReceived
|
94
|
+
config.use_faye_extension ErrorLoggingExtension.new
|
96
95
|
config.manage_topics = true
|
97
96
|
end
|
98
97
|
```
|
@@ -153,6 +152,54 @@ end
|
|
153
152
|
|
154
153
|
SalesforceStreamer.config.use_middleware MySimpleMiddleware
|
155
154
|
```
|
155
|
+
|
156
|
+
### ReplayAdapter
|
157
|
+
|
158
|
+
The `config.replay_adapter` should be an object that has an interface like Hash.
|
159
|
+
It must respond to `[]` and `[]=`. By default the adapter is an empty hash. If
|
160
|
+
you want your push topic replayId to persist between restarts, then you should
|
161
|
+
implement a class with an appropriate interface.
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
class MyReplayAdapter
|
165
|
+
def [](channel)
|
166
|
+
Persistence.get(channel)
|
167
|
+
end
|
168
|
+
|
169
|
+
def []=(channel, replay_id)
|
170
|
+
Persistence.set(channel, replay_id)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
```
|
174
|
+
|
175
|
+
This adapter will be used directly by `Restforce::ReplayExtension`.
|
176
|
+
|
177
|
+
### Use Faye Extension
|
178
|
+
|
179
|
+
The `config.use_faye_extension` should be given an object that responds to
|
180
|
+
`.incoming(message, callback)` or `.outgoing(message, callback)` or both. Find
|
181
|
+
out more about extensions from
|
182
|
+
[Faye](https://github.com/faye/faye/blob/master/spec/ruby/server/extensions_spec.rb)
|
183
|
+
specs.
|
184
|
+
|
185
|
+
Any configured extensions are added to the Faye client used by the Restforce
|
186
|
+
client when starting up the server. If the extension responds to `.server=` then
|
187
|
+
the instance of `SalesforceStreamer::Server` is assigned. This may be convenient
|
188
|
+
to restart the server subscriptions if an error requires a reset.
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
class MyRestartFayeExtension
|
192
|
+
attr_accessor :server
|
193
|
+
|
194
|
+
def incoming(message, callback)
|
195
|
+
callback.call(message).tap |message|
|
196
|
+
server.restart if message['error'] == 'tragic'
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
SalesforceStreamer.config.use_faye_extension MyRestartFayeExtension.new
|
202
|
+
```
|
156
203
|
## Development
|
157
204
|
|
158
205
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -1,27 +1,69 @@
|
|
1
|
+
require 'cookiejar/cookie_validation'
|
2
|
+
|
1
3
|
# Original source code at
|
2
4
|
# https://github.com/dwaite/cookiejar/blob/master/lib/cookiejar/cookie_validation.rb
|
3
|
-
|
4
|
-
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
module CookieJar
|
6
|
+
module CookieValidation
|
7
|
+
# Re-opening the CookieValidation module to rewrite the domains_match method to
|
8
|
+
# skip the validation of domains. Open issue at
|
9
|
+
# https://github.com/restforce/restforce/issues/120
|
10
|
+
def self.domains_match(tested_domain, base_domain)
|
11
|
+
return true if tested_domain[-15..].eql?('.salesforce.com')
|
12
|
+
|
13
|
+
# original implementation
|
14
|
+
base = effective_host base_domain
|
15
|
+
search_domains = compute_search_domains_for_host base
|
16
|
+
search_domains.find do |domain|
|
17
|
+
domain == tested_domain
|
18
|
+
end
|
19
|
+
end
|
13
20
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
21
|
+
# Implements https://github.com/dwaite/cookiejar/commit/adb79c0a14c2b347c5289e79379a1acfe34bf388
|
22
|
+
# which is not part of the cookiejar gem yet and is required to prevent
|
23
|
+
# Unknown cookie parameter 'samesite' (CookieJar::InvalidCookieError)
|
24
|
+
def self.parse_set_cookie(set_cookie_value)
|
25
|
+
args = {}
|
26
|
+
params = set_cookie_value.split(/;\s*/)
|
27
|
+
|
28
|
+
first = true
|
29
|
+
params.each do |param|
|
30
|
+
result = PARAM1.match param
|
31
|
+
unless result
|
32
|
+
fail InvalidCookieError,
|
33
|
+
"Invalid cookie parameter in cookie '#{set_cookie_value}'"
|
34
|
+
end
|
35
|
+
key = result[1].downcase.to_sym
|
36
|
+
keyvalue = result[2]
|
37
|
+
if first
|
38
|
+
args[:name] = result[1]
|
39
|
+
args[:value] = keyvalue
|
40
|
+
first = false
|
41
|
+
else
|
42
|
+
case key
|
43
|
+
when :expires
|
44
|
+
begin
|
45
|
+
args[:expires_at] = Time.parse keyvalue
|
46
|
+
rescue ArgumentError
|
47
|
+
raise unless $ERROR_INFO.message == 'time out of range'
|
48
|
+
args[:expires_at] = Time.at(0x7FFFFFFF)
|
19
49
|
end
|
50
|
+
when :"max-age"
|
51
|
+
args[:max_age] = keyvalue.to_i
|
52
|
+
when :domain, :path
|
53
|
+
args[key] = keyvalue
|
54
|
+
when :secure
|
55
|
+
args[:secure] = true
|
56
|
+
when :httponly
|
57
|
+
args[:http_only] = true
|
58
|
+
when :samesite
|
59
|
+
args[:samesite] = keyvalue.downcase
|
60
|
+
else
|
61
|
+
fail InvalidCookieError, "Unknown cookie parameter '#{key}'"
|
20
62
|
end
|
21
63
|
end
|
22
64
|
end
|
65
|
+
args[:version] = 0
|
66
|
+
args
|
23
67
|
end
|
24
68
|
end
|
25
69
|
end
|
26
|
-
|
27
|
-
CookieJar::CookieValidation.extend(CoreExtensions::CookieJar::CookieValidation)
|
@@ -32,7 +32,7 @@ module SalesforceStreamer
|
|
32
32
|
end
|
33
33
|
|
34
34
|
o.on '-v', '--verbose LEVEL', 'Set the log level (default no logging)' do |arg|
|
35
|
-
@config.logger = Logger.new(
|
35
|
+
@config.logger = Logger.new($stderr, level: arg)
|
36
36
|
end
|
37
37
|
|
38
38
|
o.on '-V', '--version', 'Print the version information' do
|
@@ -3,7 +3,7 @@ module SalesforceStreamer
|
|
3
3
|
class Configuration
|
4
4
|
attr_accessor :environment, :logger, :require_path, :config_file,
|
5
5
|
:manage_topics, :exception_adapter, :replay_adapter
|
6
|
-
attr_reader :middleware
|
6
|
+
attr_reader :middleware, :faye_extensions
|
7
7
|
|
8
8
|
class << self
|
9
9
|
attr_writer :instance
|
@@ -21,11 +21,12 @@ module SalesforceStreamer
|
|
21
21
|
@environment = ENV['RACK_ENV'] || :development
|
22
22
|
@logger = Logger.new(IO::NULL)
|
23
23
|
@exception_adapter = proc { |exc| fail(exc) }
|
24
|
-
@replay_adapter =
|
24
|
+
@replay_adapter = Hash.new { |hash, key| hash[key] = -1 }
|
25
25
|
@manage_topics = false
|
26
26
|
@config_file = './config/streamer.yml'
|
27
27
|
@require_path = './config/environment'
|
28
28
|
@middleware = []
|
29
|
+
@faye_extensions = [ReplayIdErrorExtension.new]
|
29
30
|
end
|
30
31
|
|
31
32
|
def manage_topics?
|
@@ -37,6 +38,11 @@ module SalesforceStreamer
|
|
37
38
|
@middleware << [klass, args, block]
|
38
39
|
end
|
39
40
|
|
41
|
+
# adds a Faye extension
|
42
|
+
def use_faye_extension(extension)
|
43
|
+
@faye_extensions << extension
|
44
|
+
end
|
45
|
+
|
40
46
|
# returns a ready to use chain of middleware
|
41
47
|
def middleware_runner(last_handler)
|
42
48
|
@middleware.reduce(last_handler) do |next_handler, current_handler|
|
@@ -4,11 +4,11 @@ module SalesforceStreamer
|
|
4
4
|
extend Dry::Initializer
|
5
5
|
|
6
6
|
option :name
|
7
|
-
option :query,
|
8
|
-
option :handler,
|
9
|
-
option :replay,
|
10
|
-
option :api_version, proc(&:to_s), default:
|
11
|
-
option :notify_for_fields, default:
|
7
|
+
option :query, ->(v) { v.gsub(/\s+/, ' ') }
|
8
|
+
option :handler, ->(v) { prepare_handler_proc(Object.const_get(v)) }
|
9
|
+
option :replay, ->(v) { v.to_i }, default: -> { -1 }
|
10
|
+
option :api_version, proc(&:to_s), default: -> { '49.0' }
|
11
|
+
option :notify_for_fields, default: -> { 'Referenced' }
|
12
12
|
option :id, optional: true
|
13
13
|
option :description, optional: true
|
14
14
|
|
@@ -34,7 +34,7 @@ module SalesforceStreamer
|
|
34
34
|
@handler = Object.const_get(@handler)
|
35
35
|
true
|
36
36
|
rescue NameError, TypeError => e
|
37
|
-
message =
|
37
|
+
message = "handler=#{@handler} exception=#{e}"
|
38
38
|
raise(PushTopicHandlerMissingError, message)
|
39
39
|
end
|
40
40
|
|
@@ -8,10 +8,8 @@ module SalesforceStreamer
|
|
8
8
|
@client.authenticate!
|
9
9
|
end
|
10
10
|
|
11
|
-
def subscribe(*args)
|
12
|
-
@client.subscribe(args)
|
13
|
-
yield
|
14
|
-
end
|
11
|
+
def subscribe(*args, &block)
|
12
|
+
@client.subscribe(args, &block)
|
15
13
|
end
|
16
14
|
|
17
15
|
# Returns nil or an instance of Restforce::SObject
|
@@ -1,15 +1,23 @@
|
|
1
1
|
module SalesforceStreamer
|
2
2
|
class Server
|
3
3
|
attr_writer :push_topics
|
4
|
+
attr_reader :client
|
4
5
|
|
5
6
|
def initialize(push_topics: [])
|
6
7
|
@push_topics = push_topics
|
7
8
|
end
|
8
9
|
|
9
10
|
def run
|
10
|
-
Log.info 'Starting
|
11
|
+
Log.info 'Starting server'
|
11
12
|
catch_signals
|
12
|
-
|
13
|
+
reset_client
|
14
|
+
EM.run { subscribe }
|
15
|
+
end
|
16
|
+
|
17
|
+
def restart
|
18
|
+
Log.info 'Restarting server'
|
19
|
+
reset_client
|
20
|
+
EM.next_tick { subscribe }
|
13
21
|
end
|
14
22
|
|
15
23
|
private
|
@@ -23,24 +31,21 @@ module SalesforceStreamer
|
|
23
31
|
end
|
24
32
|
end
|
25
33
|
|
26
|
-
def
|
27
|
-
return @client if @client
|
34
|
+
def reset_client
|
28
35
|
@client = Restforce.new
|
29
|
-
|
30
|
-
|
31
|
-
|
36
|
+
client.authenticate!
|
37
|
+
Configuration.instance.faye_extensions.each do |extension|
|
38
|
+
Log.debug %(adding Faye extension #{extension})
|
39
|
+
extension.server = self if extension.respond_to?(:server=)
|
40
|
+
client.faye.add_extension extension
|
41
|
+
end
|
32
42
|
end
|
33
43
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
replay_id = message.dig('event', 'replayId')
|
40
|
-
Log.info "Message #{replay_id} received from topic #{topic.name}"
|
41
|
-
topic.handle message
|
42
|
-
topic.id = replay_id
|
43
|
-
end
|
44
|
+
def subscribe
|
45
|
+
@push_topics.each do |topic|
|
46
|
+
client.subscribe topic.name, replay: Configuration.instance.replay_adapter do |message|
|
47
|
+
Log.info "Message #{message.dig('event', 'replayId')} received from topic #{topic.name}"
|
48
|
+
topic.handle message
|
44
49
|
end
|
45
50
|
end
|
46
51
|
end
|
data/salesforce_streamer.gemspec
CHANGED
@@ -27,13 +27,13 @@ Gem::Specification.new do |spec|
|
|
27
27
|
|
28
28
|
spec.add_dependency 'dry-initializer', '~> 3.0'
|
29
29
|
spec.add_dependency 'faye', '~> 1.4'
|
30
|
-
spec.add_dependency 'restforce', '
|
30
|
+
spec.add_dependency 'restforce', '~> 5.0'
|
31
31
|
|
32
32
|
spec.add_development_dependency 'byebug'
|
33
33
|
spec.add_development_dependency 'codecov'
|
34
34
|
spec.add_development_dependency 'rake'
|
35
35
|
spec.add_development_dependency 'rspec'
|
36
36
|
spec.add_development_dependency 'rubocop'
|
37
|
-
spec.add_development_dependency 'rubocop-
|
37
|
+
spec.add_development_dependency 'rubocop-rake'
|
38
38
|
spec.add_development_dependency 'rubocop-rspec'
|
39
39
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: salesforce_streamer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.4.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Serok
|
8
8
|
- RenoFi Engineering Team
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-05-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: dry-initializer
|
@@ -43,22 +43,16 @@ dependencies:
|
|
43
43
|
name: restforce
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- - "
|
47
|
-
- !ruby/object:Gem::Version
|
48
|
-
version: '4.2'
|
49
|
-
- - "<"
|
46
|
+
- - "~>"
|
50
47
|
- !ruby/object:Gem::Version
|
51
|
-
version: '
|
48
|
+
version: '5.0'
|
52
49
|
type: :runtime
|
53
50
|
prerelease: false
|
54
51
|
version_requirements: !ruby/object:Gem::Requirement
|
55
52
|
requirements:
|
56
|
-
- - "
|
57
|
-
- !ruby/object:Gem::Version
|
58
|
-
version: '4.2'
|
59
|
-
- - "<"
|
53
|
+
- - "~>"
|
60
54
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
55
|
+
version: '5.0'
|
62
56
|
- !ruby/object:Gem::Dependency
|
63
57
|
name: byebug
|
64
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -130,7 +124,7 @@ dependencies:
|
|
130
124
|
- !ruby/object:Gem::Version
|
131
125
|
version: '0'
|
132
126
|
- !ruby/object:Gem::Dependency
|
133
|
-
name: rubocop-
|
127
|
+
name: rubocop-rake
|
134
128
|
requirement: !ruby/object:Gem::Requirement
|
135
129
|
requirements:
|
136
130
|
- - ">="
|
@@ -157,7 +151,7 @@ dependencies:
|
|
157
151
|
- - ">="
|
158
152
|
- !ruby/object:Gem::Version
|
159
153
|
version: '0'
|
160
|
-
description:
|
154
|
+
description:
|
161
155
|
email:
|
162
156
|
- scott@renofi.com
|
163
157
|
- engineering@renofi.com
|
@@ -166,12 +160,14 @@ executables:
|
|
166
160
|
extensions: []
|
167
161
|
extra_rdoc_files: []
|
168
162
|
files:
|
163
|
+
- ".bundler-version"
|
169
164
|
- ".dependabot/config.yml"
|
170
165
|
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
171
166
|
- ".github/ISSUE_TEMPLATE/config.yml"
|
172
167
|
- ".github/ISSUE_TEMPLATE/story.md"
|
173
168
|
- ".github/PULL_REQUEST_TEMPLATE.md"
|
174
169
|
- ".github/workflows/auto-approve.yml"
|
170
|
+
- ".github/workflows/auto-merge.yml"
|
175
171
|
- ".gitignore"
|
176
172
|
- ".rspec"
|
177
173
|
- ".travis.yml"
|
@@ -203,7 +199,7 @@ metadata:
|
|
203
199
|
homepage_uri: https://github.com/renofi/salesforce_streamer
|
204
200
|
source_code_uri: https://github.com/renofi/salesforce_streamer
|
205
201
|
documentation_uri: https://www.rubydoc.info/gems/salesforce_streamer
|
206
|
-
post_install_message:
|
202
|
+
post_install_message:
|
207
203
|
rdoc_options: []
|
208
204
|
require_paths:
|
209
205
|
- lib
|
@@ -214,12 +210,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
214
210
|
version: '2.6'
|
215
211
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
216
212
|
requirements:
|
217
|
-
- - "
|
213
|
+
- - ">"
|
218
214
|
- !ruby/object:Gem::Version
|
219
|
-
version:
|
215
|
+
version: 1.3.1
|
220
216
|
requirements: []
|
221
|
-
rubygems_version: 3.
|
222
|
-
signing_key:
|
217
|
+
rubygems_version: 3.2.16
|
218
|
+
signing_key:
|
223
219
|
specification_version: 4
|
224
220
|
summary: A wrapper around the Restforce Streaming API with a built-in PushTopic manager.
|
225
221
|
test_files: []
|