cloudenvoy 0.3.0 → 0.4.2
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/.github/workflows/test.yml +4 -0
- data/.gitignore +3 -0
- data/Appraisals +16 -0
- data/CHANGELOG.md +29 -0
- data/README.md +4 -4
- data/app/controllers/cloudenvoy/subscriber_controller.rb +6 -5
- data/cloudenvoy.gemspec +1 -0
- data/examples/rails/Gemfile.lock +125 -106
- data/examples/sinatra/Gemfile +15 -0
- data/examples/sinatra/Gemfile.lock +127 -0
- data/examples/sinatra/Procfile +1 -0
- data/examples/sinatra/README.md +41 -0
- data/examples/sinatra/app/publishers/hello_publisher.rb +34 -0
- data/examples/sinatra/app/subscribers/hello_subscriber.rb +16 -0
- data/examples/sinatra/app.rb +40 -0
- data/examples/sinatra/bin/console +8 -0
- data/examples/sinatra/config/initializers/cloudenvoy.rb +30 -0
- data/gemfiles/rails_5.2.gemfile.lock +89 -73
- data/gemfiles/rails_6.0.gemfile.lock +90 -74
- data/gemfiles/semantic_logger_3.4.gemfile +7 -0
- data/gemfiles/semantic_logger_3.4.gemfile.lock +279 -0
- data/gemfiles/semantic_logger_4.6.gemfile +7 -0
- data/gemfiles/semantic_logger_4.6.gemfile.lock +279 -0
- data/gemfiles/semantic_logger_4.7.0.gemfile +7 -0
- data/gemfiles/semantic_logger_4.7.0.gemfile.lock +279 -0
- data/gemfiles/semantic_logger_4.7.2.gemfile +7 -0
- data/gemfiles/semantic_logger_4.7.2.gemfile.lock +279 -0
- data/lib/cloudenvoy/backend/google_pub_sub.rb +16 -1
- data/lib/cloudenvoy/logger_wrapper.rb +1 -1
- data/lib/cloudenvoy/message.rb +2 -2
- data/lib/cloudenvoy/publisher.rb +1 -0
- data/lib/cloudenvoy/subscriber.rb +3 -2
- data/lib/cloudenvoy/version.rb +1 -1
- data/lib/generators/cloudenvoy/publisher_generator.rb +46 -0
- data/lib/generators/cloudenvoy/subscriber_generator.rb +46 -0
- data/lib/generators/cloudenvoy/templates/publisher.rb.erb +11 -0
- data/lib/generators/cloudenvoy/templates/publisher_spec.rb.erb +6 -0
- data/lib/generators/cloudenvoy/templates/subscriber.rb.erb +11 -0
- data/lib/generators/cloudenvoy/templates/subscriber_spec.rb.erb +6 -0
- data/lib/tasks/cloudenvoy.rake +4 -4
- metadata +42 -7
- data/Gemfile.lock +0 -264
- data/app/controllers/cloudenvoy/application_controller.rb +0 -8
@@ -0,0 +1,41 @@
|
|
1
|
+
# Example usage with Rails
|
2
|
+
|
3
|
+
## Run using the local gcloud Pub/Sub emulator
|
4
|
+
|
5
|
+
1. Install dependencies: `bundle install`
|
6
|
+
2. Intall the Pub/Sub emulator: `gcloud components install pubsub-emulator && gcloud components update`
|
7
|
+
3. Run the Pub/Sub emulator: `gcloud beta emulators pubsub start`
|
8
|
+
4. Launch the server: `foreman start`
|
9
|
+
5. Open a Rails console: `./bin/console`
|
10
|
+
6. Create the topics and subscriptions (one time setup - no need to redo it until you restart the pubsub emulator)
|
11
|
+
```ruby
|
12
|
+
Cloudenvoy.setup_publishers
|
13
|
+
Cloudenvoy.setup_subscribers
|
14
|
+
```
|
15
|
+
7. Publish messages:
|
16
|
+
```ruby
|
17
|
+
HelloPublisher.publish('Some message')
|
18
|
+
```
|
19
|
+
8. Tail the logs to see how message get processed by `HelloSubscriber`
|
20
|
+
|
21
|
+
## Run using GCP Pub/Sub
|
22
|
+
|
23
|
+
1. Ensure that your [Google Cloud SDK](https://cloud.google.com/sdk/docs/quickstarts) is setup.
|
24
|
+
2. Install dependencies: `bundle install`
|
25
|
+
3. Start an [ngrok](https://ngrok.com) tunnel: `ngrok http 3000`
|
26
|
+
4. Edit the [initializer](./config/initializers/cloudenvoy.rb)
|
27
|
+
* Add the configuration of your GCP Pub/Sub
|
28
|
+
* Set `config.processor_host` to the ngrok http or https url
|
29
|
+
* Set `config.mode` to `:production`
|
30
|
+
5. Launch the server: `foreman start`
|
31
|
+
6. Open a Rails console: `./bin/console`
|
32
|
+
7. Create the topics and subscriptions (one time setup)
|
33
|
+
```ruby
|
34
|
+
Cloudenvoy.setup_publishers
|
35
|
+
Cloudenvoy.setup_subscribers
|
36
|
+
```
|
37
|
+
8. Publish messages
|
38
|
+
```ruby
|
39
|
+
HelloPublisher.publish('Some message')
|
40
|
+
```
|
41
|
+
9. Tail the logs to see how message get processed by `HelloSubscriber`
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class HelloPublisher
|
4
|
+
include Cloudenvoy::Publisher
|
5
|
+
|
6
|
+
cloudenvoy_options topic: 'hello-msgs'
|
7
|
+
|
8
|
+
#
|
9
|
+
# Set message metadata (attributes)
|
10
|
+
#
|
11
|
+
# @param [String] msg The message to publish
|
12
|
+
#
|
13
|
+
# @return [Hash] The message metadata
|
14
|
+
#
|
15
|
+
def metadata(msg)
|
16
|
+
{
|
17
|
+
kind: msg.start_with?('Hello') ? 'hello' : 'regular'
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Format the payload.
|
23
|
+
#
|
24
|
+
# @param [String] msg The message to publish
|
25
|
+
#
|
26
|
+
# @return [Hash] The formatted message
|
27
|
+
#
|
28
|
+
def payload(msg)
|
29
|
+
{
|
30
|
+
type: 'message',
|
31
|
+
content: msg
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class HelloSubscriber
|
4
|
+
include Cloudenvoy::Subscriber
|
5
|
+
|
6
|
+
cloudenvoy_options topic: 'hello-msgs'
|
7
|
+
|
8
|
+
#
|
9
|
+
# Process a pub/sub message
|
10
|
+
#
|
11
|
+
# @param [Cloudenvoy::Message] message The message to process.
|
12
|
+
#
|
13
|
+
def process(message)
|
14
|
+
logger.info("Received message #{message.payload.dig('content')}")
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Force logging to be realtime
|
4
|
+
STDOUT.sync = true
|
5
|
+
|
6
|
+
# Require project files
|
7
|
+
require 'sinatra'
|
8
|
+
Dir.glob('./config/initializers/*.rb').each { |file| require file }
|
9
|
+
Dir.glob('./app/publishers/*.rb').each { |file| require file }
|
10
|
+
Dir.glob('./app/subscribers/*.rb').each { |file| require file }
|
11
|
+
|
12
|
+
#---------------------------------------------------
|
13
|
+
# Routes
|
14
|
+
#---------------------------------------------------
|
15
|
+
|
16
|
+
get '/' do
|
17
|
+
'Hello!'
|
18
|
+
end
|
19
|
+
|
20
|
+
post '/cloudenvoy/receive' do
|
21
|
+
begin
|
22
|
+
# Authenticate request
|
23
|
+
Cloudenvoy::Authenticator.verify!(params['token'])
|
24
|
+
|
25
|
+
# Parse message descriptor
|
26
|
+
content = request.body.read
|
27
|
+
msg_descriptor = JSON.parse(content).except('token')
|
28
|
+
|
29
|
+
# Process message descriptor
|
30
|
+
Cloudenvoy::Subscriber.execute_from_descriptor(msg_descriptor)
|
31
|
+
return 204
|
32
|
+
rescue Cloudenvoy::InvalidSubscriberError
|
33
|
+
# 404: Message delivery will be retried
|
34
|
+
return 404
|
35
|
+
rescue StandardError => e
|
36
|
+
# 422: Message delivery will be retried
|
37
|
+
logger.info([e.message, e.backtrace].flatten.join("\n"))
|
38
|
+
return 422
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Require cloudenvoy and its extensions
|
4
|
+
require 'cloudenvoy'
|
5
|
+
|
6
|
+
Cloudenvoy.configure do |config|
|
7
|
+
#
|
8
|
+
# Secret used to authenticate job requests
|
9
|
+
#
|
10
|
+
config.secret = 'some-secret'
|
11
|
+
|
12
|
+
#
|
13
|
+
# GCP Configuration
|
14
|
+
#
|
15
|
+
config.gcp_project_id = 'some-project'
|
16
|
+
config.gcp_sub_prefix = 'my-app'
|
17
|
+
|
18
|
+
#
|
19
|
+
# Domain
|
20
|
+
#
|
21
|
+
# config.processor_host = 'https://xxxx.ngrok.io'
|
22
|
+
#
|
23
|
+
config.processor_host = 'http://localhost:3000'
|
24
|
+
|
25
|
+
#
|
26
|
+
# Uncomment to process messages via Pub/Sub.
|
27
|
+
# Requires a ngrok tunnel.
|
28
|
+
#
|
29
|
+
# config.mode = :production
|
30
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
cloudenvoy (0.
|
4
|
+
cloudenvoy (0.4.1)
|
5
5
|
activesupport
|
6
6
|
google-cloud-pubsub (~> 2.0)
|
7
7
|
jwt
|
@@ -53,70 +53,78 @@ GEM
|
|
53
53
|
tzinfo (~> 1.1)
|
54
54
|
addressable (2.7.0)
|
55
55
|
public_suffix (>= 2.0.2, < 5.0)
|
56
|
-
appraisal (2.
|
56
|
+
appraisal (2.4.0)
|
57
57
|
bundler
|
58
58
|
rake
|
59
59
|
thor (>= 0.14.0)
|
60
60
|
arel (9.0.0)
|
61
|
-
ast (2.4.
|
61
|
+
ast (2.4.2)
|
62
62
|
builder (3.2.4)
|
63
|
-
concurrent-ruby (1.1.
|
64
|
-
crack (0.4.
|
65
|
-
|
63
|
+
concurrent-ruby (1.1.8)
|
64
|
+
crack (0.4.5)
|
65
|
+
rexml
|
66
66
|
crass (1.0.6)
|
67
|
-
diff-lcs (1.4.
|
68
|
-
erubi (1.
|
69
|
-
faraday (1.
|
67
|
+
diff-lcs (1.4.4)
|
68
|
+
erubi (1.10.0)
|
69
|
+
faraday (1.4.1)
|
70
|
+
faraday-excon (~> 1.1)
|
71
|
+
faraday-net_http (~> 1.0)
|
72
|
+
faraday-net_http_persistent (~> 1.1)
|
70
73
|
multipart-post (>= 1.2, < 3)
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
74
|
+
ruby2_keywords (>= 0.0.4)
|
75
|
+
faraday-excon (1.1.0)
|
76
|
+
faraday-net_http (1.0.1)
|
77
|
+
faraday-net_http_persistent (1.1.0)
|
78
|
+
gapic-common (0.4.1)
|
79
|
+
faraday (~> 1.3)
|
80
|
+
google-protobuf (~> 3.15, >= 3.15.2)
|
81
|
+
googleapis-common-protos (>= 1.3.11, < 2.0)
|
82
|
+
googleapis-common-protos-types (>= 1.0.6, < 2.0)
|
83
|
+
googleauth (~> 0.15, >= 0.15.1)
|
84
|
+
grpc (~> 1.36)
|
77
85
|
globalid (0.4.2)
|
78
86
|
activesupport (>= 4.2.0)
|
79
|
-
google-cloud-core (1.
|
87
|
+
google-cloud-core (1.6.0)
|
80
88
|
google-cloud-env (~> 1.0)
|
81
89
|
google-cloud-errors (~> 1.0)
|
82
|
-
google-cloud-env (1.
|
90
|
+
google-cloud-env (1.5.0)
|
83
91
|
faraday (>= 0.17.3, < 2.0)
|
84
|
-
google-cloud-errors (1.0
|
85
|
-
google-cloud-pubsub (2.
|
92
|
+
google-cloud-errors (1.1.0)
|
93
|
+
google-cloud-pubsub (2.5.0)
|
86
94
|
concurrent-ruby (~> 1.1)
|
87
95
|
google-cloud-core (~> 1.5)
|
88
96
|
google-cloud-pubsub-v1 (~> 0.0)
|
89
|
-
google-cloud-pubsub-v1 (0.
|
97
|
+
google-cloud-pubsub-v1 (0.4.0)
|
90
98
|
gapic-common (~> 0.3)
|
91
99
|
google-cloud-errors (~> 1.0)
|
92
100
|
grpc-google-iam-v1 (>= 0.6.10, < 2.0)
|
93
|
-
google-protobuf (3.
|
94
|
-
googleapis-common-protos (1.3.
|
95
|
-
google-protobuf (~> 3.
|
96
|
-
googleapis-common-protos-types (>= 1.0.
|
101
|
+
google-protobuf (3.15.8)
|
102
|
+
googleapis-common-protos (1.3.11)
|
103
|
+
google-protobuf (~> 3.14)
|
104
|
+
googleapis-common-protos-types (>= 1.0.6, < 2.0)
|
97
105
|
grpc (~> 1.27)
|
98
|
-
googleapis-common-protos-types (1.0.
|
99
|
-
google-protobuf (~> 3.
|
100
|
-
googleauth (0.
|
106
|
+
googleapis-common-protos-types (1.0.6)
|
107
|
+
google-protobuf (~> 3.14)
|
108
|
+
googleauth (0.16.1)
|
101
109
|
faraday (>= 0.17.3, < 2.0)
|
102
110
|
jwt (>= 1.4, < 3.0)
|
103
111
|
memoist (~> 0.16)
|
104
112
|
multi_json (~> 1.11)
|
105
113
|
os (>= 0.9, < 2.0)
|
106
114
|
signet (~> 0.14)
|
107
|
-
grpc (1.
|
108
|
-
google-protobuf (~> 3.
|
115
|
+
grpc (1.37.0)
|
116
|
+
google-protobuf (~> 3.15)
|
109
117
|
googleapis-common-protos-types (~> 1.0)
|
110
|
-
grpc-google-iam-v1 (0.6.
|
111
|
-
google-protobuf (~> 3.
|
112
|
-
googleapis-common-protos (>= 1.3.
|
118
|
+
grpc-google-iam-v1 (0.6.11)
|
119
|
+
google-protobuf (~> 3.14)
|
120
|
+
googleapis-common-protos (>= 1.3.11, < 2.0)
|
113
121
|
grpc (~> 1.27)
|
114
122
|
hashdiff (1.0.1)
|
115
|
-
i18n (1.8.
|
123
|
+
i18n (1.8.10)
|
116
124
|
concurrent-ruby (~> 1.0)
|
117
125
|
jaro_winkler (1.5.4)
|
118
126
|
jwt (2.2.2)
|
119
|
-
loofah (2.
|
127
|
+
loofah (2.9.1)
|
120
128
|
crass (~> 1.0.2)
|
121
129
|
nokogiri (>= 1.5.9)
|
122
130
|
mail (2.7.1)
|
@@ -125,20 +133,24 @@ GEM
|
|
125
133
|
mimemagic (~> 0.3.2)
|
126
134
|
memoist (0.16.2)
|
127
135
|
method_source (1.0.0)
|
128
|
-
mimemagic (0.3.
|
129
|
-
|
130
|
-
|
131
|
-
|
136
|
+
mimemagic (0.3.10)
|
137
|
+
nokogiri (~> 1)
|
138
|
+
rake
|
139
|
+
mini_mime (1.1.0)
|
140
|
+
mini_portile2 (2.5.0)
|
141
|
+
minitest (5.14.4)
|
132
142
|
multi_json (1.15.0)
|
133
143
|
multipart-post (2.1.1)
|
134
|
-
nio4r (2.5.
|
135
|
-
nokogiri (1.
|
136
|
-
mini_portile2 (~> 2.
|
144
|
+
nio4r (2.5.7)
|
145
|
+
nokogiri (1.11.3)
|
146
|
+
mini_portile2 (~> 2.5.0)
|
147
|
+
racc (~> 1.4)
|
137
148
|
os (1.1.1)
|
138
|
-
parallel (1.
|
139
|
-
parser (
|
149
|
+
parallel (1.20.1)
|
150
|
+
parser (3.0.1.0)
|
140
151
|
ast (~> 2.4.1)
|
141
|
-
public_suffix (4.0.
|
152
|
+
public_suffix (4.0.6)
|
153
|
+
racc (1.5.2)
|
142
154
|
rack (2.2.3)
|
143
155
|
rack-test (1.1.0)
|
144
156
|
rack (>= 1.0, < 3)
|
@@ -167,29 +179,30 @@ GEM
|
|
167
179
|
rake (>= 0.8.7)
|
168
180
|
thor (>= 0.18.1, < 2.0)
|
169
181
|
rainbow (3.0.0)
|
170
|
-
rake (13.0.
|
182
|
+
rake (13.0.3)
|
171
183
|
retriable (3.1.2)
|
172
|
-
|
173
|
-
|
174
|
-
rspec-
|
175
|
-
rspec-
|
176
|
-
|
177
|
-
|
178
|
-
|
184
|
+
rexml (3.2.5)
|
185
|
+
rspec (3.10.0)
|
186
|
+
rspec-core (~> 3.10.0)
|
187
|
+
rspec-expectations (~> 3.10.0)
|
188
|
+
rspec-mocks (~> 3.10.0)
|
189
|
+
rspec-core (3.10.1)
|
190
|
+
rspec-support (~> 3.10.0)
|
191
|
+
rspec-expectations (3.10.1)
|
179
192
|
diff-lcs (>= 1.2.0, < 2.0)
|
180
|
-
rspec-support (~> 3.
|
181
|
-
rspec-mocks (3.
|
193
|
+
rspec-support (~> 3.10.0)
|
194
|
+
rspec-mocks (3.10.2)
|
182
195
|
diff-lcs (>= 1.2.0, < 2.0)
|
183
|
-
rspec-support (~> 3.
|
184
|
-
rspec-rails (
|
185
|
-
actionpack (>=
|
186
|
-
activesupport (>=
|
187
|
-
railties (>=
|
188
|
-
rspec-core (~> 3.
|
189
|
-
rspec-expectations (~> 3.
|
190
|
-
rspec-mocks (~> 3.
|
191
|
-
rspec-support (~> 3.
|
192
|
-
rspec-support (3.
|
196
|
+
rspec-support (~> 3.10.0)
|
197
|
+
rspec-rails (5.0.1)
|
198
|
+
actionpack (>= 5.2)
|
199
|
+
activesupport (>= 5.2)
|
200
|
+
railties (>= 5.2)
|
201
|
+
rspec-core (~> 3.10)
|
202
|
+
rspec-expectations (~> 3.10)
|
203
|
+
rspec-mocks (~> 3.10)
|
204
|
+
rspec-support (~> 3.10)
|
205
|
+
rspec-support (3.10.2)
|
193
206
|
rubocop (0.76.0)
|
194
207
|
jaro_winkler (~> 1.5.1)
|
195
208
|
parallel (~> 1.10)
|
@@ -199,9 +212,11 @@ GEM
|
|
199
212
|
unicode-display_width (>= 1.4.0, < 1.7)
|
200
213
|
rubocop-rspec (1.37.0)
|
201
214
|
rubocop (>= 0.68.1)
|
202
|
-
ruby-progressbar (1.
|
203
|
-
|
204
|
-
|
215
|
+
ruby-progressbar (1.11.0)
|
216
|
+
ruby2_keywords (0.0.4)
|
217
|
+
semantic_logger (4.7.4)
|
218
|
+
concurrent-ruby (~> 1.0)
|
219
|
+
signet (0.15.0)
|
205
220
|
addressable (~> 2.3)
|
206
221
|
faraday (>= 0.17.3, < 2.0)
|
207
222
|
jwt (>= 1.5, < 3.0)
|
@@ -209,18 +224,18 @@ GEM
|
|
209
224
|
sprockets (4.0.2)
|
210
225
|
concurrent-ruby (~> 1.0)
|
211
226
|
rack (> 1, < 3)
|
212
|
-
sprockets-rails (3.2.
|
227
|
+
sprockets-rails (3.2.2)
|
213
228
|
actionpack (>= 4.0)
|
214
229
|
activesupport (>= 4.0)
|
215
230
|
sprockets (>= 3.0.0)
|
216
231
|
sqlite3 (1.4.2)
|
217
|
-
thor (1.0
|
232
|
+
thor (1.1.0)
|
218
233
|
thread_safe (0.3.6)
|
219
|
-
timecop (0.9.
|
220
|
-
tzinfo (1.2.
|
234
|
+
timecop (0.9.4)
|
235
|
+
tzinfo (1.2.9)
|
221
236
|
thread_safe (~> 0.1)
|
222
237
|
unicode-display_width (1.6.1)
|
223
|
-
webmock (3.
|
238
|
+
webmock (3.12.2)
|
224
239
|
addressable (>= 2.3.6)
|
225
240
|
crack (>= 0.3.2)
|
226
241
|
hashdiff (>= 0.4.0, < 2.0.0)
|
@@ -240,9 +255,10 @@ DEPENDENCIES
|
|
240
255
|
rspec-rails
|
241
256
|
rubocop (= 0.76.0)
|
242
257
|
rubocop-rspec (= 1.37.0)
|
258
|
+
semantic_logger
|
243
259
|
sqlite3
|
244
260
|
timecop
|
245
261
|
webmock
|
246
262
|
|
247
263
|
BUNDLED WITH
|
248
|
-
2.
|
264
|
+
2.2.9
|