google-gax 1.0.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8cd0a10641a7e1420289be043083df9265950f90
4
- data.tar.gz: 59814b61241779e9dad2d71dbca9ddaa3f303518
3
+ metadata.gz: 34fe59f1bfcd32a791b319ddb7ac77d8dadf7922
4
+ data.tar.gz: 0d77001cd6917bc5fe0b4bc9960b189437b22e0f
5
5
  SHA512:
6
- metadata.gz: c7f3f07f30bf2382ff4bf38c2a6c2142dc7a72070ccbe14071b9193ebe53ba281b9fac525669179f5dd3fbc845a1b781c7659768d968b549398cbdf2948033ac
7
- data.tar.gz: 683d0a62441eabaf25a7c1c87962ffcc86bc8ee5ff3936daa3a8cc78ec20b6c4daadfb5e85d546854676604e8879eb27a4d9f359a327a3b9c9cc2844d7aeafa1
6
+ metadata.gz: bb35c9359dd55066155c0607a647365a7b75cf0cef86ba7e91dd539542b0437915db0b29c09b00e57a83d48f35161ecfc938e00ea47643c2dbf219c456790742
7
+ data.tar.gz: 00bb1dcce002d4ee67450a5825bfd02d949583b1909707c5dabed153ddf329d00d89ea364b9ac9953830952c40a7e6f8893e815e3e9b3f35d48ec2c1e94ba996
@@ -136,15 +136,15 @@ module Google
136
136
  # @param request [Object]
137
137
  # The initial request object.
138
138
  # @param settings [CallSettings]
139
- # The call settings to enumerate pages.
139
+ # The call settings to enumerate pages
140
140
  # @return [PagedEnumerable]
141
141
  # returning self for further uses.
142
- def start(api_call, request, settings)
142
+ def start(api_call, request, settings, block)
143
143
  @func = api_call
144
144
  @request = request
145
145
  page_token = settings.page_token
146
146
  @request[@request_page_token_field] = page_token if page_token
147
- @page = @page.dup_with(@func.call(@request))
147
+ @page = @page.dup_with(@func.call(@request, block))
148
148
  self
149
149
  end
150
150
 
@@ -218,12 +218,16 @@ module Google
218
218
  # @param settings [CallSettings] provides the settings for this call
219
219
  # @param params_extractor [Proc] extracts routing header params from the
220
220
  # request
221
+ # @param exception_transformer [Proc] if an API exception occurs this
222
+ # transformer is given the original exception for custom processing
223
+ # instead of raising the error directly
221
224
  # @return [Proc] a bound method on a request stub used to make an rpc call
222
225
  # @raise [StandardError] if +settings+ has incompatible values,
223
226
  # e.g, if bundling and page_streaming are both configured
224
- def create_api_call(func, settings, params_extractor: nil)
225
- api_caller = proc do |api_call, request|
226
- api_call.call(request)
227
+ def create_api_call(func, settings, params_extractor: nil,
228
+ exception_transformer: nil)
229
+ api_caller = proc do |api_call, request, _settings, block|
230
+ api_call.call(request, block)
227
231
  end
228
232
 
229
233
  if settings.page_descriptor
@@ -239,7 +243,7 @@ module Google
239
243
  api_caller = bundleable(settings.bundle_descriptor)
240
244
  end
241
245
 
242
- proc do |request, options = nil|
246
+ proc do |request, options = nil, &block|
243
247
  this_settings = settings.merge(options)
244
248
  if params_extractor
245
249
  params = params_extractor.call(request)
@@ -247,16 +251,21 @@ module Google
247
251
  end
248
252
  api_call = if settings.retry_codes?
249
253
  retryable(func, this_settings.retry_options,
250
- this_settings.kwargs)
254
+ this_settings.metadata)
251
255
  else
252
256
  add_timeout_arg(func, this_settings.timeout,
253
- this_settings.kwargs)
257
+ this_settings.metadata)
254
258
  end
255
259
  begin
256
- api_caller.call(api_call, request, this_settings)
260
+ api_caller.call(api_call, request, this_settings, block)
257
261
  rescue *settings.errors => e
258
- error_class = Google::Gax.from_error e
259
- raise error_class.new('RPC failed')
262
+ error_class = Google::Gax.from_error(e)
263
+ error = error_class.new('RPC failed')
264
+ raise error if exception_transformer.nil?
265
+ exception_transformer.call error
266
+ rescue StandardError => error
267
+ raise error if exception_transformer.nil?
268
+ exception_transformer.call error
260
269
  end
261
270
  end
262
271
  end
@@ -277,8 +286,9 @@ module Google
277
286
  # @return [Proc] A proc takes the API call's request and returns
278
287
  # an Event object.
279
288
  def bundleable(desc)
280
- proc do |api_call, request, settings|
281
- return api_call(request) unless settings.bundler
289
+ proc do |api_call, request, settings, block|
290
+ return api_call(request, block) unless settings.bundler
291
+ raise 'Bundling calls cannot accept blocks' if block
282
292
  the_id = Google::Gax.compute_bundle_id(
283
293
  request,
284
294
  desc.request_discriminator_fields
@@ -316,7 +326,7 @@ module Google
316
326
  def with_routing_header(settings, params)
317
327
  routing_header = params.map { |k, v| "#{k}=#{v}" }.join('&')
318
328
  options = CallOptions.new(
319
- kwargs: { 'x-goog-request-params' => routing_header }
329
+ metadata: { 'x-goog-request-params' => routing_header }
320
330
  )
321
331
  settings.merge(options)
322
332
  end
@@ -328,8 +338,9 @@ module Google
328
338
  # @param retry_options [RetryOptions] Configures the exceptions
329
339
  # upon which the proc should retry, and the parameters to the
330
340
  # exponential backoff retry algorithm.
341
+ # @param metadata [Hash] request metadata headers
331
342
  # @return [Proc] A proc that will retry on exception.
332
- def retryable(a_func, retry_options, kwargs)
343
+ def retryable(a_func, retry_options, metadata)
333
344
  delay_mult = retry_options.backoff_settings.retry_delay_multiplier
334
345
  max_delay = (retry_options.backoff_settings.max_retry_delay_millis /
335
346
  MILLIS_PER_SECOND)
@@ -339,13 +350,19 @@ module Google
339
350
  total_timeout = (retry_options.backoff_settings.total_timeout_millis /
340
351
  MILLIS_PER_SECOND)
341
352
 
342
- proc do |request|
353
+ proc do |request, block|
343
354
  delay = retry_options.backoff_settings.initial_retry_delay_millis
344
355
  timeout = (retry_options.backoff_settings.initial_rpc_timeout_millis /
345
356
  MILLIS_PER_SECOND)
346
357
  deadline = Time.now + total_timeout
347
358
  begin
348
- a_func.call(request, deadline: Time.now + timeout, metadata: kwargs)
359
+ op = a_func.call(request,
360
+ deadline: Time.now + timeout,
361
+ metadata: metadata,
362
+ return_op: true)
363
+ res = op.execute
364
+ block.call res, op if block
365
+ res
349
366
  rescue => exception
350
367
  unless exception.respond_to?(:code) &&
351
368
  retry_options.retry_codes.include?(exception.code)
@@ -372,10 +389,17 @@ module Google
372
389
  # @param a_func [Proc] a proc to be updated
373
390
  # @param timeout [Numeric] to be added to the original proc as it
374
391
  # final positional arg.
392
+ # @param metadata [Hash] request metadata headers
375
393
  # @return [Proc] the original proc updated to the timeout arg
376
- def add_timeout_arg(a_func, timeout, kwargs)
377
- proc do |request|
378
- a_func.call(request, deadline: Time.now + timeout, metadata: kwargs)
394
+ def add_timeout_arg(a_func, timeout, metadata)
395
+ proc do |request, block|
396
+ op = a_func.call(request,
397
+ deadline: Time.now + timeout,
398
+ metadata: metadata,
399
+ return_op: true)
400
+ res = op.execute
401
+ block.call op if block
402
+ res
379
403
  end
380
404
  end
381
405
 
@@ -42,11 +42,11 @@ module Google
42
42
  # @return [Object]
43
43
  # @!attribute [r] bundle_descriptor
44
44
  # @return [BundleDescriptor]
45
- # @!attribute [r] kwargs
45
+ # @!attribute [r] metadata
46
46
  # @return [Hash]
47
47
  class CallSettings
48
48
  attr_reader :timeout, :retry_options, :page_descriptor, :page_token,
49
- :bundler, :bundle_descriptor, :kwargs, :errors
49
+ :bundler, :bundle_descriptor, :metadata, :errors
50
50
 
51
51
  # @param timeout [Numeric] The client-side timeout for API calls. This
52
52
  # parameter is ignored for retrying calls.
@@ -62,20 +62,22 @@ module Google
62
62
  # performed.
63
63
  # @param bundle_descriptor [BundleDescriptor] indicates the structure of
64
64
  # the bundle. If nil, bundling is not performed.
65
+ # @param metadata [Hash] the request header params.
65
66
  # @param kwargs [Hash]
66
- # Additional keyword argments to be passed to the API call.
67
+ # Deprecated, if set this will be merged with the metadata field.
67
68
  # @param errors [Array<Exception>]
68
69
  # Configures the exceptions to wrap with GaxError.
69
70
  def initialize(timeout: 30, retry_options: nil, page_descriptor: nil,
70
71
  page_token: nil, bundler: nil, bundle_descriptor: nil,
71
- kwargs: {}, errors: [])
72
+ metadata: {}, kwargs: {}, errors: [])
72
73
  @timeout = timeout
73
74
  @retry_options = retry_options
74
75
  @page_descriptor = page_descriptor
75
76
  @page_token = page_token
76
77
  @bundler = bundler
77
78
  @bundle_descriptor = bundle_descriptor
78
- @kwargs = kwargs
79
+ @metadata = metadata
80
+ @metadata.merge!(kwargs) if kwargs && metadata
79
81
  @errors = errors
80
82
  end
81
83
 
@@ -101,7 +103,7 @@ module Google
101
103
  page_token: @page_token,
102
104
  bundler: @bundler,
103
105
  bundle_descriptor: @bundle_descriptor,
104
- kwargs: @kwargs,
106
+ metadata: @metadata,
105
107
  errors: @errors)
106
108
  end
107
109
 
@@ -121,8 +123,8 @@ module Google
121
123
  options.page_token
122
124
  end
123
125
 
124
- kwargs = @kwargs.dup
125
- kwargs.update(options.kwargs) if options.kwargs != :OPTION_INHERIT
126
+ metadata = (metadata.dup if metadata) || {}
127
+ metadata.update(options.metadata) if options.metadata != :OPTION_INHERIT
126
128
 
127
129
  CallSettings.new(timeout: timeout,
128
130
  retry_options: retry_options,
@@ -130,7 +132,7 @@ module Google
130
132
  page_token: page_token,
131
133
  bundler: @bundler,
132
134
  bundle_descriptor: @bundle_descriptor,
133
- kwargs: kwargs,
135
+ metadata: metadata,
134
136
  errors: @errors)
135
137
  end
136
138
  end
@@ -144,10 +146,13 @@ module Google
144
146
  # @return [RetryOptions, :OPTION_INHERIT]
145
147
  # @!attribute [r] page_token
146
148
  # @return [Object, :OPTION_INHERIT, :INITIAL_PAGE]
149
+ # @!attribute [r] metadata
150
+ # @return [Hash, :OPTION_INHERIT]
147
151
  # @!attribute [r] kwargs
148
- # @return [Hash, :OPTION_INHERIT]
152
+ # @return [Hash, :OPTION_INHERIT] deprecated, use metadata instead
149
153
  class CallOptions
150
- attr_reader :timeout, :retry_options, :page_token, :kwargs
154
+ attr_reader :timeout, :retry_options, :page_token, :metadata
155
+ alias kwargs metadata
151
156
 
152
157
  # @param timeout [Numeric, :OPTION_INHERIT]
153
158
  # The client-side timeout for API calls.
@@ -157,16 +162,19 @@ module Google
157
162
  # @param page_token [Object, :OPTION_INHERIT]
158
163
  # If set and the call is configured for page streaming, page streaming
159
164
  # is starting with this page_token.
165
+ # @param metadata [Hash, :OPTION_INHERIT] the request header params.
160
166
  # @param kwargs [Hash, :OPTION_INHERIT]
161
- # Additional keyword argments to be passed to the API call.
167
+ # Deprecated, if set this will be merged with the metadata field.
162
168
  def initialize(timeout: :OPTION_INHERIT,
163
169
  retry_options: :OPTION_INHERIT,
164
170
  page_token: :OPTION_INHERIT,
171
+ metadata: :OPTION_INHERIT,
165
172
  kwargs: :OPTION_INHERIT)
166
173
  @timeout = timeout
167
174
  @retry_options = retry_options
168
175
  @page_token = page_token
169
- @kwargs = kwargs
176
+ @metadata = metadata
177
+ @metadata.merge!(kwargs) if kwargs.is_a?(Hash) && metadata.is_a?(Hash)
170
178
  end
171
179
  end
172
180
 
@@ -466,17 +474,22 @@ module Google
466
474
  # @param page_descriptors [Hash{String => PageDescriptor}] A
467
475
  # dictionary of method names to PageDescriptor objects for
468
476
  # methods that are page streaming-enabled.
477
+ # @param metadata [Hash]
478
+ # Header params to be passed to the API call.
469
479
  # @param kwargs [Hash]
470
- # Additional keyword argments to be passed to the API call.
480
+ # Deprecated, same as metadata and if present will be merged with metadata
471
481
  # @param errors [Array<Exception>]
472
482
  # Configures the exceptions to wrap with GaxError.
473
483
  # @return [CallSettings, nil] A CallSettings, or nil if the
474
484
  # service is not found in the config.
475
485
  def construct_settings(service_name, client_config, config_overrides,
476
486
  retry_names, timeout, bundle_descriptors: {},
477
- page_descriptors: {}, kwargs: {}, errors: [])
487
+ page_descriptors: {}, metadata: {}, kwargs: {},
488
+ errors: [])
478
489
  defaults = {}
479
490
 
491
+ metadata.merge!(kwargs) if kwargs.is_a?(Hash) && metadata.is_a?(Hash)
492
+
480
493
  service_config = client_config.fetch('interfaces', {})[service_name]
481
494
  return nil unless service_config
482
495
 
@@ -509,7 +522,7 @@ module Google
509
522
  page_descriptor: page_descriptors[snake_name],
510
523
  bundler: construct_bundling(bundling_config, bundle_descriptor),
511
524
  bundle_descriptor: bundle_descriptor,
512
- kwargs: kwargs,
525
+ metadata: metadata,
513
526
  errors: errors
514
527
  )
515
528
  end
@@ -29,6 +29,6 @@
29
29
 
30
30
  module Google
31
31
  module Gax
32
- VERSION = '1.0.1'.freeze
32
+ VERSION = '1.2.0'.freeze
33
33
  end
34
34
  end
@@ -56,10 +56,15 @@ describe Google::Gax do
56
56
  it 'calls api call' do
57
57
  settings = CallSettings.new
58
58
  deadline_arg = nil
59
+
60
+ op = double('op')
61
+ allow(op).to receive(:execute) { 42 }
62
+
59
63
  func = proc do |deadline: nil, **_kwargs|
60
64
  deadline_arg = deadline
61
- 42
65
+ op
62
66
  end
67
+
63
68
  my_callable = Google::Gax.create_api_call(func, settings)
64
69
  expect(my_callable.call(nil)).to eq(42)
65
70
  expect(deadline_arg).to be_a(Time)
@@ -71,10 +76,65 @@ describe Google::Gax do
71
76
  end
72
77
  end
73
78
 
79
+ describe 'create_api_call with block options' do
80
+ it 'calls with block' do
81
+ adder = 0
82
+ settings = CallSettings.new
83
+
84
+ op = double('op', request: 3)
85
+ allow(op).to receive(:execute) { 2 + op.request + adder }
86
+
87
+ func = proc do |request, _deadline: nil, **_kwargs|
88
+ expect(request).to eq(3)
89
+ op
90
+ end
91
+
92
+ my_callable = Google::Gax.create_api_call(func, settings)
93
+ expect(my_callable.call(3)).to eq(5)
94
+ expect(my_callable.call(3) { adder = 5 }).to eq(5)
95
+ expect(my_callable.call(3)).to eq(10)
96
+ end
97
+ end
98
+
99
+ describe 'custom exceptions' do
100
+ it 'traps an exception' do
101
+ settings = CallSettings.new
102
+
103
+ transformer = proc do |ex|
104
+ expect(ex).to be_a(Google::Gax::RetryError)
105
+ raise CustomException.new('', FAKE_STATUS_CODE_2)
106
+ end
107
+
108
+ func = proc do
109
+ raise Google::Gax::RetryError.new('')
110
+ end
111
+ my_callable = Google::Gax.create_api_call(
112
+ func, settings, exception_transformer: transformer
113
+ )
114
+ expect { my_callable.call }.to raise_error(CustomException)
115
+ end
116
+
117
+ it 'traps a wrapped exception' do
118
+ settings = CallSettings.new(errors: [CustomException])
119
+
120
+ transformer = proc do |ex|
121
+ expect(ex).to be_a(Google::Gax::GaxError)
122
+ raise Exception.new('')
123
+ end
124
+
125
+ func = proc do
126
+ raise CustomException.new('', :FAKE_STATUS_CODE_1)
127
+ end
128
+ my_callable = Google::Gax.create_api_call(
129
+ func, settings, exception_transformer: transformer
130
+ )
131
+ expect { my_callable.call }.to raise_error(Exception)
132
+ end
133
+ end
134
+
74
135
  describe 'page streaming' do
75
136
  page_size = 3
76
137
  pages_to_stream = 5
77
-
78
138
  page_descriptor = Google::Gax::PageDescriptor.new('page_token',
79
139
  'next_page_token', 'nums')
80
140
  settings = CallSettings.new(page_descriptor: page_descriptor)
@@ -93,7 +153,13 @@ describe Google::Gax do
93
153
  end
94
154
 
95
155
  it 'iterates over elements' do
96
- my_callable = Google::Gax.create_api_call(func, settings)
156
+ func2 = proc do |request, **kwargs|
157
+ op = double('op')
158
+ allow(op).to receive(:execute) { func.call(request, **kwargs) }
159
+ op
160
+ end
161
+
162
+ my_callable = Google::Gax.create_api_call(func2, settings)
97
163
  expect(my_callable.call('page_token' => 0).to_a).to match_array(
98
164
  (0...(page_size * pages_to_stream))
99
165
  )
@@ -101,7 +167,13 @@ describe Google::Gax do
101
167
  end
102
168
 
103
169
  it 'offers interface for pages' do
104
- my_callable = Google::Gax.create_api_call(func, settings)
170
+ func2 = proc do |request, **kwargs|
171
+ op = double('op')
172
+ allow(op).to receive(:execute) { func.call(request, **kwargs) }
173
+ op
174
+ end
175
+
176
+ my_callable = Google::Gax.create_api_call(func2, settings)
105
177
  stream = my_callable.call('page_token' => 0)
106
178
  page = stream.page
107
179
  expect(page.to_a).to eq((0...page_size).to_a)
@@ -114,8 +186,14 @@ describe Google::Gax do
114
186
  end
115
187
 
116
188
  it 'starts from the specified page_token' do
189
+ func2 = proc do |request, **kwargs|
190
+ op = double('op')
191
+ allow(op).to receive(:execute) { func.call(request, **kwargs) }
192
+ op
193
+ end
194
+
117
195
  my_settings = settings.merge(Google::Gax::CallOptions.new(page_token: 3))
118
- my_callable = Google::Gax.create_api_call(func, my_settings)
196
+ my_callable = Google::Gax.create_api_call(func2, my_settings)
119
197
  expect(my_callable.call({}).to_a).to match_array(
120
198
  3...(page_size * pages_to_stream)
121
199
  )
@@ -188,8 +266,13 @@ describe Google::Gax do
188
266
  func = proc do |request, _|
189
267
  request['elements'].count
190
268
  end
269
+ func2 = proc do |request, **kwargs|
270
+ op = double('op')
271
+ allow(op).to receive(:execute) { func.call(request, **kwargs) }
272
+ op
273
+ end
191
274
 
192
- callable = Google::Gax.create_api_call(func, settings)
275
+ callable = Google::Gax.create_api_call(func2, settings)
193
276
 
194
277
  first = callable.call('elements' => [0] * 5)
195
278
  expect(first).to be_an_instance_of Google::Gax::Event
@@ -207,11 +290,16 @@ describe Google::Gax do
207
290
  metadata_arg = metadata
208
291
  42
209
292
  end
293
+ func2 = proc do |request, **kwargs|
294
+ op = double('op')
295
+ allow(op).to receive(:execute) { func.call(request, **kwargs) }
296
+ op
297
+ end
210
298
  params_extractor = proc do |request|
211
299
  { 'name' => request[:name], 'book.read' => request[:book][:read] }
212
300
  end
213
301
  my_callable = Google::Gax.create_api_call(
214
- func, settings, params_extractor: params_extractor
302
+ func2, settings, params_extractor: params_extractor
215
303
  )
216
304
  expect(my_callable.call(name: 'foo', book: { read: true })).to eq(42)
217
305
  expect(metadata_arg).to eq(
@@ -241,7 +329,13 @@ describe Google::Gax do
241
329
  raise CustomException.new('', FAKE_STATUS_CODE_1) if to_attempt > 0
242
330
  1729
243
331
  end
244
- my_callable = Google::Gax.create_api_call(func, settings)
332
+ func2 = proc do |request, **kwargs|
333
+ op = double('op')
334
+ allow(op).to receive(:execute) { func.call(request, **kwargs) }
335
+ op
336
+ end
337
+
338
+ my_callable = Google::Gax.create_api_call(func2, settings)
245
339
  expect(my_callable.call).to eq(1729)
246
340
  expect(to_attempt).to eq(0)
247
341
  expect(deadline_arg).to be_a(Time)
@@ -318,7 +412,12 @@ describe Google::Gax do
318
412
 
319
413
  it 'does not retry even when no responses' do
320
414
  func = proc { nil }
321
- my_callable = Google::Gax.create_api_call(func, settings)
415
+ func2 = proc do |request, **kwargs|
416
+ op = double('op')
417
+ allow(op).to receive(:execute) { func.call(request, **kwargs) }
418
+ op
419
+ end
420
+ my_callable = Google::Gax.create_api_call(func2, settings)
322
421
  expect(my_callable.call).to be_nil
323
422
  end
324
423
 
@@ -91,7 +91,7 @@ describe Google::Gax do
91
91
  SERVICE_NAME, A_CONFIG, {}, RETRY_DICT, 30,
92
92
  bundle_descriptors: BUNDLE_DESCRIPTORS,
93
93
  page_descriptors: PAGE_DESCRIPTORS,
94
- kwargs: { 'key' => 'value' },
94
+ metadata: { 'key' => 'value' },
95
95
  errors: [StandardError]
96
96
  )
97
97
  settings = defaults['bundling_method']
@@ -104,7 +104,7 @@ describe Google::Gax do
104
104
  expect(settings.retry_options.backoff_settings).to be_a(
105
105
  Google::Gax::BackoffSettings
106
106
  )
107
- expect(settings.kwargs).to match('key' => 'value')
107
+ expect(settings.metadata).to match('key' => 'value')
108
108
  expect(settings.errors).to match_array([StandardError])
109
109
 
110
110
  settings = defaults['some_https_page_streaming_method']
@@ -117,7 +117,7 @@ describe Google::Gax do
117
117
  expect(settings.retry_options.backoff_settings).to be_a(
118
118
  Google::Gax::BackoffSettings
119
119
  )
120
- expect(settings.kwargs).to match('key' => 'value')
120
+ expect(settings.metadata).to match('key' => 'value')
121
121
  expect(settings.errors).to match_array([StandardError])
122
122
  end
123
123
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-gax
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Google API Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-21 00:00:00.000000000 Z
11
+ date: 2018-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: googleauth
@@ -215,7 +215,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
215
215
  version: '0'
216
216
  requirements: []
217
217
  rubyforge_project:
218
- rubygems_version: 2.6.12
218
+ rubygems_version: 2.6.14
219
219
  signing_key:
220
220
  specification_version: 4
221
221
  summary: Aids the development of APIs for clients and servers based on GRPC and Google