1# Copyright 2017 gRPC authors. 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# http://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. 14require_relative 'interceptor_registry' 15 16# GRPC contains the General RPC module. 17module GRPC 18 ## 19 # Base class for interception in GRPC 20 # 21 class Interceptor 22 ## 23 # @param [Hash] options A hash of options that will be used 24 # by the interceptor. This is an EXPERIMENTAL API. 25 # 26 def initialize(options = {}) 27 @options = options || {} 28 end 29 end 30 31 ## 32 # ClientInterceptor allows for wrapping outbound gRPC client stub requests. 33 # This is an EXPERIMENTAL API. 34 # 35 class ClientInterceptor < Interceptor 36 ## 37 # Intercept a unary request response call 38 # 39 # @param [Object] request 40 # @param [GRPC::ActiveCall] call 41 # @param [Method] method 42 # @param [Hash] metadata 43 # 44 def request_response(request: nil, call: nil, method: nil, metadata: nil) 45 GRPC.logger.debug "Intercepting request response method #{method}" \ 46 " for request #{request} with call #{call} and metadata: #{metadata}" 47 yield 48 end 49 50 ## 51 # Intercept a client streaming call 52 # 53 # @param [Enumerable] requests 54 # @param [GRPC::ActiveCall] call 55 # @param [Method] method 56 # @param [Hash] metadata 57 # 58 def client_streamer(requests: nil, call: nil, method: nil, metadata: nil) 59 GRPC.logger.debug "Intercepting client streamer method #{method}" \ 60 " for requests #{requests} with call #{call} and metadata: #{metadata}" 61 yield 62 end 63 64 ## 65 # Intercept a server streaming call 66 # 67 # @param [Object] request 68 # @param [GRPC::ActiveCall] call 69 # @param [Method] method 70 # @param [Hash] metadata 71 # 72 def server_streamer(request: nil, call: nil, method: nil, metadata: nil) 73 GRPC.logger.debug "Intercepting server streamer method #{method}" \ 74 " for request #{request} with call #{call} and metadata: #{metadata}" 75 yield 76 end 77 78 ## 79 # Intercept a BiDi streaming call 80 # 81 # @param [Enumerable] requests 82 # @param [GRPC::ActiveCall] call 83 # @param [Method] method 84 # @param [Hash] metadata 85 # 86 def bidi_streamer(requests: nil, call: nil, method: nil, metadata: nil) 87 GRPC.logger.debug "Intercepting bidi streamer method #{method}" \ 88 " for requests #{requests} with call #{call} and metadata: #{metadata}" 89 yield 90 end 91 end 92 93 ## 94 # ServerInterceptor allows for wrapping gRPC server execution handling. 95 # This is an EXPERIMENTAL API. 96 # 97 class ServerInterceptor < Interceptor 98 ## 99 # Intercept a unary request response call. 100 # 101 # @param [Object] request 102 # @param [GRPC::ActiveCall::SingleReqView] call 103 # @param [Method] method 104 # 105 def request_response(request: nil, call: nil, method: nil) 106 GRPC.logger.debug "Intercepting request response method #{method}" \ 107 " for request #{request} with call #{call}" 108 yield 109 end 110 111 ## 112 # Intercept a client streaming call 113 # 114 # @param [GRPC::ActiveCall::MultiReqView] call 115 # @param [Method] method 116 # 117 def client_streamer(call: nil, method: nil) 118 GRPC.logger.debug "Intercepting client streamer method #{method}" \ 119 " with call #{call}" 120 yield 121 end 122 123 ## 124 # Intercept a server streaming call 125 # 126 # @param [Object] request 127 # @param [GRPC::ActiveCall::SingleReqView] call 128 # @param [Method] method 129 # 130 def server_streamer(request: nil, call: nil, method: nil) 131 GRPC.logger.debug "Intercepting server streamer method #{method}" \ 132 " for request #{request} with call #{call}" 133 yield 134 end 135 136 ## 137 # Intercept a BiDi streaming call 138 # 139 # @param [Enumerable<Object>] requests 140 # @param [GRPC::ActiveCall::MultiReqView] call 141 # @param [Method] method 142 # 143 def bidi_streamer(requests: nil, call: nil, method: nil) 144 GRPC.logger.debug "Intercepting bidi streamer method #{method}" \ 145 " for requests #{requests} with call #{call}" 146 yield 147 end 148 end 149 150 ## 151 # Represents the context in which an interceptor runs. Used to provide an 152 # injectable mechanism for handling interception. This is an EXPERIMENTAL API. 153 # 154 class InterceptionContext 155 ## 156 # @param interceptors [Array<GRPC::Interceptor>] 157 # 158 def initialize(interceptors = []) 159 @interceptors = interceptors.dup 160 end 161 162 ## 163 # Intercept the call and fire out to interceptors in a FIFO execution. 164 # This is an EXPERIMENTAL API. 165 # 166 # @param [Symbol] type The request type 167 # @param [Hash] args The arguments for the call 168 # 169 def intercept!(type, args = {}) 170 return yield if @interceptors.none? 171 172 i = @interceptors.pop 173 return yield unless i 174 175 i.send(type, args) do 176 if @interceptors.any? 177 intercept!(type, args) do 178 yield 179 end 180 else 181 yield 182 end 183 end 184 end 185 end 186end 187