gapic-common 0.21.1 → 0.24.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 +28 -0
- data/lib/gapic/common/version.rb +1 -1
- data/lib/gapic/grpc/service_stub/channel.rb +4 -2
- data/lib/gapic/grpc/service_stub/channel_pool.rb +9 -2
- data/lib/gapic/grpc/service_stub/rpc_call.rb +120 -12
- data/lib/gapic/grpc/service_stub.rb +15 -3
- data/lib/gapic/headers.rb +5 -1
- data/lib/gapic/logging_concerns.rb +210 -0
- data/lib/gapic/rest/client_stub.rb +91 -18
- data/lib/gapic/universe_domain_concerns.rb +2 -2
- metadata +54 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dcd83f8068cc42ed2b87bab10ef10ce8f3b3ac6cabc5980c1b52ae1279a9a7b8
|
4
|
+
data.tar.gz: 80137d53ab13ad21af6a083f3f72405952ff844b3b3a49ca71f3ee7339518587
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ff6fac4cf4699bfc105c27a179c3d733c657ea555ed5e35213f34da1a4ea20dd069b947f017b0d3da52f491f55d7a9433cd00e33fe81bb659f7b2015a77cbd9
|
7
|
+
data.tar.gz: 047d76f0a9627aedcc4cfe5658b21fbf9ba7371ea9fb18ec39af4bc84e1fc3e4252853ca5108850dcda681f0a4fb66aafe5cd240f527e72afde6f1709795d45f
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 0.24.0 (2024-12-05)
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
* Log requests and responses ([#1112](https://github.com/googleapis/gapic-generator-ruby/issues/1112))
|
8
|
+
#### Bug Fixes
|
9
|
+
|
10
|
+
* Hardened deadline determination against Time.now hacking ([#942](https://github.com/googleapis/gapic-generator-ruby/issues/942))
|
11
|
+
|
12
|
+
### 0.23.0 (2024-10-15)
|
13
|
+
|
14
|
+
#### Features
|
15
|
+
|
16
|
+
* Disable universe domain check if credentials include an explicit request to do so ([#1119](https://github.com/googleapis/gapic-generator-ruby/issues/1119))
|
17
|
+
|
18
|
+
### 0.22.0 (2024-07-17)
|
19
|
+
|
20
|
+
#### Features
|
21
|
+
|
22
|
+
* Support for google-protobuf 4.x
|
23
|
+
* Requires at least Ruby 3.0
|
24
|
+
|
25
|
+
### 0.21.2 (2024-07-02)
|
26
|
+
|
27
|
+
#### Bug Fixes
|
28
|
+
|
29
|
+
* Start requiring ostruct in generated test helper files ([#1065](https://github.com/googleapis/gapic-generator-ruby/issues/1065))
|
30
|
+
|
3
31
|
### 0.21.1 (2023-12-14)
|
4
32
|
|
5
33
|
#### Bug Fixes
|
data/lib/gapic/common/version.rb
CHANGED
@@ -32,12 +32,13 @@ module Gapic
|
|
32
32
|
# Creates a new Channel instance
|
33
33
|
#
|
34
34
|
def initialize grpc_stub_class, endpoint:, credentials:, channel_args: nil, interceptors: nil,
|
35
|
-
on_channel_create: nil
|
35
|
+
on_channel_create: nil, stub_logger: nil
|
36
36
|
@grpc_stub_class = grpc_stub_class
|
37
37
|
@endpoint = endpoint
|
38
38
|
@credentials = credentials
|
39
39
|
@channel_args = Hash channel_args
|
40
40
|
@interceptors = Array interceptors
|
41
|
+
@stub_logger = stub_logger
|
41
42
|
@concurrent_streams = 0
|
42
43
|
@mutex = Mutex.new
|
43
44
|
setup_grpc_stub
|
@@ -88,7 +89,8 @@ module Gapic
|
|
88
89
|
def call_rpc method_name, request, options: nil, &block
|
89
90
|
@mutex.synchronize { @concurrent_streams += 1 }
|
90
91
|
begin
|
91
|
-
|
92
|
+
meth = @grpc_stub.method method_name
|
93
|
+
rpc_call = RpcCall.new meth, stub_logger: @stub_logger, method_name: method_name
|
92
94
|
response = rpc_call.call request, options: options, &block
|
93
95
|
response
|
94
96
|
ensure
|
@@ -30,7 +30,12 @@ module Gapic
|
|
30
30
|
##
|
31
31
|
# Initialize an instance of ServiceStub::ChannelPool
|
32
32
|
#
|
33
|
-
def initialize grpc_stub_class,
|
33
|
+
def initialize grpc_stub_class,
|
34
|
+
endpoint:, credentials:,
|
35
|
+
channel_args: nil,
|
36
|
+
interceptors: nil,
|
37
|
+
config: nil,
|
38
|
+
stub_logger: nil
|
34
39
|
if credentials.is_a? ::GRPC::Core::Channel
|
35
40
|
raise ArgumentError, "Can't create a channel pool with GRPC::Core::Channel as credentials"
|
36
41
|
end
|
@@ -41,6 +46,7 @@ module Gapic
|
|
41
46
|
@channel_args = channel_args
|
42
47
|
@interceptors = interceptors
|
43
48
|
@config = config || Configuration.new
|
49
|
+
@stub_logger = stub_logger
|
44
50
|
|
45
51
|
@channels = (1..@config.channel_count).map { create_channel }
|
46
52
|
end
|
@@ -49,7 +55,8 @@ module Gapic
|
|
49
55
|
# Creates a new channel.
|
50
56
|
def create_channel
|
51
57
|
Channel.new @grpc_stub_class, endpoint: @endpoint, credentials: @credentials, channel_args: @channel_args,
|
52
|
-
interceptors: @interceptors, on_channel_create: @config.on_channel_create
|
58
|
+
interceptors: @interceptors, on_channel_create: @config.on_channel_create,
|
59
|
+
stub_logger: @stub_logger
|
53
60
|
end
|
54
61
|
|
55
62
|
##
|
@@ -13,6 +13,7 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
require "gapic/call_options"
|
16
|
+
require "gapic/logging_concerns"
|
16
17
|
require "grpc/errors"
|
17
18
|
|
18
19
|
module Gapic
|
@@ -32,8 +33,11 @@ module Gapic
|
|
32
33
|
#
|
33
34
|
# @param stub_method [Proc] Used to make a bare rpc call.
|
34
35
|
#
|
35
|
-
def initialize stub_method
|
36
|
+
def initialize stub_method, stub_logger: nil, method_name: nil
|
36
37
|
@stub_method = stub_method
|
38
|
+
@stub_logger = stub_logger
|
39
|
+
@method_name = method_name
|
40
|
+
@request_id = LoggingConcerns.random_uuid4
|
37
41
|
end
|
38
42
|
|
39
43
|
##
|
@@ -44,7 +48,8 @@ module Gapic
|
|
44
48
|
# customize the options object, using keys that match the arguments for {Gapic::CallOptions.new}. This object
|
45
49
|
# should only be used once.
|
46
50
|
#
|
47
|
-
# @yield [response, operation] Access the response along with the RPC operation.
|
51
|
+
# @yield [response, operation] Access the response along with the RPC operation. Additionally, throwing
|
52
|
+
# `:response, obj` within the block will change the return value to `obj`.
|
48
53
|
# @yieldparam response [Object] The response object.
|
49
54
|
# @yieldparam operation [::GRPC::ActiveCall::Operation] The RPC operation for the response.
|
50
55
|
#
|
@@ -91,7 +96,7 @@ module Gapic
|
|
91
96
|
# )
|
92
97
|
# response = echo_call.call request, options: options
|
93
98
|
#
|
94
|
-
# @example Accessing the
|
99
|
+
# @example Accessing the RPC operation using a block:
|
95
100
|
# require "google/showcase/v1beta1/echo_pb"
|
96
101
|
# require "google/showcase/v1beta1/echo_services_pb"
|
97
102
|
# require "gapic"
|
@@ -107,8 +112,8 @@ module Gapic
|
|
107
112
|
# echo_call = Gapic::ServiceStub::RpcCall.new echo_stub.method :echo
|
108
113
|
#
|
109
114
|
# request = Google::Showcase::V1beta1::EchoRequest.new
|
110
|
-
# echo_call.call request do |
|
111
|
-
# operation.trailing_metadata
|
115
|
+
# metadata = echo_call.call request do |_response, operation|
|
116
|
+
# throw :response, operation.trailing_metadata
|
112
117
|
# end
|
113
118
|
#
|
114
119
|
def call request, options: nil
|
@@ -117,21 +122,27 @@ module Gapic
|
|
117
122
|
deadline = calculate_deadline options
|
118
123
|
metadata = options.metadata
|
119
124
|
|
125
|
+
try_number = 1
|
120
126
|
retried_exception = nil
|
121
127
|
begin
|
128
|
+
request = log_request request, metadata, try_number
|
122
129
|
operation = stub_method.call request, deadline: deadline, metadata: metadata, return_op: true
|
123
130
|
response = operation.execute
|
124
|
-
|
125
|
-
|
131
|
+
catch :response do
|
132
|
+
response = log_response response, try_number
|
133
|
+
yield response, operation if block_given?
|
134
|
+
response
|
135
|
+
end
|
126
136
|
rescue ::GRPC::DeadlineExceeded => e
|
137
|
+
log_response e, try_number
|
127
138
|
raise Gapic::GRPC::DeadlineExceededError.new e.message, root_cause: retried_exception
|
128
139
|
rescue StandardError => e
|
129
|
-
|
130
|
-
|
131
|
-
end
|
140
|
+
e = normalize_exception e
|
141
|
+
log_response e, try_number
|
132
142
|
|
133
143
|
if check_retry?(deadline) && options.retry_policy.call(e)
|
134
144
|
retried_exception = e
|
145
|
+
try_number += 1
|
135
146
|
retry
|
136
147
|
end
|
137
148
|
|
@@ -145,13 +156,110 @@ module Gapic
|
|
145
156
|
return if options.timeout.nil?
|
146
157
|
return if options.timeout.negative?
|
147
158
|
|
148
|
-
|
159
|
+
current_time + options.timeout
|
149
160
|
end
|
150
161
|
|
151
162
|
def check_retry? deadline
|
152
163
|
return true if deadline.nil?
|
153
164
|
|
154
|
-
deadline >
|
165
|
+
deadline > current_time
|
166
|
+
end
|
167
|
+
|
168
|
+
def current_time
|
169
|
+
# An alternative way of saying Time.now without actually calling
|
170
|
+
# Time.now. This allows clients that replace Time.now (e.g. via the
|
171
|
+
# timecop gem) to do so without interfering with the deadline.
|
172
|
+
nanos = Process.clock_gettime Process::CLOCK_REALTIME, :nanosecond
|
173
|
+
secs_part = nanos / 1_000_000_000
|
174
|
+
nsecs_part = nanos % 1_000_000_000
|
175
|
+
Time.at secs_part, nsecs_part, :nanosecond
|
176
|
+
end
|
177
|
+
|
178
|
+
def normalize_exception exception
|
179
|
+
if exception.is_a?(::GRPC::Unavailable) && /Signet::AuthorizationError/ =~ exception.message
|
180
|
+
exception = Gapic::GRPC::AuthorizationError.new exception.message.gsub(%r{^\d+:}, "")
|
181
|
+
end
|
182
|
+
exception
|
183
|
+
end
|
184
|
+
|
185
|
+
def log_request request, metadata, try_number
|
186
|
+
return request unless @stub_logger
|
187
|
+
@stub_logger.info do |entry|
|
188
|
+
entry.set_system_name
|
189
|
+
entry.set_service
|
190
|
+
entry.set "rpcName", @method_name
|
191
|
+
entry.set "retryAttempt", try_number
|
192
|
+
entry.set "requestId", @request_id
|
193
|
+
entry.message =
|
194
|
+
if request.is_a? Enumerable
|
195
|
+
"Sending stream to #{entry.service}.#{@method_name} (try #{try_number})"
|
196
|
+
else
|
197
|
+
"Sending request to #{entry.service}.#{@method_name} (try #{try_number})"
|
198
|
+
end
|
199
|
+
end
|
200
|
+
loggable_metadata = metadata.to_h rescue {}
|
201
|
+
if request.is_a? Enumerable
|
202
|
+
request.lazy.map do |req|
|
203
|
+
log_single_request req, loggable_metadata
|
204
|
+
end
|
205
|
+
else
|
206
|
+
log_single_request request, loggable_metadata
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def log_single_request request, metadata
|
211
|
+
request_content = request.respond_to?(:to_h) ? (request.to_h rescue {}) : request.to_s
|
212
|
+
if !request_content.empty? || !metadata.empty?
|
213
|
+
@stub_logger.debug do |entry|
|
214
|
+
entry.set "requestId", @request_id
|
215
|
+
entry.set "request", request_content
|
216
|
+
entry.set "headers", metadata
|
217
|
+
entry.message = "(request payload as #{request.class})"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
request
|
221
|
+
end
|
222
|
+
|
223
|
+
def log_response response, try_number
|
224
|
+
return response unless @stub_logger
|
225
|
+
@stub_logger.info do |entry|
|
226
|
+
entry.set_system_name
|
227
|
+
entry.set_service
|
228
|
+
entry.set "rpcName", @method_name
|
229
|
+
entry.set "retryAttempt", try_number
|
230
|
+
entry.set "requestId", @request_id
|
231
|
+
case response
|
232
|
+
when StandardError
|
233
|
+
entry.set "exception", response.to_s
|
234
|
+
entry.message = "Received error for #{entry.service}.#{@method_name} (try #{try_number}): #{response}"
|
235
|
+
when Enumerable
|
236
|
+
entry.message = "Receiving stream for #{entry.service}.#{@method_name} (try #{try_number})"
|
237
|
+
else
|
238
|
+
entry.message = "Received response for #{entry.service}.#{@method_name} (try #{try_number})"
|
239
|
+
end
|
240
|
+
end
|
241
|
+
case response
|
242
|
+
when StandardError
|
243
|
+
response
|
244
|
+
when Enumerable
|
245
|
+
response.lazy.map do |resp|
|
246
|
+
log_single_response resp
|
247
|
+
end
|
248
|
+
else
|
249
|
+
log_single_response response
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def log_single_response response
|
254
|
+
response_content = response.respond_to?(:to_h) ? (response.to_h rescue {}) : response.to_s
|
255
|
+
unless response_content.empty?
|
256
|
+
@stub_logger.debug do |entry|
|
257
|
+
entry.set "requestId", @request_id
|
258
|
+
entry.set "response", response_content
|
259
|
+
entry.message = "(response payload as #{response.class})"
|
260
|
+
end
|
261
|
+
end
|
262
|
+
response
|
155
263
|
end
|
156
264
|
end
|
157
265
|
end
|
@@ -17,6 +17,7 @@ require "googleauth"
|
|
17
17
|
require "gapic/grpc/service_stub/rpc_call"
|
18
18
|
require "gapic/grpc/service_stub/channel"
|
19
19
|
require "gapic/grpc/service_stub/channel_pool"
|
20
|
+
require "gapic/logging_concerns"
|
20
21
|
require "gapic/universe_domain_concerns"
|
21
22
|
|
22
23
|
module Gapic
|
@@ -32,6 +33,7 @@ module Gapic
|
|
32
33
|
#
|
33
34
|
class ServiceStub
|
34
35
|
include UniverseDomainConcerns
|
36
|
+
include LoggingConcerns
|
35
37
|
|
36
38
|
attr_reader :grpc_stub
|
37
39
|
attr_reader :channel_pool
|
@@ -64,6 +66,9 @@ module Gapic
|
|
64
66
|
# be used for intercepting calls before they are executed Interceptors are an EXPERIMENTAL API.
|
65
67
|
# @param channel_pool_config [::Gapic::ServiceStub:ChannelPool::Configuration] The configuration for channel
|
66
68
|
# pool. This argument will raise error when `credentials` is provided as a `::GRPC::Core::Channel`.
|
69
|
+
# @param logger [Logger,:default,nil] An explicit logger to use, or one
|
70
|
+
# of the values `:default` (the default) to construct a default logger,
|
71
|
+
# or `nil` to disable logging explicitly.
|
67
72
|
#
|
68
73
|
def initialize grpc_stub_class,
|
69
74
|
credentials:,
|
@@ -72,13 +77,19 @@ module Gapic
|
|
72
77
|
universe_domain: nil,
|
73
78
|
channel_args: nil,
|
74
79
|
interceptors: nil,
|
75
|
-
channel_pool_config: nil
|
80
|
+
channel_pool_config: nil,
|
81
|
+
logger: :default
|
76
82
|
raise ArgumentError, "grpc_stub_class is required" if grpc_stub_class.nil?
|
77
83
|
|
78
84
|
setup_universe_domain universe_domain: universe_domain,
|
79
85
|
endpoint: endpoint,
|
80
86
|
endpoint_template: endpoint_template,
|
81
87
|
credentials: credentials
|
88
|
+
setup_logging logger: logger,
|
89
|
+
system_name: grpc_stub_class,
|
90
|
+
service: grpc_stub_class,
|
91
|
+
endpoint: self.endpoint,
|
92
|
+
client_id: object_id
|
82
93
|
|
83
94
|
@channel_pool = nil
|
84
95
|
@grpc_stub = nil
|
@@ -102,7 +113,7 @@ module Gapic
|
|
102
113
|
end
|
103
114
|
@channel_pool = ChannelPool.new grpc_stub_class, endpoint: endpoint, credentials: credentials,
|
104
115
|
channel_args: channel_args, interceptors: interceptors,
|
105
|
-
config: channel_pool_config
|
116
|
+
config: channel_pool_config, stub_logger: stub_logger
|
106
117
|
end
|
107
118
|
|
108
119
|
def create_grpc_stub grpc_stub_class, endpoint:, credentials:, channel_args: nil, interceptors: nil
|
@@ -201,7 +212,8 @@ module Gapic
|
|
201
212
|
#
|
202
213
|
def call_rpc method_name, request, options: nil, &block
|
203
214
|
if @channel_pool.nil?
|
204
|
-
|
215
|
+
meth = @grpc_stub.method method_name
|
216
|
+
rpc_call = RpcCall.new meth, stub_logger: stub_logger, method_name: method_name
|
205
217
|
rpc_call.call request, options: options, &block
|
206
218
|
else
|
207
219
|
@channel_pool.call_rpc method_name, request, options: options, &block
|
data/lib/gapic/headers.rb
CHANGED
@@ -19,6 +19,8 @@ require "gapic/common/version"
|
|
19
19
|
module Gapic
|
20
20
|
# A collection of common header values.
|
21
21
|
module Headers
|
22
|
+
# rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
23
|
+
|
22
24
|
##
|
23
25
|
# @param ruby_version [String] The ruby version. Defaults to `RUBY_VERSION`.
|
24
26
|
# @param lib_name [String] The client library name.
|
@@ -32,10 +34,10 @@ module Gapic
|
|
32
34
|
# `:grpc` to send the GRPC library version (if defined)
|
33
35
|
# `:rest` to send the REST library version (if defined)
|
34
36
|
# Defaults to `[:grpc]`
|
37
|
+
#
|
35
38
|
def self.x_goog_api_client ruby_version: nil, lib_name: nil, lib_version: nil, gax_version: nil,
|
36
39
|
gapic_version: nil, grpc_version: nil, rest_version: nil, protobuf_version: nil,
|
37
40
|
transports_version_send: [:grpc]
|
38
|
-
|
39
41
|
ruby_version ||= ::RUBY_VERSION
|
40
42
|
gax_version ||= ::Gapic::Common::VERSION
|
41
43
|
grpc_version ||= ::GRPC::VERSION if defined? ::GRPC::VERSION
|
@@ -52,4 +54,6 @@ module Gapic
|
|
52
54
|
x_goog_api_client_header.join " ".freeze
|
53
55
|
end
|
54
56
|
end
|
57
|
+
|
58
|
+
# rubocop:enable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
55
59
|
end
|
@@ -0,0 +1,210 @@
|
|
1
|
+
# Copyright 2024 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require "google/cloud/env"
|
16
|
+
require "google/logging/message"
|
17
|
+
require "google/logging/structured_formatter"
|
18
|
+
|
19
|
+
module Gapic
|
20
|
+
##
|
21
|
+
# A mixin module that handles logging setup for a stub.
|
22
|
+
#
|
23
|
+
module LoggingConcerns
|
24
|
+
##
|
25
|
+
# The logger for this object.
|
26
|
+
#
|
27
|
+
# @return [Logger]
|
28
|
+
#
|
29
|
+
attr_reader :logger
|
30
|
+
|
31
|
+
##
|
32
|
+
# @private
|
33
|
+
# A convenience object used by stub-based logging.
|
34
|
+
#
|
35
|
+
class StubLogger
|
36
|
+
OMIT_FILES = [
|
37
|
+
/^#{Regexp.escape __dir__}/
|
38
|
+
].freeze
|
39
|
+
|
40
|
+
def initialize logger: nil, **kwargs
|
41
|
+
@logger = logger
|
42
|
+
@kwargs = kwargs
|
43
|
+
end
|
44
|
+
|
45
|
+
def log severity
|
46
|
+
return unless @logger
|
47
|
+
locations = caller_locations
|
48
|
+
@logger.add severity do
|
49
|
+
builder = LogEntryBuilder.new(**@kwargs)
|
50
|
+
builder.set_source_location_from locations
|
51
|
+
yield builder
|
52
|
+
builder.build
|
53
|
+
rescue StandardError
|
54
|
+
# Do nothing
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def info &block
|
59
|
+
log Logger::INFO, &block
|
60
|
+
end
|
61
|
+
|
62
|
+
def debug &block
|
63
|
+
log Logger::DEBUG, &block
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# @private
|
68
|
+
# Builder for a log entry, passed to {StubLogger#log}.
|
69
|
+
#
|
70
|
+
class LogEntryBuilder
|
71
|
+
def initialize system_name: nil,
|
72
|
+
service: nil,
|
73
|
+
endpoint: nil,
|
74
|
+
client_id: nil
|
75
|
+
@system_name = system_name
|
76
|
+
@service = service
|
77
|
+
@endpoint = endpoint
|
78
|
+
@client_id = client_id
|
79
|
+
@message = nil
|
80
|
+
@caller_locations = caller_locations
|
81
|
+
@fields = { "clientId" => @client_id }
|
82
|
+
end
|
83
|
+
|
84
|
+
attr_reader :system_name
|
85
|
+
|
86
|
+
attr_reader :service
|
87
|
+
|
88
|
+
attr_reader :endpoint
|
89
|
+
|
90
|
+
attr_accessor :message
|
91
|
+
|
92
|
+
attr_writer :source_location
|
93
|
+
|
94
|
+
attr_reader :fields
|
95
|
+
|
96
|
+
def set name, value
|
97
|
+
fields[name] = value
|
98
|
+
end
|
99
|
+
|
100
|
+
def set_system_name
|
101
|
+
set "system", system_name
|
102
|
+
end
|
103
|
+
|
104
|
+
def set_service
|
105
|
+
set "serviceName", service
|
106
|
+
end
|
107
|
+
|
108
|
+
def set_credentials_fields creds
|
109
|
+
creds = creds.client if creds.respond_to? :client
|
110
|
+
set "credentialsId", creds.object_id
|
111
|
+
set "credentialsType", creds.class.name
|
112
|
+
set "credentialsScope", creds.scope if creds.respond_to? :scope
|
113
|
+
set "useSelfSignedJWT", creds.enable_self_signed_jwt? if creds.respond_to? :enable_self_signed_jwt?
|
114
|
+
set "universeDomain", creds.universe_domain if creds.respond_to? :universe_domain
|
115
|
+
end
|
116
|
+
|
117
|
+
def source_location
|
118
|
+
@source_location ||= Google::Logging::SourceLocation.for_caller omit_files: OMIT_FILES,
|
119
|
+
locations: @caller_locations
|
120
|
+
end
|
121
|
+
|
122
|
+
def set_source_location_from locations
|
123
|
+
@caller_locations = locations
|
124
|
+
@source_location = nil
|
125
|
+
end
|
126
|
+
|
127
|
+
def build
|
128
|
+
Google::Logging::Message.from message: message, source_location: source_location, fields: fields
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
##
|
134
|
+
# @private
|
135
|
+
# Initialize logging concerns.
|
136
|
+
#
|
137
|
+
def setup_logging logger: :default,
|
138
|
+
stream: nil,
|
139
|
+
formatter: nil,
|
140
|
+
level: nil,
|
141
|
+
system_name: nil,
|
142
|
+
service: nil,
|
143
|
+
endpoint: nil,
|
144
|
+
client_id: nil
|
145
|
+
service = LoggingConcerns.normalize_service service
|
146
|
+
system_name = LoggingConcerns.normalize_system_name system_name
|
147
|
+
logging_env = ENV["GOOGLE_SDK_RUBY_LOGGING_GEMS"].to_s.downcase
|
148
|
+
logger = nil if ["false", "none"].include? logging_env
|
149
|
+
if logger == :default
|
150
|
+
logger = nil
|
151
|
+
if ["true", "all"].include?(logging_env) || logging_env.split(",").include?(system_name)
|
152
|
+
stream ||= $stderr
|
153
|
+
level ||= "DEBUG"
|
154
|
+
formatter ||= Google::Logging::StructuredFormatter.new if Google::Cloud::Env.get.logging_agent_expected?
|
155
|
+
logger = Logger.new stream, progname: system_name, level: level, formatter: formatter
|
156
|
+
end
|
157
|
+
end
|
158
|
+
@logger = logger
|
159
|
+
@stub_logger = StubLogger.new logger: logger,
|
160
|
+
system_name: system_name,
|
161
|
+
service: service,
|
162
|
+
endpoint: endpoint,
|
163
|
+
client_id: client_id
|
164
|
+
end
|
165
|
+
|
166
|
+
# @private
|
167
|
+
attr_reader :stub_logger
|
168
|
+
|
169
|
+
class << self
|
170
|
+
# @private
|
171
|
+
def random_uuid4
|
172
|
+
ary = Random.bytes 16
|
173
|
+
ary.setbyte 6, ((ary.getbyte(6) & 0x0f) | 0x40)
|
174
|
+
ary.setbyte 8, ((ary.getbyte(8) & 0x3f) | 0x80)
|
175
|
+
ary.unpack("H8H4H4H4H12").join "-"
|
176
|
+
end
|
177
|
+
|
178
|
+
# @private
|
179
|
+
def normalize_system_name input
|
180
|
+
case input
|
181
|
+
when String
|
182
|
+
input
|
183
|
+
when Class
|
184
|
+
input.name.split("::")[..-3]
|
185
|
+
.map { |elem| elem.scan(/[A-Z][A-Z]*(?=[A-Z][a-z0-9]|$)|[A-Z][a-z0-9]+/).map(&:downcase).join("_") }
|
186
|
+
.join("-")
|
187
|
+
else
|
188
|
+
"googleapis"
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
# @private
|
193
|
+
def normalize_service input
|
194
|
+
case input
|
195
|
+
when String
|
196
|
+
input
|
197
|
+
when Class
|
198
|
+
mod = input.name.split("::")[..-2].inject(Object) { |m, n| m.const_get n }
|
199
|
+
if mod.const_defined? "Service"
|
200
|
+
mod.const_get("Service").service_name
|
201
|
+
else
|
202
|
+
name_segments = input.name.split("::")[..-3]
|
203
|
+
mod = name_segments.inject(Object) { |m, n| m.const_get n }
|
204
|
+
name_segments.join "." if mod.const_defined? "Rest"
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
@@ -13,6 +13,7 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
require "googleauth"
|
16
|
+
require "gapic/logging_concerns"
|
16
17
|
require "gapic/rest/faraday_middleware"
|
17
18
|
require "gapic/universe_domain_concerns"
|
18
19
|
require "faraday/retry"
|
@@ -28,9 +29,11 @@ module Gapic
|
|
28
29
|
#
|
29
30
|
class ClientStub
|
30
31
|
include UniverseDomainConcerns
|
32
|
+
include LoggingConcerns
|
31
33
|
|
32
34
|
##
|
33
35
|
# Initializes with an endpoint and credentials
|
36
|
+
#
|
34
37
|
# @param endpoint [String] The endpoint of the API. Overrides any endpoint_template.
|
35
38
|
# @param endpoint_template [String] The endpoint of the API, where the
|
36
39
|
# universe domain component of the hostname is marked by the string in
|
@@ -41,12 +44,14 @@ module Gapic
|
|
41
44
|
# Credentials to send with calls in form of a googleauth credentials object.
|
42
45
|
# (see the [googleauth docs](https://googleapis.dev/ruby/googleauth/latest/index.html))
|
43
46
|
# @param numeric_enums [Boolean] Whether to signal the server to JSON-encode enums as ints
|
44
|
-
#
|
45
47
|
# @param raise_faraday_errors [Boolean]
|
46
48
|
# Whether to raise Faraday errors instead of wrapping them in `Gapic::Rest::Error`
|
47
49
|
# Added for backwards compatibility.
|
48
50
|
# Default is `true`. All REST clients (except for old versions of `google-cloud-compute-v1`)
|
49
51
|
# should explicitly set this parameter to `false`.
|
52
|
+
# @param logger [Logger,:default,nil] An explicit logger to use, or one
|
53
|
+
# of the values `:default` (the default) to construct a default logger,
|
54
|
+
# or `nil` to disable logging explicitly.
|
50
55
|
#
|
51
56
|
# @yield [Faraday::Connection]
|
52
57
|
#
|
@@ -55,7 +60,10 @@ module Gapic
|
|
55
60
|
endpoint_template: nil,
|
56
61
|
universe_domain: nil,
|
57
62
|
numeric_enums: false,
|
58
|
-
raise_faraday_errors: true
|
63
|
+
raise_faraday_errors: true,
|
64
|
+
logging_system: nil,
|
65
|
+
service_name: nil,
|
66
|
+
logger: :default
|
59
67
|
setup_universe_domain universe_domain: universe_domain,
|
60
68
|
endpoint: endpoint,
|
61
69
|
endpoint_template: endpoint_template,
|
@@ -65,6 +73,12 @@ module Gapic
|
|
65
73
|
endpoint_url = "https://#{endpoint_url}" unless /^https?:/.match? endpoint_url
|
66
74
|
endpoint_url = endpoint_url.sub %r{/$}, ""
|
67
75
|
|
76
|
+
setup_logging logger: logger,
|
77
|
+
system_name: logging_system,
|
78
|
+
service: service_name,
|
79
|
+
endpoint: endpoint_url,
|
80
|
+
client_id: object_id
|
81
|
+
|
68
82
|
@numeric_enums = numeric_enums
|
69
83
|
|
70
84
|
@raise_faraday_errors = raise_faraday_errors
|
@@ -88,8 +102,8 @@ module Gapic
|
|
88
102
|
# @param options [::Gapic::CallOptions,Hash] gapic options to be applied
|
89
103
|
# to the REST call. Currently only timeout and headers are supported.
|
90
104
|
# @return [Faraday::Response]
|
91
|
-
def make_get_request uri:, params: {}, options: {}
|
92
|
-
make_http_request :get, uri: uri, body: nil, params: params, options: options
|
105
|
+
def make_get_request uri:, params: {}, options: {}, method_name: nil
|
106
|
+
make_http_request :get, uri: uri, body: nil, params: params, options: options, method_name: method_name
|
93
107
|
end
|
94
108
|
|
95
109
|
##
|
@@ -100,8 +114,8 @@ module Gapic
|
|
100
114
|
# @param options [::Gapic::CallOptions,Hash] gapic options to be applied
|
101
115
|
# to the REST call. Currently only timeout and headers are supported.
|
102
116
|
# @return [Faraday::Response]
|
103
|
-
def make_delete_request uri:, params: {}, options: {}
|
104
|
-
make_http_request :delete, uri: uri, body: nil, params: params, options: options
|
117
|
+
def make_delete_request uri:, params: {}, options: {}, method_name: nil
|
118
|
+
make_http_request :delete, uri: uri, body: nil, params: params, options: options, method_name: method_name
|
105
119
|
end
|
106
120
|
|
107
121
|
##
|
@@ -113,8 +127,8 @@ module Gapic
|
|
113
127
|
# @param options [::Gapic::CallOptions,Hash] gapic options to be applied
|
114
128
|
# to the REST call. Currently only timeout and headers are supported.
|
115
129
|
# @return [Faraday::Response]
|
116
|
-
def make_patch_request uri:, body:, params: {}, options: {}
|
117
|
-
make_http_request :patch, uri: uri, body: body, params: params, options: options
|
130
|
+
def make_patch_request uri:, body:, params: {}, options: {}, method_name: nil
|
131
|
+
make_http_request :patch, uri: uri, body: body, params: params, options: options, method_name: method_name
|
118
132
|
end
|
119
133
|
|
120
134
|
##
|
@@ -126,8 +140,8 @@ module Gapic
|
|
126
140
|
# @param options [::Gapic::CallOptions,Hash] gapic options to be applied
|
127
141
|
# to the REST call. Currently only timeout and headers are supported.
|
128
142
|
# @return [Faraday::Response]
|
129
|
-
def make_post_request uri:, body: nil, params: {}, options: {}
|
130
|
-
make_http_request :post, uri: uri, body: body, params: params, options: options
|
143
|
+
def make_post_request uri:, body: nil, params: {}, options: {}, method_name: nil
|
144
|
+
make_http_request :post, uri: uri, body: body, params: params, options: options, method_name: method_name
|
131
145
|
end
|
132
146
|
|
133
147
|
##
|
@@ -139,8 +153,8 @@ module Gapic
|
|
139
153
|
# @param options [::Gapic::CallOptions,Hash] gapic options to be applied
|
140
154
|
# to the REST call. Currently only timeout and headers are supported.
|
141
155
|
# @return [Faraday::Response]
|
142
|
-
def make_put_request uri:, body: nil, params: {}, options: {}
|
143
|
-
make_http_request :put, uri: uri, body: body, params: params, options: options
|
156
|
+
def make_put_request uri:, body: nil, params: {}, options: {}, method_name: nil
|
157
|
+
make_http_request :put, uri: uri, body: body, params: params, options: options, method_name: method_name
|
144
158
|
end
|
145
159
|
|
146
160
|
##
|
@@ -154,27 +168,38 @@ module Gapic
|
|
154
168
|
# @param is_server_streaming [Boolean] flag if method is streaming
|
155
169
|
# @yieldparam chunk [String] The chunk of data received during server streaming.
|
156
170
|
# @return [Faraday::Response]
|
157
|
-
def make_http_request verb,
|
171
|
+
def make_http_request verb,
|
172
|
+
uri:, body:, params:, options:,
|
173
|
+
is_server_streaming: false, method_name: nil,
|
174
|
+
&block
|
158
175
|
# Converts hash and nil to an options object
|
159
176
|
options = ::Gapic::CallOptions.new(**options.to_h) unless options.is_a? ::Gapic::CallOptions
|
160
177
|
deadline = calculate_deadline options
|
161
178
|
retried_exception = nil
|
162
179
|
next_timeout = get_timeout deadline
|
180
|
+
request_id = LoggingConcerns.random_uuid4
|
181
|
+
try_number = 1
|
163
182
|
|
164
183
|
begin
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
184
|
+
log_request method_name, request_id, try_number, body, options.metadata
|
185
|
+
response = base_make_http_request verb: verb, uri: uri, body: body,
|
186
|
+
params: params, metadata: options.metadata,
|
187
|
+
timeout: next_timeout,
|
188
|
+
is_server_streaming: is_server_streaming,
|
189
|
+
&block
|
190
|
+
log_response method_name, request_id, try_number, response, is_server_streaming
|
191
|
+
response
|
170
192
|
rescue ::Faraday::TimeoutError => e
|
193
|
+
log_response method_name, request_id, try_number, e, is_server_streaming
|
171
194
|
raise if @raise_faraday_errors
|
172
195
|
raise Gapic::Rest::DeadlineExceededError.wrap_faraday_error e, root_cause: retried_exception
|
173
196
|
rescue ::Faraday::Error => e
|
197
|
+
log_response method_name, request_id, try_number, e, is_server_streaming
|
174
198
|
next_timeout = get_timeout deadline
|
175
199
|
|
176
200
|
if check_retry?(next_timeout) && options.retry_policy.call(e)
|
177
201
|
retried_exception = e
|
202
|
+
try_number += 1
|
178
203
|
retry
|
179
204
|
end
|
180
205
|
|
@@ -251,6 +276,54 @@ module Gapic
|
|
251
276
|
|
252
277
|
timeout.positive?
|
253
278
|
end
|
279
|
+
|
280
|
+
def log_request method_name, request_id, try_number, body, metadata
|
281
|
+
return unless stub_logger
|
282
|
+
stub_logger.info do |entry|
|
283
|
+
entry.set_system_name
|
284
|
+
entry.set_service
|
285
|
+
entry.set "rpcName", method_name
|
286
|
+
entry.set "retryAttempt", try_number
|
287
|
+
entry.set "requestId", request_id
|
288
|
+
entry.message = "Sending request to #{entry.service}.#{method_name} (try #{try_number})"
|
289
|
+
end
|
290
|
+
body = body.to_s
|
291
|
+
metadata = metadata.to_h rescue {}
|
292
|
+
return if body.empty? && metadata.empty?
|
293
|
+
stub_logger.debug do |entry|
|
294
|
+
entry.set "requestId", request_id
|
295
|
+
entry.set "request", body
|
296
|
+
entry.set "headers", metadata
|
297
|
+
entry.message = "(request payload as JSON)"
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
def log_response method_name, request_id, try_number, response, is_server_streaming
|
302
|
+
return unless stub_logger
|
303
|
+
stub_logger.info do |entry|
|
304
|
+
entry.set_system_name
|
305
|
+
entry.set_service
|
306
|
+
entry.set "rpcName", method_name
|
307
|
+
entry.set "retryAttempt", try_number
|
308
|
+
entry.set "requestId", request_id
|
309
|
+
if response.is_a? StandardError
|
310
|
+
entry.set "exception", response.to_s
|
311
|
+
entry.message = "Received error for #{entry.service}.#{method_name} (try #{try_number}): #{response}"
|
312
|
+
elsif is_server_streaming
|
313
|
+
entry.message = "Receiving stream for #{entry.service}.#{method_name} (try #{try_number})"
|
314
|
+
else
|
315
|
+
entry.message = "Received response for #{entry.service}.#{method_name} (try #{try_number})"
|
316
|
+
end
|
317
|
+
end
|
318
|
+
return if is_server_streaming || !response.respond_to?(:body)
|
319
|
+
body = response.body.to_s
|
320
|
+
return if body.empty?
|
321
|
+
stub_logger.debug do |entry|
|
322
|
+
entry.set "requestId", request_id
|
323
|
+
entry.set "response", body
|
324
|
+
entry.message = "(response payload as JSON)"
|
325
|
+
end
|
326
|
+
end
|
254
327
|
end
|
255
328
|
end
|
256
329
|
end
|
@@ -60,11 +60,11 @@ module Gapic
|
|
60
60
|
raise ArgumentError, "endpoint or endpoint_template is required" if endpoint.nil? && endpoint_template.nil?
|
61
61
|
raise ArgumentError, "credentials is required" if credentials.nil?
|
62
62
|
|
63
|
-
# TODO: The env logic should live in google-cloud-env
|
64
63
|
universe_domain ||= ENV["GOOGLE_CLOUD_UNIVERSE_DOMAIN"] || "googleapis.com"
|
65
64
|
endpoint ||= endpoint_template.sub ENDPOINT_SUBSTITUTION, universe_domain
|
66
65
|
|
67
|
-
if credentials.respond_to?(:
|
66
|
+
if !(credentials.respond_to?(:disable_universe_domain_check) && credentials.disable_universe_domain_check) &&
|
67
|
+
credentials.respond_to?(:universe_domain) && credentials.universe_domain != universe_domain
|
68
68
|
raise UniverseDomainMismatch,
|
69
69
|
"Universe domain is #{universe_domain} but credentials are in #{credentials.universe_domain}"
|
70
70
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gapic-common
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.24.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:
|
11
|
+
date: 2024-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -54,84 +54,106 @@ dependencies:
|
|
54
54
|
name: googleapis-common-protos
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
56
56
|
requirements:
|
57
|
-
- - "
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
version: 1.4.0
|
60
|
-
- - "<"
|
57
|
+
- - "~>"
|
61
58
|
- !ruby/object:Gem::Version
|
62
|
-
version:
|
59
|
+
version: '1.6'
|
63
60
|
type: :runtime
|
64
61
|
prerelease: false
|
65
62
|
version_requirements: !ruby/object:Gem::Requirement
|
66
63
|
requirements:
|
67
|
-
- - "
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: 1.4.0
|
70
|
-
- - "<"
|
64
|
+
- - "~>"
|
71
65
|
- !ruby/object:Gem::Version
|
72
|
-
version:
|
66
|
+
version: '1.6'
|
73
67
|
- !ruby/object:Gem::Dependency
|
74
68
|
name: googleapis-common-protos-types
|
75
69
|
requirement: !ruby/object:Gem::Requirement
|
76
70
|
requirements:
|
77
|
-
- - "
|
78
|
-
- !ruby/object:Gem::Version
|
79
|
-
version: 1.11.0
|
80
|
-
- - "<"
|
71
|
+
- - "~>"
|
81
72
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
73
|
+
version: '1.15'
|
83
74
|
type: :runtime
|
84
75
|
prerelease: false
|
85
76
|
version_requirements: !ruby/object:Gem::Requirement
|
86
77
|
requirements:
|
87
|
-
- - "
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: 1.11.0
|
90
|
-
- - "<"
|
78
|
+
- - "~>"
|
91
79
|
- !ruby/object:Gem::Version
|
92
|
-
version:
|
80
|
+
version: '1.15'
|
93
81
|
- !ruby/object:Gem::Dependency
|
94
82
|
name: googleauth
|
95
83
|
requirement: !ruby/object:Gem::Requirement
|
96
84
|
requirements:
|
97
85
|
- - "~>"
|
98
86
|
- !ruby/object:Gem::Version
|
99
|
-
version: '1.
|
87
|
+
version: '1.12'
|
100
88
|
type: :runtime
|
101
89
|
prerelease: false
|
102
90
|
version_requirements: !ruby/object:Gem::Requirement
|
103
91
|
requirements:
|
104
92
|
- - "~>"
|
105
93
|
- !ruby/object:Gem::Version
|
106
|
-
version: '1.
|
94
|
+
version: '1.12'
|
107
95
|
- !ruby/object:Gem::Dependency
|
108
|
-
name: google-
|
96
|
+
name: google-cloud-env
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - "~>"
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '2.2'
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - "~>"
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '2.2'
|
109
|
+
- !ruby/object:Gem::Dependency
|
110
|
+
name: google-logging-utils
|
109
111
|
requirement: !ruby/object:Gem::Requirement
|
110
112
|
requirements:
|
111
113
|
- - "~>"
|
112
114
|
- !ruby/object:Gem::Version
|
113
|
-
version: '
|
115
|
+
version: '0.1'
|
114
116
|
type: :runtime
|
115
117
|
prerelease: false
|
116
118
|
version_requirements: !ruby/object:Gem::Requirement
|
117
119
|
requirements:
|
118
120
|
- - "~>"
|
119
121
|
- !ruby/object:Gem::Version
|
120
|
-
version: '
|
122
|
+
version: '0.1'
|
123
|
+
- !ruby/object:Gem::Dependency
|
124
|
+
name: google-protobuf
|
125
|
+
requirement: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '3.25'
|
130
|
+
- - "<"
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 5.a
|
133
|
+
type: :runtime
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '3.25'
|
140
|
+
- - "<"
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: 5.a
|
121
143
|
- !ruby/object:Gem::Dependency
|
122
144
|
name: grpc
|
123
145
|
requirement: !ruby/object:Gem::Requirement
|
124
146
|
requirements:
|
125
147
|
- - "~>"
|
126
148
|
- !ruby/object:Gem::Version
|
127
|
-
version: '1.
|
149
|
+
version: '1.66'
|
128
150
|
type: :runtime
|
129
151
|
prerelease: false
|
130
152
|
version_requirements: !ruby/object:Gem::Requirement
|
131
153
|
requirements:
|
132
154
|
- - "~>"
|
133
155
|
- !ruby/object:Gem::Version
|
134
|
-
version: '1.
|
156
|
+
version: '1.66'
|
135
157
|
description:
|
136
158
|
email:
|
137
159
|
- googleapis-packages@google.com
|
@@ -165,6 +187,7 @@ files:
|
|
165
187
|
- lib/gapic/grpc/service_stub/rpc_call.rb
|
166
188
|
- lib/gapic/grpc/status_details.rb
|
167
189
|
- lib/gapic/headers.rb
|
190
|
+
- lib/gapic/logging_concerns.rb
|
168
191
|
- lib/gapic/lru_hash.rb
|
169
192
|
- lib/gapic/operation.rb
|
170
193
|
- lib/gapic/operation/retry_policy.rb
|
@@ -195,14 +218,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
195
218
|
requirements:
|
196
219
|
- - ">="
|
197
220
|
- !ruby/object:Gem::Version
|
198
|
-
version: '
|
221
|
+
version: '3.0'
|
199
222
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
200
223
|
requirements:
|
201
224
|
- - ">="
|
202
225
|
- !ruby/object:Gem::Version
|
203
226
|
version: '0'
|
204
227
|
requirements: []
|
205
|
-
rubygems_version: 3.
|
228
|
+
rubygems_version: 3.5.23
|
206
229
|
signing_key:
|
207
230
|
specification_version: 4
|
208
231
|
summary: Common code for GAPIC-generated API clients
|