gapic-common 0.17.1 → 0.21.1
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 +41 -0
- data/lib/gapic/call_options.rb +2 -3
- data/lib/gapic/common/version.rb +1 -1
- data/lib/gapic/config.rb +5 -5
- data/lib/gapic/generic_lro/operation.rb +4 -4
- data/lib/gapic/grpc/service_stub/channel.rb +100 -0
- data/lib/gapic/grpc/service_stub/channel_pool.rb +113 -0
- data/lib/gapic/grpc/service_stub.rb +63 -11
- data/lib/gapic/lru_hash.rb +106 -0
- data/lib/gapic/operation.rb +5 -5
- data/lib/gapic/paged_enumerable.rb +1 -1
- data/lib/gapic/protobuf.rb +40 -66
- data/lib/gapic/rest/client_stub.rb +25 -8
- data/lib/gapic/rest/error.rb +5 -0
- data/lib/gapic/rest/grpc_transcoder.rb +3 -3
- data/lib/gapic/rest/transport_operation.rb +1 -1
- data/lib/gapic/universe_domain_concerns.rb +84 -0
- metadata +18 -154
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: b7c5286b152666f59249b7c1ba16867d494b934f2252bff17b68f1135ef47e97
         | 
| 4 | 
            +
              data.tar.gz: 14bbbc1179570401141d6f62520bc2ff00b27f21f55431f0e3db2d3f4e7220e1
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: f7e29a779c1fb17a88336b5c99c5635a9f196b275f9f381d56e25e8a5edc9ccf2e5ff9096500ab8bc33725489b793c2e1593bb38671da48b83529bba379562e0
         | 
| 7 | 
            +
              data.tar.gz: ceb55e48e017ba629c0b583ebb9145d541a309998b29d5b47d40ef0819b0befde3659f39e37a4362691a248070042cd86a34f104100587b76ee742a6edec9565
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,46 @@ | |
| 1 1 | 
             
            # Release History
         | 
| 2 2 |  | 
| 3 | 
            +
            ### 0.21.1 (2023-12-14)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            #### Bug Fixes
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            * add missing module import for universe_domain_concerns ([#1016](https://github.com/googleapis/gapic-generator-ruby/issues/1016)) 
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            ### 0.21.0 (2023-12-13)
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            #### Features
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            * Drop support for Ruby 2.6 ([#1009](https://github.com/googleapis/gapic-generator-ruby/issues/1009)) 
         | 
| 14 | 
            +
            * Honor universe domain in stubs ([#1008](https://github.com/googleapis/gapic-generator-ruby/issues/1008)) 
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            ### 0.20.0 (2023-08-31)
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            #### Features
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            * Add channel pooling for gapic clients ([#969](https://github.com/googleapis/gapic-generator-ruby/issues/969)) 
         | 
| 21 | 
            +
            * Add LRU hash ([#970](https://github.com/googleapis/gapic-generator-ruby/issues/970)) 
         | 
| 22 | 
            +
            #### Documentation
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            * Minor fixes to YARD documentation links and parameters ([#959](https://github.com/googleapis/gapic-generator-ruby/issues/959)) 
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            ### 0.19.1 (2023-05-30)
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            #### Bug Fixes
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            * Fixed handling of optional fields in coerce ([#954](https://github.com/googleapis/gapic-generator-ruby/issues/954)) 
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            ### 0.19.0 (2023-05-26)
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            #### Features
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            * Compatibility with protobuf v23 generated map fields ([#948](https://github.com/googleapis/gapic-generator-ruby/issues/948)) 
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            ### 0.18.0 (2023-02-27)
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            #### Features
         | 
| 41 | 
            +
             | 
| 42 | 
            +
            * add alias for details field in Rest Error ([#928](https://github.com/googleapis/gapic-generator-ruby/issues/928)) 
         | 
| 43 | 
            +
             | 
| 3 44 | 
             
            ### 0.17.1 (2023-02-09)
         | 
| 4 45 |  | 
| 5 46 | 
             
            #### Bug Fixes
         | 
    
        data/lib/gapic/call_options.rb
    CHANGED
    
    | @@ -37,7 +37,7 @@ module Gapic | |
| 37 37 | 
             
                # @param timeout [Numeric] The client-side timeout for RPC calls.
         | 
| 38 38 | 
             
                # @param metadata [Hash] The request header params.
         | 
| 39 39 | 
             
                # @param retry_policy [Hash, RetryPolicy, Proc] The policy for error retry. A Hash can be provided to
         | 
| 40 | 
            -
                #   customize the policy object, using keys that match the arguments for {RetryPolicy. | 
| 40 | 
            +
                #   customize the policy object, using keys that match the arguments for {RetryPolicy.initialize}.
         | 
| 41 41 | 
             
                #
         | 
| 42 42 | 
             
                #   A Proc object can also be provided. The Proc should accept an error as an argument, and return `true` if the
         | 
| 43 43 | 
             
                #   error should be retried or `false` if not. If the error is to be retried, the Proc object must also block
         | 
| @@ -59,9 +59,8 @@ module Gapic | |
| 59 59 | 
             
                #
         | 
| 60 60 | 
             
                # @param timeout [Numeric] The client-side timeout for RPC calls.
         | 
| 61 61 | 
             
                # @param metadata [Hash] the request header params.
         | 
| 62 | 
            -
                # @param retry_policy [Hash] the policy for error retry.
         | 
| 63 62 | 
             
                # @param retry_policy [Hash] The policy for error retry. keys must match the arguments for
         | 
| 64 | 
            -
                #   {RetryPolicy. | 
| 63 | 
            +
                #   {RetryPolicy.initialize}.
         | 
| 65 64 | 
             
                #
         | 
| 66 65 | 
             
                def apply_defaults timeout: nil, metadata: nil, retry_policy: nil
         | 
| 67 66 | 
             
                  @timeout ||= timeout
         | 
    
        data/lib/gapic/common/version.rb
    CHANGED
    
    
    
        data/lib/gapic/config.rb
    CHANGED
    
    | @@ -44,13 +44,13 @@ module Gapic | |
| 44 44 | 
             
                ##
         | 
| 45 45 | 
             
                # Add configuration attribute methods to the configuratin class.
         | 
| 46 46 | 
             
                #
         | 
| 47 | 
            -
                # @param [String, Symbol]  | 
| 48 | 
            -
                # @param [Object, nil]  | 
| 49 | 
            -
                # @param [ | 
| 47 | 
            +
                # @param [String, Symbol] name The name of the option
         | 
| 48 | 
            +
                # @param [Object, nil] default Initial value (nil is allowed)
         | 
| 49 | 
            +
                # @param [Array] valid_values A list of valid types
         | 
| 50 50 | 
             
                #
         | 
| 51 51 | 
             
                def config_attr name, default, *valid_values, &validator
         | 
| 52 52 | 
             
                  name = String(name).to_sym
         | 
| 53 | 
            -
                  name_setter = "#{name}=" | 
| 53 | 
            +
                  name_setter = :"#{name}="
         | 
| 54 54 | 
             
                  raise NameError, "invalid config name #{name}" if name !~ /^[a-zA-Z]\w*$/ || name == :parent_config
         | 
| 55 55 | 
             
                  raise NameError, "method #{name} already exists" if method_defined? name
         | 
| 56 56 | 
             
                  raise NameError, "method #{name_setter} already exists" if method_defined? name_setter
         | 
| @@ -58,7 +58,7 @@ module Gapic | |
| 58 58 | 
             
                  raise ArgumentError, "validation must be provided" if validator.nil? && valid_values.empty?
         | 
| 59 59 | 
             
                  validator ||= ->(value) { valid_values.any? { |v| v === value } }
         | 
| 60 60 |  | 
| 61 | 
            -
                  name_ivar = "@#{name}" | 
| 61 | 
            +
                  name_ivar = :"@#{name}"
         | 
| 62 62 |  | 
| 63 63 | 
             
                  create_getter name_ivar, name, default
         | 
| 64 64 | 
             
                  create_setter name_ivar, name_setter, default, validator
         | 
| @@ -90,7 +90,7 @@ module Gapic | |
| 90 90 | 
             
                  #
         | 
| 91 91 | 
             
                  def results
         | 
| 92 92 | 
             
                    return error if error?
         | 
| 93 | 
            -
                     | 
| 93 | 
            +
                    response if response?
         | 
| 94 94 | 
             
                  end
         | 
| 95 95 |  | 
| 96 96 | 
             
                  ##
         | 
| @@ -196,7 +196,7 @@ module Gapic | |
| 196 196 | 
             
                  # @param retry_policy [RetryPolicy, Hash, Proc] The policy for retry. A custom proc that takes the error as an
         | 
| 197 197 | 
             
                  #   argument and blocks can also be provided.
         | 
| 198 198 | 
             
                  #
         | 
| 199 | 
            -
                  # @ | 
| 199 | 
            +
                  # @yieldparam operation [Gapic::GenericLRO::Operation] Yields the finished Operation.
         | 
| 200 200 | 
             
                  #
         | 
| 201 201 | 
             
                  def wait_until_done! retry_policy: nil
         | 
| 202 202 | 
             
                    retry_policy = ::Gapic::Operation::RetryPolicy.new(**retry_policy) if retry_policy.is_a? Hash
         | 
| @@ -216,7 +216,7 @@ module Gapic | |
| 216 216 | 
             
                  # Registers a callback to be run when an operation is being reloaded. If the operation has completed
         | 
| 217 217 | 
             
                  # prior to a call to this function the callback will NOT be called or registered.
         | 
| 218 218 | 
             
                  #
         | 
| 219 | 
            -
                  # @ | 
| 219 | 
            +
                  # @yieldparam operation [Gapic::Operation] Yields the finished Operation.
         | 
| 220 220 | 
             
                  #
         | 
| 221 221 | 
             
                  def on_reload &block
         | 
| 222 222 | 
             
                    return if done?
         | 
| @@ -227,7 +227,7 @@ module Gapic | |
| 227 227 | 
             
                  # Registers a callback to be run when a refreshed operation is marked as done. If the operation has completed
         | 
| 228 228 | 
             
                  # prior to a call to this function the callback will be called instead of registered.
         | 
| 229 229 | 
             
                  #
         | 
| 230 | 
            -
                  # @ | 
| 230 | 
            +
                  # @yieldparam operation [Gapic::Operation] Yields the finished Operation.
         | 
| 231 231 | 
             
                  #
         | 
| 232 232 | 
             
                  def on_done &block
         | 
| 233 233 | 
             
                    if done?
         | 
| @@ -0,0 +1,100 @@ | |
| 1 | 
            +
            # Copyright 2023 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 "grpc"
         | 
| 16 | 
            +
            require "googleauth"
         | 
| 17 | 
            +
            require "gapic/grpc/service_stub/rpc_call"
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            module Gapic
         | 
| 20 | 
            +
              class ServiceStub
         | 
| 21 | 
            +
                ##
         | 
| 22 | 
            +
                # @private
         | 
| 23 | 
            +
                #
         | 
| 24 | 
            +
                # Gapic gRPC ServiceStub Channel.
         | 
| 25 | 
            +
                #
         | 
| 26 | 
            +
                # This class wraps the gRPC stub object and its RPC methods.
         | 
| 27 | 
            +
                #
         | 
| 28 | 
            +
                class Channel
         | 
| 29 | 
            +
                  attr_reader :concurrent_streams
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  ##
         | 
| 32 | 
            +
                  # Creates a new Channel instance
         | 
| 33 | 
            +
                  #
         | 
| 34 | 
            +
                  def initialize grpc_stub_class, endpoint:, credentials:, channel_args: nil, interceptors: nil,
         | 
| 35 | 
            +
                                 on_channel_create: nil
         | 
| 36 | 
            +
                    @grpc_stub_class = grpc_stub_class
         | 
| 37 | 
            +
                    @endpoint = endpoint
         | 
| 38 | 
            +
                    @credentials = credentials
         | 
| 39 | 
            +
                    @channel_args = Hash channel_args
         | 
| 40 | 
            +
                    @interceptors = Array interceptors
         | 
| 41 | 
            +
                    @concurrent_streams = 0
         | 
| 42 | 
            +
                    @mutex = Mutex.new
         | 
| 43 | 
            +
                    setup_grpc_stub
         | 
| 44 | 
            +
                    on_channel_create&.call self
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  ##
         | 
| 48 | 
            +
                  # Creates a gRPC stub object
         | 
| 49 | 
            +
                  #
         | 
| 50 | 
            +
                  def setup_grpc_stub
         | 
| 51 | 
            +
                    raise ArgumentError, "grpc_stub_class is required" if @grpc_stub_class.nil?
         | 
| 52 | 
            +
                    raise ArgumentError, "endpoint is required" if @endpoint.nil?
         | 
| 53 | 
            +
                    raise ArgumentError, "credentials is required" if @credentials.nil?
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                    @grpc_stub = case @credentials
         | 
| 56 | 
            +
                                 when ::GRPC::Core::Channel
         | 
| 57 | 
            +
                                   @grpc_stub_class.new @endpoint, nil, channel_override: @credentials, interceptors: @interceptors
         | 
| 58 | 
            +
                                 when ::GRPC::Core::ChannelCredentials, Symbol
         | 
| 59 | 
            +
                                   @grpc_stub_class.new @endpoint, @credentials, channel_args: @channel_args,
         | 
| 60 | 
            +
                                                        interceptors: @interceptors
         | 
| 61 | 
            +
                                 else
         | 
| 62 | 
            +
                                   updater_proc = @credentials.updater_proc if @credentials.respond_to? :updater_proc
         | 
| 63 | 
            +
                                   updater_proc ||= @credentials if @credentials.is_a? Proc
         | 
| 64 | 
            +
                                   raise ArgumentError, "invalid credentials (#{credentials.class})" if updater_proc.nil?
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                                   call_creds = ::GRPC::Core::CallCredentials.new updater_proc
         | 
| 67 | 
            +
                                   chan_creds = ::GRPC::Core::ChannelCredentials.new.compose call_creds
         | 
| 68 | 
            +
                                   @grpc_stub_class.new @endpoint, chan_creds, channel_args: @channel_args,
         | 
| 69 | 
            +
                                                        interceptors: @interceptors
         | 
| 70 | 
            +
                                 end
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                  ##
         | 
| 74 | 
            +
                  # Invoke the specified RPC call.
         | 
| 75 | 
            +
                  #
         | 
| 76 | 
            +
                  # @param method_name [Symbol] The RPC method name.
         | 
| 77 | 
            +
                  # @param request [Object] The request object.
         | 
| 78 | 
            +
                  # @param options [Gapic::CallOptions, Hash] The options for making the RPC call. A Hash can be provided to
         | 
| 79 | 
            +
                  #   customize the options object, using keys that match the arguments for {Gapic::CallOptions.new}. This object
         | 
| 80 | 
            +
                  #   should only be used once.
         | 
| 81 | 
            +
                  #
         | 
| 82 | 
            +
                  # @yield [response, operation] Access the response along with the RPC operation.
         | 
| 83 | 
            +
                  # @yieldparam response [Object] The response object.
         | 
| 84 | 
            +
                  # @yieldparam operation [::GRPC::ActiveCall::Operation] The RPC operation for the response.
         | 
| 85 | 
            +
                  #
         | 
| 86 | 
            +
                  # @return [Object] The response object.
         | 
| 87 | 
            +
                  #
         | 
| 88 | 
            +
                  def call_rpc method_name, request, options: nil, &block
         | 
| 89 | 
            +
                    @mutex.synchronize { @concurrent_streams += 1 }
         | 
| 90 | 
            +
                    begin
         | 
| 91 | 
            +
                      rpc_call = RpcCall.new @grpc_stub.method method_name
         | 
| 92 | 
            +
                      response = rpc_call.call request, options: options, &block
         | 
| 93 | 
            +
                      response
         | 
| 94 | 
            +
                    ensure
         | 
| 95 | 
            +
                      @mutex.synchronize { @concurrent_streams -= 1 }
         | 
| 96 | 
            +
                    end
         | 
| 97 | 
            +
                  end
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
              end
         | 
| 100 | 
            +
            end
         | 
| @@ -0,0 +1,113 @@ | |
| 1 | 
            +
            # Copyright 2023 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 "grpc"
         | 
| 16 | 
            +
            require "googleauth"
         | 
| 17 | 
            +
            require "gapic/config"
         | 
| 18 | 
            +
             | 
| 19 | 
            +
             | 
| 20 | 
            +
            module Gapic
         | 
| 21 | 
            +
              class ServiceStub
         | 
| 22 | 
            +
                ##
         | 
| 23 | 
            +
                # @private
         | 
| 24 | 
            +
                #
         | 
| 25 | 
            +
                # Gapic gRPC ServiceStub ChannelPool
         | 
| 26 | 
            +
                #
         | 
| 27 | 
            +
                # This class wraps multiple channels for sending RPCs.
         | 
| 28 | 
            +
                #
         | 
| 29 | 
            +
                class ChannelPool
         | 
| 30 | 
            +
                  ##
         | 
| 31 | 
            +
                  # Initialize an instance of ServiceStub::ChannelPool
         | 
| 32 | 
            +
                  #
         | 
| 33 | 
            +
                  def initialize grpc_stub_class, endpoint:, credentials:, channel_args: nil, interceptors: nil, config: nil
         | 
| 34 | 
            +
                    if credentials.is_a? ::GRPC::Core::Channel
         | 
| 35 | 
            +
                      raise ArgumentError, "Can't create a channel pool with GRPC::Core::Channel as credentials"
         | 
| 36 | 
            +
                    end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                    @grpc_stub_class = grpc_stub_class
         | 
| 39 | 
            +
                    @endpoint = endpoint
         | 
| 40 | 
            +
                    @credentials = credentials
         | 
| 41 | 
            +
                    @channel_args = channel_args
         | 
| 42 | 
            +
                    @interceptors = interceptors
         | 
| 43 | 
            +
                    @config = config || Configuration.new
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                    @channels = (1..@config.channel_count).map { create_channel }
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  ##
         | 
| 49 | 
            +
                  # Creates a new channel.
         | 
| 50 | 
            +
                  def create_channel
         | 
| 51 | 
            +
                    Channel.new @grpc_stub_class, endpoint: @endpoint, credentials: @credentials, channel_args: @channel_args,
         | 
| 52 | 
            +
                                interceptors: @interceptors, on_channel_create: @config.on_channel_create
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  ##
         | 
| 56 | 
            +
                  # Invoke the specified RPC call.
         | 
| 57 | 
            +
                  #
         | 
| 58 | 
            +
                  # @param method_name [Symbol] The RPC method name.
         | 
| 59 | 
            +
                  # @param request [Object] The request object.
         | 
| 60 | 
            +
                  # @param options [Gapic::CallOptions, Hash] The options for making the RPC call. A Hash can be provided to
         | 
| 61 | 
            +
                  #   customize the options object, using keys that match the arguments for {Gapic::CallOptions.new}. This object
         | 
| 62 | 
            +
                  #   should only be used once.
         | 
| 63 | 
            +
                  #
         | 
| 64 | 
            +
                  # @yield [response, operation] Access the response along with the RPC operation.
         | 
| 65 | 
            +
                  # @yieldparam response [Object] The response object.
         | 
| 66 | 
            +
                  # @yieldparam operation [::GRPC::ActiveCall::Operation] The RPC operation for the response.
         | 
| 67 | 
            +
                  #
         | 
| 68 | 
            +
                  # @return [Object] The response object.
         | 
| 69 | 
            +
                  #
         | 
| 70 | 
            +
                  def call_rpc method_name, request, options: nil, &block
         | 
| 71 | 
            +
                    unless @config.channel_selection == :least_loaded
         | 
| 72 | 
            +
                      warn "Invalid channel selection configuration, resorting to least loaded channel"
         | 
| 73 | 
            +
                    end
         | 
| 74 | 
            +
                    channel = least_loaded_channel
         | 
| 75 | 
            +
                    channel.call_rpc method_name, request, options: options, &block
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
             | 
| 79 | 
            +
                  private
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                  ##
         | 
| 82 | 
            +
                  # Return the least loaded channel in the pool
         | 
| 83 | 
            +
                  #
         | 
| 84 | 
            +
                  # @return [::Grpc::ServiceStub::Channel]
         | 
| 85 | 
            +
                  #
         | 
| 86 | 
            +
                  def least_loaded_channel
         | 
| 87 | 
            +
                    @channels.min_by(&:concurrent_streams)
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                  ##
         | 
| 91 | 
            +
                  # Configuration class for ChannelPool
         | 
| 92 | 
            +
                  #
         | 
| 93 | 
            +
                  # @!attribute [rw] channel_count
         | 
| 94 | 
            +
                  #  The number of channels in the channel pool.
         | 
| 95 | 
            +
                  #  return [Integer]
         | 
| 96 | 
            +
                  # @!attribute [rw] on_channel_create
         | 
| 97 | 
            +
                  #  Proc to run at the end of each channel initialization.
         | 
| 98 | 
            +
                  #  Proc is provided ::Gapic::ServiceStub::Channel object as input.
         | 
| 99 | 
            +
                  #  return [Proc]
         | 
| 100 | 
            +
                  # @!attribute [rw] channel_selection
         | 
| 101 | 
            +
                  #  The algorithm for selecting a channel for an RPC.
         | 
| 102 | 
            +
                  #  return [Symbol]
         | 
| 103 | 
            +
                  #
         | 
| 104 | 
            +
                  class Configuration
         | 
| 105 | 
            +
                    extend ::Gapic::Config
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                    config_attr :channel_count, 1, ::Integer
         | 
| 108 | 
            +
                    config_attr :on_channel_create, nil, ::Proc
         | 
| 109 | 
            +
                    config_attr :channel_selection, :least_loaded, :least_loaded
         | 
| 110 | 
            +
                  end
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
              end
         | 
| 113 | 
            +
            end
         | 
| @@ -15,24 +15,37 @@ | |
| 15 15 | 
             
            require "grpc"
         | 
| 16 16 | 
             
            require "googleauth"
         | 
| 17 17 | 
             
            require "gapic/grpc/service_stub/rpc_call"
         | 
| 18 | 
            +
            require "gapic/grpc/service_stub/channel"
         | 
| 19 | 
            +
            require "gapic/grpc/service_stub/channel_pool"
         | 
| 20 | 
            +
            require "gapic/universe_domain_concerns"
         | 
| 18 21 |  | 
| 19 22 | 
             
            module Gapic
         | 
| 20 23 | 
             
              ##
         | 
| 21 24 | 
             
              # Gapic gRPC Stub
         | 
| 22 25 | 
             
              #
         | 
| 23 | 
            -
              # This class wraps the actual gRPC Stub  | 
| 26 | 
            +
              # This class wraps the actual gRPC Stub and ChannelPool objects.
         | 
| 24 27 | 
             
              #
         | 
| 25 28 | 
             
              # @!attribute [r] grpc_stub
         | 
| 26 29 | 
             
              #   @return [Object] The instance of the gRPC stub class (`grpc_stub_class`) constructor argument.
         | 
| 30 | 
            +
              # @!attribute [r] channel_pool
         | 
| 31 | 
            +
              #   @return [Gapic::ServiceStub::ChannelPool] The instance of the ChannelPool class.
         | 
| 27 32 | 
             
              #
         | 
| 28 33 | 
             
              class ServiceStub
         | 
| 34 | 
            +
                include UniverseDomainConcerns
         | 
| 35 | 
            +
             | 
| 29 36 | 
             
                attr_reader :grpc_stub
         | 
| 37 | 
            +
                attr_reader :channel_pool
         | 
| 30 38 |  | 
| 31 39 | 
             
                ##
         | 
| 32 40 | 
             
                # Creates a Gapic gRPC stub object.
         | 
| 33 41 | 
             
                #
         | 
| 34 42 | 
             
                # @param grpc_stub_class [Class] gRPC stub class to create a new instance of.
         | 
| 35 | 
            -
                # @param endpoint [String] The endpoint of the API.
         | 
| 43 | 
            +
                # @param endpoint [String] The endpoint of the API. Overrides any endpoint_template.
         | 
| 44 | 
            +
                # @param endpoint_template [String] The endpoint of the API, where the
         | 
| 45 | 
            +
                #   universe domain component of the hostname is marked by the string in
         | 
| 46 | 
            +
                #   the constant {UniverseDomainConcerns::ENDPOINT_SUBSTITUTION}.
         | 
| 47 | 
            +
                # @param universe_domain [String] The universe domain in which calls should
         | 
| 48 | 
            +
                #   be made. Defaults to `googleapis.com`.
         | 
| 36 49 | 
             
                # @param credentials [Google::Auth::Credentials, Signet::OAuth2::Client, String, Hash, Proc,
         | 
| 37 50 | 
             
                #   ::GRPC::Core::Channel, ::GRPC::Core::ChannelCredentials] Provides the means for authenticating requests made by
         | 
| 38 51 | 
             
                #   the client. This parameter can be many types:
         | 
| @@ -49,22 +62,57 @@ module Gapic | |
| 49 62 | 
             
                #     provided as a `::GRPC::Core::Channel`.)
         | 
| 50 63 | 
             
                # @param interceptors [Array<::GRPC::ClientInterceptor>] An array of {::GRPC::ClientInterceptor} objects that will
         | 
| 51 64 | 
             
                #   be used for intercepting calls before they are executed Interceptors are an EXPERIMENTAL API.
         | 
| 52 | 
            -
                #
         | 
| 53 | 
            -
                 | 
| 65 | 
            +
                # @param channel_pool_config [::Gapic::ServiceStub:ChannelPool::Configuration] The configuration for channel
         | 
| 66 | 
            +
                #     pool. This argument will raise error when `credentials` is provided as a `::GRPC::Core::Channel`.
         | 
| 67 | 
            +
                #
         | 
| 68 | 
            +
                def initialize grpc_stub_class,
         | 
| 69 | 
            +
                               credentials:,
         | 
| 70 | 
            +
                               endpoint: nil,
         | 
| 71 | 
            +
                               endpoint_template: nil,
         | 
| 72 | 
            +
                               universe_domain: nil,
         | 
| 73 | 
            +
                               channel_args: nil,
         | 
| 74 | 
            +
                               interceptors: nil,
         | 
| 75 | 
            +
                               channel_pool_config: nil
         | 
| 54 76 | 
             
                  raise ArgumentError, "grpc_stub_class is required" if grpc_stub_class.nil?
         | 
| 55 | 
            -
                  raise ArgumentError, "endpoint is required" if endpoint.nil?
         | 
| 56 | 
            -
                  raise ArgumentError, "credentials is required" if credentials.nil?
         | 
| 57 77 |  | 
| 78 | 
            +
                  setup_universe_domain universe_domain: universe_domain,
         | 
| 79 | 
            +
                                        endpoint: endpoint,
         | 
| 80 | 
            +
                                        endpoint_template: endpoint_template,
         | 
| 81 | 
            +
                                        credentials: credentials
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                  @channel_pool = nil
         | 
| 84 | 
            +
                  @grpc_stub = nil
         | 
| 58 85 | 
             
                  channel_args = Hash channel_args
         | 
| 59 86 | 
             
                  interceptors = Array interceptors
         | 
| 60 87 |  | 
| 88 | 
            +
                  if channel_pool_config && channel_pool_config.channel_count > 1
         | 
| 89 | 
            +
                    create_channel_pool grpc_stub_class, endpoint: self.endpoint, credentials: self.credentials,
         | 
| 90 | 
            +
                                        channel_args: channel_args, interceptors: interceptors,
         | 
| 91 | 
            +
                                        channel_pool_config: channel_pool_config
         | 
| 92 | 
            +
                  else
         | 
| 93 | 
            +
                    create_grpc_stub grpc_stub_class, endpoint: self.endpoint, credentials: self.credentials,
         | 
| 94 | 
            +
                                     channel_args: channel_args, interceptors: interceptors
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
                end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                def create_channel_pool grpc_stub_class, endpoint:, credentials:, channel_args: nil,
         | 
| 99 | 
            +
                                        interceptors: nil, channel_pool_config: nil
         | 
| 100 | 
            +
                  if credentials.is_a? ::GRPC::Core::Channel
         | 
| 101 | 
            +
                    raise ArgumentError, "Cannot create a channel pool with GRPC::Core::Channel as credentials"
         | 
| 102 | 
            +
                  end
         | 
| 103 | 
            +
                  @channel_pool = ChannelPool.new grpc_stub_class, endpoint: endpoint, credentials: credentials,
         | 
| 104 | 
            +
                                    channel_args: channel_args, interceptors: interceptors,
         | 
| 105 | 
            +
                                    config: channel_pool_config
         | 
| 106 | 
            +
                end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                def create_grpc_stub grpc_stub_class, endpoint:, credentials:, channel_args: nil, interceptors: nil
         | 
| 61 109 | 
             
                  @grpc_stub = case credentials
         | 
| 62 110 | 
             
                               when ::GRPC::Core::Channel
         | 
| 63 111 | 
             
                                 grpc_stub_class.new endpoint, nil, channel_override: credentials,
         | 
| 64 | 
            -
             | 
| 112 | 
            +
                                                     interceptors: interceptors
         | 
| 65 113 | 
             
                               when ::GRPC::Core::ChannelCredentials, Symbol
         | 
| 66 114 | 
             
                                 grpc_stub_class.new endpoint, credentials, channel_args: channel_args,
         | 
| 67 | 
            -
             | 
| 115 | 
            +
                                                     interceptors: interceptors
         | 
| 68 116 | 
             
                               else
         | 
| 69 117 | 
             
                                 updater_proc = credentials.updater_proc if credentials.respond_to? :updater_proc
         | 
| 70 118 | 
             
                                 updater_proc ||= credentials if credentials.is_a? Proc
         | 
| @@ -73,7 +121,7 @@ module Gapic | |
| 73 121 | 
             
                                 call_creds = ::GRPC::Core::CallCredentials.new updater_proc
         | 
| 74 122 | 
             
                                 chan_creds = ::GRPC::Core::ChannelCredentials.new.compose call_creds
         | 
| 75 123 | 
             
                                 grpc_stub_class.new endpoint, chan_creds, channel_args: channel_args,
         | 
| 76 | 
            -
             | 
| 124 | 
            +
                                                     interceptors: interceptors
         | 
| 77 125 | 
             
                               end
         | 
| 78 126 | 
             
                end
         | 
| 79 127 |  | 
| @@ -152,8 +200,12 @@ module Gapic | |
| 152 200 | 
             
                #   end
         | 
| 153 201 | 
             
                #
         | 
| 154 202 | 
             
                def call_rpc method_name, request, options: nil, &block
         | 
| 155 | 
            -
                   | 
| 156 | 
            -
             | 
| 203 | 
            +
                  if @channel_pool.nil?
         | 
| 204 | 
            +
                    rpc_call = RpcCall.new @grpc_stub.method method_name
         | 
| 205 | 
            +
                    rpc_call.call request, options: options, &block
         | 
| 206 | 
            +
                  else
         | 
| 207 | 
            +
                    @channel_pool.call_rpc method_name, request, options: options, &block
         | 
| 208 | 
            +
                  end
         | 
| 157 209 | 
             
                end
         | 
| 158 210 | 
             
              end
         | 
| 159 211 | 
             
            end
         | 
| @@ -0,0 +1,106 @@ | |
| 1 | 
            +
            # Copyright 2023 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 | 
            +
            module Gapic
         | 
| 16 | 
            +
              ##
         | 
| 17 | 
            +
              # @private
         | 
| 18 | 
            +
              #
         | 
| 19 | 
            +
              # Linked list based hash maintaining the order of
         | 
| 20 | 
            +
              # access/creation of the keys.
         | 
| 21 | 
            +
              #
         | 
| 22 | 
            +
              class LruHash
         | 
| 23 | 
            +
                def initialize size = 1
         | 
| 24 | 
            +
                  raise ArgumentError, "The size of LRU hash can't be < 1" unless size > 1
         | 
| 25 | 
            +
                  @start = nil
         | 
| 26 | 
            +
                  @end = nil
         | 
| 27 | 
            +
                  @size = size
         | 
| 28 | 
            +
                  @cache = {}
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def get key
         | 
| 32 | 
            +
                  return nil unless @cache.key? key
         | 
| 33 | 
            +
                  node = @cache[key]
         | 
| 34 | 
            +
                  move_to_top node
         | 
| 35 | 
            +
                  node.value
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                def put key, value
         | 
| 39 | 
            +
                  if @cache.key? key
         | 
| 40 | 
            +
                    node = @cache[key]
         | 
| 41 | 
            +
                    node.value = value
         | 
| 42 | 
            +
                    move_to_top node
         | 
| 43 | 
            +
                  else
         | 
| 44 | 
            +
                    remove_tail if @cache.size >= @size
         | 
| 45 | 
            +
                    new_node = Node.new key, value
         | 
| 46 | 
            +
                    insert_at_top new_node
         | 
| 47 | 
            +
                    @cache[key] = new_node
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                private
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                def move_to_top node
         | 
| 54 | 
            +
                  return if node.equal? @start
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  if node.equal? @end
         | 
| 57 | 
            +
                    @end = node.prev
         | 
| 58 | 
            +
                    @end.next = nil
         | 
| 59 | 
            +
                  else
         | 
| 60 | 
            +
                    node.prev.next = node.next
         | 
| 61 | 
            +
                    node.next.prev = node.prev
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  node.prev = nil
         | 
| 65 | 
            +
                  node.next = @start
         | 
| 66 | 
            +
                  @start.prev = node
         | 
| 67 | 
            +
                  @start = node
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                def remove_tail
         | 
| 71 | 
            +
                  @cache.delete @end.key
         | 
| 72 | 
            +
                  @end = @end.prev
         | 
| 73 | 
            +
                  @end.next = nil if @end
         | 
| 74 | 
            +
                end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                def insert_at_top node
         | 
| 77 | 
            +
                  if @start.nil?
         | 
| 78 | 
            +
                    @start = node
         | 
| 79 | 
            +
                    @end = node
         | 
| 80 | 
            +
                  else
         | 
| 81 | 
            +
                    node.next = @start
         | 
| 82 | 
            +
                    @start.prev = node
         | 
| 83 | 
            +
                    @start = node
         | 
| 84 | 
            +
                  end
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                ##
         | 
| 88 | 
            +
                # @private
         | 
| 89 | 
            +
                #
         | 
| 90 | 
            +
                # Node class for linked list.
         | 
| 91 | 
            +
                #
         | 
| 92 | 
            +
                class Node
         | 
| 93 | 
            +
                  attr_accessor :key
         | 
| 94 | 
            +
                  attr_accessor :value
         | 
| 95 | 
            +
                  attr_accessor :prev
         | 
| 96 | 
            +
                  attr_accessor :next
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                  def initialize key, value
         | 
| 99 | 
            +
                    @key = key
         | 
| 100 | 
            +
                    @value = value
         | 
| 101 | 
            +
                    @prev = nil
         | 
| 102 | 
            +
                    @next = nil
         | 
| 103 | 
            +
                  end
         | 
| 104 | 
            +
                end
         | 
| 105 | 
            +
              end
         | 
| 106 | 
            +
            end
         | 
    
        data/lib/gapic/operation.rb
    CHANGED
    
    | @@ -99,10 +99,10 @@ module Gapic | |
| 99 99 | 
             
                # returned. Otherwise returns nil.
         | 
| 100 100 | 
             
                #
         | 
| 101 101 | 
             
                # @return [Object, Google::Rpc::Status, nil] The result of the operation. If it is an error a
         | 
| 102 | 
            -
                #    | 
| 102 | 
            +
                #   `Google::Rpc::Status` will be returned.
         | 
| 103 103 | 
             
                def results
         | 
| 104 104 | 
             
                  return error if error?
         | 
| 105 | 
            -
                   | 
| 105 | 
            +
                  response if response?
         | 
| 106 106 | 
             
                end
         | 
| 107 107 |  | 
| 108 108 | 
             
                ##
         | 
| @@ -119,7 +119,7 @@ module Gapic | |
| 119 119 | 
             
                # Returns the metadata of an operation. If a type is provided, the metadata will be unpacked using the type
         | 
| 120 120 | 
             
                # provided; returning nil if the metadata is not of the type provided. If the type is not of provided, the
         | 
| 121 121 | 
             
                # metadata will be unpacked using the metadata's type_url if the type_url is found in the
         | 
| 122 | 
            -
                #  | 
| 122 | 
            +
                # `Google::Protobuf::DescriptorPool.generated_pool`. If the type cannot be found the raw metadata is retuned.
         | 
| 123 123 | 
             
                #
         | 
| 124 124 | 
             
                # @return [Object, nil] The metadata of the operation. Can be nil.
         | 
| 125 125 | 
             
                #
         | 
| @@ -250,7 +250,7 @@ module Gapic | |
| 250 250 | 
             
                # @param retry_policy [RetryPolicy, Hash, Proc] The policy for retry. A custom proc that takes the error as an
         | 
| 251 251 | 
             
                #   argument and blocks can also be provided.
         | 
| 252 252 | 
             
                #
         | 
| 253 | 
            -
                # @ | 
| 253 | 
            +
                # @yieldparam operation [Gapic::Operation] Yields the finished Operation.
         | 
| 254 254 | 
             
                #
         | 
| 255 255 | 
             
                def wait_until_done! retry_policy: nil
         | 
| 256 256 | 
             
                  retry_policy = RetryPolicy.new(**retry_policy) if retry_policy.is_a? Hash
         | 
| @@ -270,7 +270,7 @@ module Gapic | |
| 270 270 | 
             
                # Registers a callback to be run when a refreshed operation is marked as done. If the operation has completed
         | 
| 271 271 | 
             
                # prior to a call to this function the callback will be called instead of registered.
         | 
| 272 272 | 
             
                #
         | 
| 273 | 
            -
                # @ | 
| 273 | 
            +
                # @yieldparam operation [Gapic::Operation] Yields the finished Operation.
         | 
| 274 274 | 
             
                #
         | 
| 275 275 | 
             
                def on_done &block
         | 
| 276 276 | 
             
                  if done?
         | 
    
        data/lib/gapic/protobuf.rb
    CHANGED
    
    | @@ -16,7 +16,8 @@ require "google/protobuf/timestamp_pb" | |
| 16 16 |  | 
| 17 17 | 
             
            module Gapic
         | 
| 18 18 | 
             
              ##
         | 
| 19 | 
            -
              #  | 
| 19 | 
            +
              # A set of internal utilities for coercing data to protobuf messages.
         | 
| 20 | 
            +
              #
         | 
| 20 21 | 
             
              module Protobuf
         | 
| 21 22 | 
             
                ##
         | 
| 22 23 | 
             
                # Creates an instance of a protobuf message from a hash that may include nested hashes. `google/protobuf` allows
         | 
| @@ -30,11 +31,15 @@ module Gapic | |
| 30 31 | 
             
                # @return [Object] An instance of the given message class.
         | 
| 31 32 | 
             
                def self.coerce hash, to:
         | 
| 32 33 | 
             
                  return hash if hash.is_a? to
         | 
| 34 | 
            +
                  return nil if hash.nil?
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  # Special case handling of certain types
         | 
| 37 | 
            +
                  return time_to_timestamp hash if to == Google::Protobuf::Timestamp && hash.is_a?(Time)
         | 
| 33 38 |  | 
| 34 39 | 
             
                  # Sanity check: input must be a Hash
         | 
| 35 40 | 
             
                  raise ArgumentError, "Value #{hash} must be a Hash or a #{to.name}" unless hash.is_a? Hash
         | 
| 36 41 |  | 
| 37 | 
            -
                  hash = coerce_submessages hash, to
         | 
| 42 | 
            +
                  hash = coerce_submessages hash, to.descriptor
         | 
| 38 43 | 
             
                  to.new hash
         | 
| 39 44 | 
             
                end
         | 
| 40 45 |  | 
| @@ -44,89 +49,58 @@ module Gapic | |
| 44 49 | 
             
                # @private
         | 
| 45 50 | 
             
                #
         | 
| 46 51 | 
             
                # @param hash [Hash] The hash whose nested hashes will be coerced.
         | 
| 47 | 
            -
                # @param  | 
| 52 | 
            +
                # @param message_descriptor [Google::Protobuf::Descriptor] The protobuf descriptor for the message.
         | 
| 48 53 | 
             
                #
         | 
| 49 54 | 
             
                # @return [Hash] A hash whose nested hashes have been coerced.
         | 
| 50 | 
            -
                def self.coerce_submessages hash,  | 
| 55 | 
            +
                def self.coerce_submessages hash, message_descriptor
         | 
| 51 56 | 
             
                  return nil if hash.nil?
         | 
| 52 57 | 
             
                  coerced = {}
         | 
| 53 | 
            -
                  message_descriptor = message_class.descriptor
         | 
| 54 58 | 
             
                  hash.each do |key, val|
         | 
| 55 59 | 
             
                    field_descriptor = message_descriptor.lookup key.to_s
         | 
| 56 | 
            -
                    coerced[key] = | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 60 | 
            +
                    coerced[key] =
         | 
| 61 | 
            +
                      if field_descriptor&.type == :message
         | 
| 62 | 
            +
                        coerce_submessage val, field_descriptor
         | 
| 63 | 
            +
                      elsif field_descriptor&.type == :bytes && (val.is_a?(IO) || val.is_a?(StringIO))
         | 
| 64 | 
            +
                        val.binmode.read
         | 
| 65 | 
            +
                      else
         | 
| 66 | 
            +
                        # For non-message fields, just pass the scalar value through.
         | 
| 67 | 
            +
                        # Note: if field_descriptor is not found, we just pass the value
         | 
| 68 | 
            +
                        # through and let protobuf raise an error.
         | 
| 69 | 
            +
                        val
         | 
| 70 | 
            +
                      end
         | 
| 66 71 | 
             
                  end
         | 
| 67 72 | 
             
                  coerced
         | 
| 68 73 | 
             
                end
         | 
| 69 74 |  | 
| 70 75 | 
             
                ##
         | 
| 71 | 
            -
                # Coerces  | 
| 76 | 
            +
                # Coerces a message-typed field.
         | 
| 77 | 
            +
                # The field can be a normal single message, a repeated message, or a map.
         | 
| 72 78 | 
             
                #
         | 
| 73 79 | 
             
                # @private
         | 
| 74 80 | 
             
                #
         | 
| 75 | 
            -
                # @param val [Object] The value to  | 
| 76 | 
            -
                # @param field_descriptor [Google::Protobuf::FieldDescriptor] The field descriptor | 
| 81 | 
            +
                # @param val [Object] The value to coerce
         | 
| 82 | 
            +
                # @param field_descriptor [Google::Protobuf::FieldDescriptor] The field descriptor.
         | 
| 77 83 | 
             
                #
         | 
| 78 | 
            -
                # @return [Object] The coerced version of the given value.
         | 
| 79 84 | 
             
                def self.coerce_submessage val, field_descriptor
         | 
| 80 | 
            -
                  if  | 
| 81 | 
            -
                     | 
| 82 | 
            -
             | 
| 83 | 
            -
                     | 
| 85 | 
            +
                  if val.is_a? Array
         | 
| 86 | 
            +
                    # Assume this is a repeated message field, iterate over it and coerce
         | 
| 87 | 
            +
                    # each to the message class.
         | 
| 88 | 
            +
                    # Protobuf will raise an error if this assumption is incorrect.
         | 
| 89 | 
            +
                    val.map do |elem|
         | 
| 90 | 
            +
                      coerce elem, to: field_descriptor.subtype.msgclass
         | 
| 91 | 
            +
                    end
         | 
| 92 | 
            +
                  elsif field_descriptor.label == :repeated
         | 
| 93 | 
            +
                    # Non-array passed to a repeated field: assume this is a map, and that
         | 
| 94 | 
            +
                    # a hash is being passed, and let protobuf handle the conversion.
         | 
| 95 | 
            +
                    # Protobuf will raise an error if this assumption is incorrect.
         | 
| 96 | 
            +
                    val
         | 
| 84 97 | 
             
                  else
         | 
| 85 | 
            -
                     | 
| 98 | 
            +
                    # Assume this is a normal single message, and coerce to the message
         | 
| 99 | 
            +
                    # class.
         | 
| 100 | 
            +
                    coerce val, to: field_descriptor.subtype.msgclass
         | 
| 86 101 | 
             
                  end
         | 
| 87 102 | 
             
                end
         | 
| 88 103 |  | 
| 89 | 
            -
                ##
         | 
| 90 | 
            -
                # Coerces the values of an array to be acceptable by the instantiation method the wrapping message.
         | 
| 91 | 
            -
                #
         | 
| 92 | 
            -
                # @private
         | 
| 93 | 
            -
                #
         | 
| 94 | 
            -
                # @param array [Array<Object>] The values to be coerced.
         | 
| 95 | 
            -
                # @param field_descriptor [Google::Protobuf::FieldDescriptor] The field descriptor of the values.
         | 
| 96 | 
            -
                #
         | 
| 97 | 
            -
                # @return [Array<Object>] The coerced version of the given values.
         | 
| 98 | 
            -
                def self.coerce_array array, field_descriptor
         | 
| 99 | 
            -
                  raise ArgumentError, "Value #{array} must be an array" unless array.is_a? Array
         | 
| 100 | 
            -
                  array.map do |val|
         | 
| 101 | 
            -
                    coerce_value val, field_descriptor
         | 
| 102 | 
            -
                  end
         | 
| 103 | 
            -
                end
         | 
| 104 | 
            -
             | 
| 105 | 
            -
                ##
         | 
| 106 | 
            -
                # Hack to determine if field_descriptor is for a map.
         | 
| 107 | 
            -
                #
         | 
| 108 | 
            -
                # TODO(geigerj): Remove this once protobuf Ruby supports an official way
         | 
| 109 | 
            -
                # to determine if a FieldDescriptor represents a map.
         | 
| 110 | 
            -
                # See: https://github.com/google/protobuf/issues/3425
         | 
| 111 | 
            -
                def self.map_field? field_descriptor
         | 
| 112 | 
            -
                  (field_descriptor.label == :repeated) &&
         | 
| 113 | 
            -
                    (field_descriptor.subtype.name.include? "_MapEntry_")
         | 
| 114 | 
            -
                end
         | 
| 115 | 
            -
             | 
| 116 | 
            -
                ##
         | 
| 117 | 
            -
                # Coerces the value of a field to be acceptable by the instantiation method of the wrapping message.
         | 
| 118 | 
            -
                #
         | 
| 119 | 
            -
                # @private
         | 
| 120 | 
            -
                #
         | 
| 121 | 
            -
                # @param val [Object] The value to be coerced.
         | 
| 122 | 
            -
                # @param field_descriptor [Google::Protobuf::FieldDescriptor] The field descriptor of the value.
         | 
| 123 | 
            -
                #
         | 
| 124 | 
            -
                # @return [Object] The coerced version of the given value.
         | 
| 125 | 
            -
                def self.coerce_value val, field_descriptor
         | 
| 126 | 
            -
                  return val unless (val.is_a? Hash) && !(map_field? field_descriptor)
         | 
| 127 | 
            -
                  coerce val, to: field_descriptor.subtype.msgclass
         | 
| 128 | 
            -
                end
         | 
| 129 | 
            -
             | 
| 130 104 | 
             
                ##
         | 
| 131 105 | 
             
                # Utility for converting a Google::Protobuf::Timestamp instance to a Ruby time.
         | 
| 132 106 | 
             
                #
         | 
| @@ -147,6 +121,6 @@ module Gapic | |
| 147 121 | 
             
                  Google::Protobuf::Timestamp.new seconds: time.to_i, nanos: time.nsec
         | 
| 148 122 | 
             
                end
         | 
| 149 123 |  | 
| 150 | 
            -
                private_class_method :coerce_submessages, :coerce_submessage | 
| 124 | 
            +
                private_class_method :coerce_submessages, :coerce_submessage
         | 
| 151 125 | 
             
              end
         | 
| 152 126 | 
             
            end
         | 
| @@ -14,6 +14,7 @@ | |
| 14 14 |  | 
| 15 15 | 
             
            require "googleauth"
         | 
| 16 16 | 
             
            require "gapic/rest/faraday_middleware"
         | 
| 17 | 
            +
            require "gapic/universe_domain_concerns"
         | 
| 17 18 | 
             
            require "faraday/retry"
         | 
| 18 19 |  | 
| 19 20 | 
             
            module Gapic
         | 
| @@ -26,9 +27,16 @@ module Gapic | |
| 26 27 | 
             
                #   - store credentials and add auth information to the request
         | 
| 27 28 | 
             
                #
         | 
| 28 29 | 
             
                class ClientStub
         | 
| 30 | 
            +
                  include UniverseDomainConcerns
         | 
| 31 | 
            +
             | 
| 29 32 | 
             
                  ##
         | 
| 30 33 | 
             
                  # Initializes with an endpoint and credentials
         | 
| 31 | 
            -
                  # @param endpoint [String]  | 
| 34 | 
            +
                  # @param endpoint [String] The endpoint of the API. Overrides any endpoint_template.
         | 
| 35 | 
            +
                  # @param endpoint_template [String] The endpoint of the API, where the
         | 
| 36 | 
            +
                  #   universe domain component of the hostname is marked by the string in
         | 
| 37 | 
            +
                  #   the constant {UniverseDomainConcerns::ENDPOINT_SUBSTITUTION}.
         | 
| 38 | 
            +
                  # @param universe_domain [String] The universe domain in which calls
         | 
| 39 | 
            +
                  #   should be made. Defaults to `googleapis.com`.
         | 
| 32 40 | 
             
                  # @param credentials [Google::Auth::Credentials]
         | 
| 33 41 | 
             
                  #   Credentials to send with calls in form of a googleauth credentials object.
         | 
| 34 42 | 
             
                  #   (see the [googleauth docs](https://googleapis.dev/ruby/googleauth/latest/index.html))
         | 
| @@ -42,19 +50,28 @@ module Gapic | |
| 42 50 | 
             
                  #
         | 
| 43 51 | 
             
                  # @yield [Faraday::Connection]
         | 
| 44 52 | 
             
                  #
         | 
| 45 | 
            -
                  def initialize  | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 53 | 
            +
                  def initialize credentials:,
         | 
| 54 | 
            +
                                 endpoint: nil,
         | 
| 55 | 
            +
                                 endpoint_template: nil,
         | 
| 56 | 
            +
                                 universe_domain: nil,
         | 
| 57 | 
            +
                                 numeric_enums: false,
         | 
| 58 | 
            +
                                 raise_faraday_errors: true
         | 
| 59 | 
            +
                    setup_universe_domain universe_domain: universe_domain,
         | 
| 60 | 
            +
                                          endpoint: endpoint,
         | 
| 61 | 
            +
                                          endpoint_template: endpoint_template,
         | 
| 62 | 
            +
                                          credentials: credentials
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    endpoint_url = self.endpoint
         | 
| 65 | 
            +
                    endpoint_url = "https://#{endpoint_url}" unless /^https?:/.match? endpoint_url
         | 
| 66 | 
            +
                    endpoint_url = endpoint_url.sub %r{/$}, ""
         | 
| 49 67 |  | 
| 50 | 
            -
                    @credentials = credentials
         | 
| 51 68 | 
             
                    @numeric_enums = numeric_enums
         | 
| 52 69 |  | 
| 53 70 | 
             
                    @raise_faraday_errors = raise_faraday_errors
         | 
| 54 71 |  | 
| 55 | 
            -
                    @connection = Faraday.new url:  | 
| 72 | 
            +
                    @connection = Faraday.new url: endpoint_url do |conn|
         | 
| 56 73 | 
             
                      conn.headers = { "Content-Type" => "application/json" }
         | 
| 57 | 
            -
                      conn.request :google_authorization,  | 
| 74 | 
            +
                      conn.request :google_authorization, self.credentials unless self.credentials.is_a? ::Symbol
         | 
| 58 75 | 
             
                      conn.request :retry
         | 
| 59 76 | 
             
                      conn.response :raise_error
         | 
| 60 77 | 
             
                      conn.adapter :net_http
         | 
    
        data/lib/gapic/rest/error.rb
    CHANGED
    
    | @@ -14,6 +14,9 @@ | |
| 14 14 |  | 
| 15 15 | 
             
            require "json"
         | 
| 16 16 | 
             
            require "gapic/common/error"
         | 
| 17 | 
            +
            require "google/protobuf/well_known_types"
         | 
| 18 | 
            +
            # Not technically required but GRPC counterpart loads it and so should we for test parity
         | 
| 19 | 
            +
            require "google/rpc/error_details_pb"
         | 
| 17 20 |  | 
| 18 21 | 
             
            module Gapic
         | 
| 19 22 | 
             
              module Rest
         | 
| @@ -25,6 +28,8 @@ module Gapic | |
| 25 28 | 
             
                  attr_reader :status
         | 
| 26 29 | 
             
                  # @return [Object, nil] the details as parsed from the response body
         | 
| 27 30 | 
             
                  attr_reader :details
         | 
| 31 | 
            +
                  # The Cloud error wrapper expect to see a `status_details` property
         | 
| 32 | 
            +
                  alias status_details details
         | 
| 28 33 | 
             
                  # @return [Object, nil] the headers of the REST error
         | 
| 29 34 | 
             
                  attr_reader :headers
         | 
| 30 35 | 
             
                  # The Cloud error wrapper expect to see a `header` property
         | 
| @@ -117,7 +117,7 @@ module Gapic | |
| 117 117 | 
             
                      field_value = extract_scalar_value! request_hash, field_path_camel, field_binding.regex
         | 
| 118 118 |  | 
| 119 119 | 
             
                      if field_value
         | 
| 120 | 
            -
                        field_value = field_value.split("/").map { |segment| percent_escape | 
| 120 | 
            +
                        field_value = field_value.split("/").map { |segment| percent_escape segment }.join("/")
         | 
| 121 121 | 
             
                      end
         | 
| 122 122 |  | 
| 123 123 | 
             
                      [field_binding.field_path, field_value]
         | 
| @@ -126,7 +126,7 @@ module Gapic | |
| 126 126 |  | 
| 127 127 | 
             
                  # Percent-escapes a string.
         | 
| 128 128 | 
             
                  # @param str [String] String to escape.
         | 
| 129 | 
            -
                  # @return  | 
| 129 | 
            +
                  # @return [String] Escaped string.
         | 
| 130 130 | 
             
                  def percent_escape str
         | 
| 131 131 | 
             
                    # `+` to represent spaces is not currently supported in Showcase server.
         | 
| 132 132 | 
             
                    CGI.escape(str).gsub("+", "%20")
         | 
| @@ -218,7 +218,7 @@ module Gapic | |
| 218 218 |  | 
| 219 219 | 
             
                    # Covers the case where in `foo.bar.baz`, `baz` is still a submessage or an array.
         | 
| 220 220 | 
             
                    return nil if value.is_a?(::Hash) || value.is_a?(::Array)
         | 
| 221 | 
            -
                     | 
| 221 | 
            +
                    value.to_s if value.to_s =~ regex
         | 
| 222 222 | 
             
                  end
         | 
| 223 223 |  | 
| 224 224 | 
             
                  # Finds a value in the hash by path.
         | 
| @@ -28,7 +28,7 @@ module Gapic | |
| 28 28 |  | 
| 29 29 | 
             
                  ##
         | 
| 30 30 | 
             
                  # @private
         | 
| 31 | 
            -
                  # @param  | 
| 31 | 
            +
                  # @param underlying_op [::Object, nil, ::Faraday::Response]
         | 
| 32 32 | 
             
                  #   The underlying transport's library object that describes the active call, if any.
         | 
| 33 33 | 
             
                  def initialize underlying_op
         | 
| 34 34 | 
             
                    @underlying_op = underlying_op
         | 
| @@ -0,0 +1,84 @@ | |
| 1 | 
            +
            # Copyright 2023 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 "gapic/common/error"
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            module Gapic
         | 
| 18 | 
            +
              ##
         | 
| 19 | 
            +
              # A mixin module that provides methods for obtaining the effective universe
         | 
| 20 | 
            +
              # domain, endpoint, and credentials for a stub. This is included in
         | 
| 21 | 
            +
              # Grpc::ServiceStub and Rest::ClientStub.
         | 
| 22 | 
            +
              #
         | 
| 23 | 
            +
              module UniverseDomainConcerns
         | 
| 24 | 
            +
                ##
         | 
| 25 | 
            +
                # A substitution string for the universe domain in an endpoint template
         | 
| 26 | 
            +
                # @return [String]
         | 
| 27 | 
            +
                #
         | 
| 28 | 
            +
                ENDPOINT_SUBSTITUTION = "$UNIVERSE_DOMAIN$".freeze
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                ##
         | 
| 31 | 
            +
                # The effective endpoint
         | 
| 32 | 
            +
                # @return [String]
         | 
| 33 | 
            +
                #
         | 
| 34 | 
            +
                attr_reader :endpoint
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                ##
         | 
| 37 | 
            +
                # The effective universe domain
         | 
| 38 | 
            +
                # @return [String]
         | 
| 39 | 
            +
                #
         | 
| 40 | 
            +
                attr_reader :universe_domain
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                ##
         | 
| 43 | 
            +
                # The effective credentials
         | 
| 44 | 
            +
                #
         | 
| 45 | 
            +
                # @return [Google::Auth::Credentials, Signet::OAuth2::Client, Proc,
         | 
| 46 | 
            +
                #   ::GRPC::Core::Channel, ::GRPC::Core::ChannelCredentials]
         | 
| 47 | 
            +
                #
         | 
| 48 | 
            +
                attr_reader :credentials
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                protected
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                ##
         | 
| 53 | 
            +
                # @private
         | 
| 54 | 
            +
                # Called from the stub constructor to populate the data.
         | 
| 55 | 
            +
                #
         | 
| 56 | 
            +
                def setup_universe_domain universe_domain: nil,
         | 
| 57 | 
            +
                                          endpoint: nil,
         | 
| 58 | 
            +
                                          endpoint_template: nil,
         | 
| 59 | 
            +
                                          credentials: nil
         | 
| 60 | 
            +
                  raise ArgumentError, "endpoint or endpoint_template is required" if endpoint.nil? && endpoint_template.nil?
         | 
| 61 | 
            +
                  raise ArgumentError, "credentials is required" if credentials.nil?
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  # TODO: The env logic should live in google-cloud-env
         | 
| 64 | 
            +
                  universe_domain ||= ENV["GOOGLE_CLOUD_UNIVERSE_DOMAIN"] || "googleapis.com"
         | 
| 65 | 
            +
                  endpoint ||= endpoint_template.sub ENDPOINT_SUBSTITUTION, universe_domain
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                  if credentials.respond_to?(:universe_domain) && credentials.universe_domain != universe_domain
         | 
| 68 | 
            +
                    raise UniverseDomainMismatch,
         | 
| 69 | 
            +
                          "Universe domain is #{universe_domain} but credentials are in #{credentials.universe_domain}"
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  @universe_domain = universe_domain
         | 
| 73 | 
            +
                  @endpoint = endpoint
         | 
| 74 | 
            +
                  @credentials = credentials
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
              end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
              ##
         | 
| 79 | 
            +
              # Raised when the configured universe domain does not match the universe
         | 
| 80 | 
            +
              # domain of the credentials.
         | 
| 81 | 
            +
              #
         | 
| 82 | 
            +
              class UniverseDomainMismatch < ::Gapic::Common::Error
         | 
| 83 | 
            +
              end
         | 
| 84 | 
            +
            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.21.1
         | 
| 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: 2023- | 
| 11 | 
            +
            date: 2023-12-14 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: faraday
         | 
| @@ -56,7 +56,7 @@ dependencies: | |
| 56 56 | 
             
                requirements:
         | 
| 57 57 | 
             
                - - ">="
         | 
| 58 58 | 
             
                  - !ruby/object:Gem::Version
         | 
| 59 | 
            -
                    version: 1. | 
| 59 | 
            +
                    version: 1.4.0
         | 
| 60 60 | 
             
                - - "<"
         | 
| 61 61 | 
             
                  - !ruby/object:Gem::Version
         | 
| 62 62 | 
             
                    version: 2.a
         | 
| @@ -66,7 +66,7 @@ dependencies: | |
| 66 66 | 
             
                requirements:
         | 
| 67 67 | 
             
                - - ">="
         | 
| 68 68 | 
             
                  - !ruby/object:Gem::Version
         | 
| 69 | 
            -
                    version: 1. | 
| 69 | 
            +
                    version: 1.4.0
         | 
| 70 70 | 
             
                - - "<"
         | 
| 71 71 | 
             
                  - !ruby/object:Gem::Version
         | 
| 72 72 | 
             
                    version: 2.a
         | 
| @@ -76,7 +76,7 @@ dependencies: | |
| 76 76 | 
             
                requirements:
         | 
| 77 77 | 
             
                - - ">="
         | 
| 78 78 | 
             
                  - !ruby/object:Gem::Version
         | 
| 79 | 
            -
                    version: 1. | 
| 79 | 
            +
                    version: 1.11.0
         | 
| 80 80 | 
             
                - - "<"
         | 
| 81 81 | 
             
                  - !ruby/object:Gem::Version
         | 
| 82 82 | 
             
                    version: 2.a
         | 
| @@ -86,7 +86,7 @@ dependencies: | |
| 86 86 | 
             
                requirements:
         | 
| 87 87 | 
             
                - - ">="
         | 
| 88 88 | 
             
                  - !ruby/object:Gem::Version
         | 
| 89 | 
            -
                    version: 1. | 
| 89 | 
            +
                    version: 1.11.0
         | 
| 90 90 | 
             
                - - "<"
         | 
| 91 91 | 
             
                  - !ruby/object:Gem::Version
         | 
| 92 92 | 
             
                    version: 2.a
         | 
| @@ -96,182 +96,42 @@ dependencies: | |
| 96 96 | 
             
                requirements:
         | 
| 97 97 | 
             
                - - "~>"
         | 
| 98 98 | 
             
                  - !ruby/object:Gem::Version
         | 
| 99 | 
            -
                    version: '1. | 
| 99 | 
            +
                    version: '1.9'
         | 
| 100 100 | 
             
              type: :runtime
         | 
| 101 101 | 
             
              prerelease: false
         | 
| 102 102 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 103 103 | 
             
                requirements:
         | 
| 104 104 | 
             
                - - "~>"
         | 
| 105 105 | 
             
                  - !ruby/object:Gem::Version
         | 
| 106 | 
            -
                    version: '1. | 
| 106 | 
            +
                    version: '1.9'
         | 
| 107 107 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 108 108 | 
             
              name: google-protobuf
         | 
| 109 109 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 110 110 | 
             
                requirements:
         | 
| 111 111 | 
             
                - - "~>"
         | 
| 112 112 | 
             
                  - !ruby/object:Gem::Version
         | 
| 113 | 
            -
                    version: '3. | 
| 113 | 
            +
                    version: '3.18'
         | 
| 114 114 | 
             
              type: :runtime
         | 
| 115 115 | 
             
              prerelease: false
         | 
| 116 116 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 117 117 | 
             
                requirements:
         | 
| 118 118 | 
             
                - - "~>"
         | 
| 119 119 | 
             
                  - !ruby/object:Gem::Version
         | 
| 120 | 
            -
                    version: '3. | 
| 120 | 
            +
                    version: '3.18'
         | 
| 121 121 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 122 122 | 
             
              name: grpc
         | 
| 123 123 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 124 124 | 
             
                requirements:
         | 
| 125 125 | 
             
                - - "~>"
         | 
| 126 126 | 
             
                  - !ruby/object:Gem::Version
         | 
| 127 | 
            -
                    version: '1. | 
| 127 | 
            +
                    version: '1.59'
         | 
| 128 128 | 
             
              type: :runtime
         | 
| 129 129 | 
             
              prerelease: false
         | 
| 130 130 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 131 131 | 
             
                requirements:
         | 
| 132 132 | 
             
                - - "~>"
         | 
| 133 133 | 
             
                  - !ruby/object:Gem::Version
         | 
| 134 | 
            -
                    version: '1. | 
| 135 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 136 | 
            -
              name: google-cloud-core
         | 
| 137 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 138 | 
            -
                requirements:
         | 
| 139 | 
            -
                - - "~>"
         | 
| 140 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 141 | 
            -
                    version: '1.5'
         | 
| 142 | 
            -
              type: :development
         | 
| 143 | 
            -
              prerelease: false
         | 
| 144 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 145 | 
            -
                requirements:
         | 
| 146 | 
            -
                - - "~>"
         | 
| 147 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 148 | 
            -
                    version: '1.5'
         | 
| 149 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 150 | 
            -
              name: google-style
         | 
| 151 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 152 | 
            -
                requirements:
         | 
| 153 | 
            -
                - - "~>"
         | 
| 154 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 155 | 
            -
                    version: 1.26.0
         | 
| 156 | 
            -
              type: :development
         | 
| 157 | 
            -
              prerelease: false
         | 
| 158 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 159 | 
            -
                requirements:
         | 
| 160 | 
            -
                - - "~>"
         | 
| 161 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 162 | 
            -
                    version: 1.26.0
         | 
| 163 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 164 | 
            -
              name: minitest
         | 
| 165 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 166 | 
            -
                requirements:
         | 
| 167 | 
            -
                - - "~>"
         | 
| 168 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 169 | 
            -
                    version: '5.16'
         | 
| 170 | 
            -
              type: :development
         | 
| 171 | 
            -
              prerelease: false
         | 
| 172 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 173 | 
            -
                requirements:
         | 
| 174 | 
            -
                - - "~>"
         | 
| 175 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 176 | 
            -
                    version: '5.16'
         | 
| 177 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 178 | 
            -
              name: minitest-autotest
         | 
| 179 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 180 | 
            -
                requirements:
         | 
| 181 | 
            -
                - - "~>"
         | 
| 182 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 183 | 
            -
                    version: '1.0'
         | 
| 184 | 
            -
              type: :development
         | 
| 185 | 
            -
              prerelease: false
         | 
| 186 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 187 | 
            -
                requirements:
         | 
| 188 | 
            -
                - - "~>"
         | 
| 189 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 190 | 
            -
                    version: '1.0'
         | 
| 191 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 192 | 
            -
              name: minitest-focus
         | 
| 193 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 194 | 
            -
                requirements:
         | 
| 195 | 
            -
                - - "~>"
         | 
| 196 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 197 | 
            -
                    version: '1.1'
         | 
| 198 | 
            -
              type: :development
         | 
| 199 | 
            -
              prerelease: false
         | 
| 200 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 201 | 
            -
                requirements:
         | 
| 202 | 
            -
                - - "~>"
         | 
| 203 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 204 | 
            -
                    version: '1.1'
         | 
| 205 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 206 | 
            -
              name: minitest-rg
         | 
| 207 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 208 | 
            -
                requirements:
         | 
| 209 | 
            -
                - - "~>"
         | 
| 210 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 211 | 
            -
                    version: '5.2'
         | 
| 212 | 
            -
              type: :development
         | 
| 213 | 
            -
              prerelease: false
         | 
| 214 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 215 | 
            -
                requirements:
         | 
| 216 | 
            -
                - - "~>"
         | 
| 217 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 218 | 
            -
                    version: '5.2'
         | 
| 219 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 220 | 
            -
              name: pry
         | 
| 221 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 222 | 
            -
                requirements:
         | 
| 223 | 
            -
                - - ">="
         | 
| 224 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 225 | 
            -
                    version: '0.14'
         | 
| 226 | 
            -
              type: :development
         | 
| 227 | 
            -
              prerelease: false
         | 
| 228 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 229 | 
            -
                requirements:
         | 
| 230 | 
            -
                - - ">="
         | 
| 231 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 232 | 
            -
                    version: '0.14'
         | 
| 233 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 234 | 
            -
              name: rake
         | 
| 235 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 236 | 
            -
                requirements:
         | 
| 237 | 
            -
                - - ">="
         | 
| 238 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 239 | 
            -
                    version: '12.0'
         | 
| 240 | 
            -
              type: :development
         | 
| 241 | 
            -
              prerelease: false
         | 
| 242 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 243 | 
            -
                requirements:
         | 
| 244 | 
            -
                - - ">="
         | 
| 245 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 246 | 
            -
                    version: '12.0'
         | 
| 247 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 248 | 
            -
              name: redcarpet
         | 
| 249 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 250 | 
            -
                requirements:
         | 
| 251 | 
            -
                - - "~>"
         | 
| 252 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 253 | 
            -
                    version: '3.0'
         | 
| 254 | 
            -
              type: :development
         | 
| 255 | 
            -
              prerelease: false
         | 
| 256 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 257 | 
            -
                requirements:
         | 
| 258 | 
            -
                - - "~>"
         | 
| 259 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 260 | 
            -
                    version: '3.0'
         | 
| 261 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 262 | 
            -
              name: yard
         | 
| 263 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 264 | 
            -
                requirements:
         | 
| 265 | 
            -
                - - "~>"
         | 
| 266 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 267 | 
            -
                    version: '0.9'
         | 
| 268 | 
            -
              type: :development
         | 
| 269 | 
            -
              prerelease: false
         | 
| 270 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 271 | 
            -
                requirements:
         | 
| 272 | 
            -
                - - "~>"
         | 
| 273 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 274 | 
            -
                    version: '0.9'
         | 
| 134 | 
            +
                    version: '1.59'
         | 
| 275 135 | 
             
            description: 
         | 
| 276 136 | 
             
            email:
         | 
| 277 137 | 
             
            - googleapis-packages@google.com
         | 
| @@ -300,9 +160,12 @@ files: | |
| 300 160 | 
             
            - lib/gapic/grpc.rb
         | 
| 301 161 | 
             
            - lib/gapic/grpc/errors.rb
         | 
| 302 162 | 
             
            - lib/gapic/grpc/service_stub.rb
         | 
| 163 | 
            +
            - lib/gapic/grpc/service_stub/channel.rb
         | 
| 164 | 
            +
            - lib/gapic/grpc/service_stub/channel_pool.rb
         | 
| 303 165 | 
             
            - lib/gapic/grpc/service_stub/rpc_call.rb
         | 
| 304 166 | 
             
            - lib/gapic/grpc/status_details.rb
         | 
| 305 167 | 
             
            - lib/gapic/headers.rb
         | 
| 168 | 
            +
            - lib/gapic/lru_hash.rb
         | 
| 306 169 | 
             
            - lib/gapic/operation.rb
         | 
| 307 170 | 
             
            - lib/gapic/operation/retry_policy.rb
         | 
| 308 171 | 
             
            - lib/gapic/paged_enumerable.rb
         | 
| @@ -319,6 +182,7 @@ files: | |
| 319 182 | 
             
            - lib/gapic/rest/threaded_enumerator.rb
         | 
| 320 183 | 
             
            - lib/gapic/rest/transport_operation.rb
         | 
| 321 184 | 
             
            - lib/gapic/stream_input.rb
         | 
| 185 | 
            +
            - lib/gapic/universe_domain_concerns.rb
         | 
| 322 186 | 
             
            homepage: https://github.com/googleapis/gapic-generator-ruby
         | 
| 323 187 | 
             
            licenses:
         | 
| 324 188 | 
             
            - Apache-2.0
         | 
| @@ -331,14 +195,14 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 331 195 | 
             
              requirements:
         | 
| 332 196 | 
             
              - - ">="
         | 
| 333 197 | 
             
                - !ruby/object:Gem::Version
         | 
| 334 | 
            -
                  version: '2. | 
| 198 | 
            +
                  version: '2.7'
         | 
| 335 199 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 336 200 | 
             
              requirements:
         | 
| 337 201 | 
             
              - - ">="
         | 
| 338 202 | 
             
                - !ruby/object:Gem::Version
         | 
| 339 203 | 
             
                  version: '0'
         | 
| 340 204 | 
             
            requirements: []
         | 
| 341 | 
            -
            rubygems_version: 3.4. | 
| 205 | 
            +
            rubygems_version: 3.4.19
         | 
| 342 206 | 
             
            signing_key: 
         | 
| 343 207 | 
             
            specification_version: 4
         | 
| 344 208 | 
             
            summary: Common code for GAPIC-generated API clients
         |