tshield 0.11.13.0 → 0.11.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +0 -1
- data/README.md +37 -6
- data/Rakefile +1 -1
- data/bin/tshield +2 -10
- data/config/tshield.yml +7 -0
- data/lib/tshield.rb +1 -1
- data/lib/tshield/configuration.rb +5 -0
- data/lib/tshield/extensions/string_extensions.rb +8 -0
- data/lib/tshield/grpc.rb +73 -0
- data/lib/tshield/grpc/vcr.rb +84 -0
- data/lib/tshield/server.rb +1 -1
- data/lib/tshield/version.rb +1 -1
- data/spec/spec_helper.rb +0 -5
- data/spec/tshield/configuration_spec.rb +19 -0
- data/spec/tshield/fixtures/config/tshield-without-grpc.yml +17 -0
- data/spec/tshield/fixtures/config/tshield.yml +2 -0
- data/spec/tshield/fixtures/proto/test_services_pb.rb +13 -0
- data/spec/tshield/grpc_spec.rb +24 -0
- data/tshield.gemspec +3 -0
- metadata +70 -3
- data/lib/tshield/simple_tcp_server.rb +0 -28
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 36efe1ccd1ea061d66f046d338b76fcb0b9b6f30c740ecadabe6c774939dcd5b
|
|
4
|
+
data.tar.gz: 38559f053d082a577260aa94a115a66937ffb9ce45c52fee3a60339ade9ea32d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ba74b2c25265ef74b62b297db19795b387c1bfe4821dce609d17cf99b00d663d58f3f889e134d58a22b679b9f1781bf00c64117fdd1e097111c7fc2cfaab5069
|
|
7
|
+
data.tar.gz: ce7f58cb6bf00a942b56464235cd8fa002c6489aa6643c057f9d201eeebafe3e57be70724f8bca03f8068a5468caf3d62caea846869305d145edca2ed4d19322
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -13,9 +13,10 @@ TShield is an open source proxy for mocks API responses.
|
|
|
13
13
|
* REST
|
|
14
14
|
* SOAP
|
|
15
15
|
* Session manager to separate multiple scenarios (success, error, sucess variation, ...)
|
|
16
|
+
gRPC [EXPERIMENTAL]
|
|
16
17
|
* Lightweight
|
|
17
18
|
* MIT license
|
|
18
|
-
|
|
19
|
+
|
|
19
20
|
## Table of Contents
|
|
20
21
|
|
|
21
22
|
* [Basic Usage](#basic-usage)
|
|
@@ -26,7 +27,7 @@ TShield is an open source proxy for mocks API responses.
|
|
|
26
27
|
* [Features](#features)
|
|
27
28
|
* [Examples](#examples)
|
|
28
29
|
* [Contributing](#contributing)
|
|
29
|
-
|
|
30
|
+
|
|
30
31
|
## Basic Usage
|
|
31
32
|
### Install
|
|
32
33
|
|
|
@@ -37,7 +38,7 @@ TShield is an open source proxy for mocks API responses.
|
|
|
37
38
|
To run server execute this command
|
|
38
39
|
|
|
39
40
|
tshield
|
|
40
|
-
|
|
41
|
+
|
|
41
42
|
Default port is `4567`
|
|
42
43
|
|
|
43
44
|
#### Command Line Options
|
|
@@ -102,7 +103,7 @@ To register stub into a session create an object with following attributes:
|
|
|
102
103
|
* **session**: name of session.
|
|
103
104
|
* **stubs**: an array with objects described above.
|
|
104
105
|
|
|
105
|
-
### Example of matching configuration
|
|
106
|
+
### Example of HTTP matching configuration
|
|
106
107
|
|
|
107
108
|
```json
|
|
108
109
|
[
|
|
@@ -163,7 +164,7 @@ To register stub into a session create an object with following attributes:
|
|
|
163
164
|
]
|
|
164
165
|
```
|
|
165
166
|
|
|
166
|
-
## Config options for VCR
|
|
167
|
+
## Config options for HTTP VCR
|
|
167
168
|
```yaml
|
|
168
169
|
request:
|
|
169
170
|
timeout: 8
|
|
@@ -227,7 +228,7 @@ You can use TShield sessions to separate multiple scenarios for your mocks
|
|
|
227
228
|
By default TShield save request/response into
|
|
228
229
|
|
|
229
230
|
requests/<<domain_name>>/<<resource_with_param>>/<<http_verb>>/<<index_based.content and json>>
|
|
230
|
-
|
|
231
|
+
|
|
231
232
|
If you start a session a folder with de **session_name** will be placed between **"requests/"** and **"<<domain_name>>"**
|
|
232
233
|
|
|
233
234
|
### Start TShield session
|
|
@@ -249,6 +250,36 @@ _DELETE_ to http://localhost:4567/sessions
|
|
|
249
250
|
curl -X DELETE \
|
|
250
251
|
http://localhost:4567/sessions
|
|
251
252
|
```
|
|
253
|
+
## [Experimental] Config options for gRPC
|
|
254
|
+
|
|
255
|
+
```yaml
|
|
256
|
+
grpc:
|
|
257
|
+
port: 5678
|
|
258
|
+
proto_dir: 'proto'
|
|
259
|
+
services:
|
|
260
|
+
'helloworld_services_pb':
|
|
261
|
+
module: 'Helloworld::Greeter'
|
|
262
|
+
hostname: '0.0.0.0:50051'
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
### Not Implemented Yet
|
|
267
|
+
|
|
268
|
+
- Sessions
|
|
269
|
+
- Matching
|
|
270
|
+
|
|
271
|
+
### Configuration
|
|
272
|
+
|
|
273
|
+
First, generate ruby files from proto files. Use `grpc_tools_ruby_protoc`
|
|
274
|
+
present in the gem `grpc-tools`. Example:
|
|
275
|
+
|
|
276
|
+
`grpc_tools_ruby_protoc -I proto --ruby_out=proto --grpc_out=proto proto/<INPUT>.proto`
|
|
277
|
+
|
|
278
|
+
Call example in component_tests using [grpcurl](https://github.com/fullstorydev/grpcurl):
|
|
279
|
+
|
|
280
|
+
`grpcurl -plaintext -import-path component_tests/proto -proto helloworld.proto -d '{"name": "teste"}' localhost:5678 helloworld.Greeter/SayHello`
|
|
281
|
+
|
|
282
|
+
### Using in VCR mode
|
|
252
283
|
|
|
253
284
|
## Custom controllers
|
|
254
285
|
|
data/Rakefile
CHANGED
data/bin/tshield
CHANGED
|
@@ -5,14 +5,6 @@ require 'tshield/options'
|
|
|
5
5
|
TShield::Options.init
|
|
6
6
|
|
|
7
7
|
require 'tshield'
|
|
8
|
-
tshield = Thread.new { TShield::Server.run! }
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
puts "initializing #{tcp_server['name']}"
|
|
13
|
-
require "./servers/#{tcp_server['file']}"
|
|
14
|
-
klass = Object.const_get(tcp_server['name'])
|
|
15
|
-
Thread.new { klass.new.listen(tcp_server['port']) }
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
tshield.join
|
|
9
|
+
Thread.new { TShield::Grpc.run! }
|
|
10
|
+
TShield::Server.run!
|
data/config/tshield.yml
CHANGED
data/lib/tshield.rb
CHANGED
|
@@ -103,6 +103,11 @@ module TShield
|
|
|
103
103
|
session_path || '/sessions'
|
|
104
104
|
end
|
|
105
105
|
|
|
106
|
+
def grpc
|
|
107
|
+
defaults = { 'port' => 5678, 'proto_dir' => 'proto', 'services' => {} }
|
|
108
|
+
defaults.merge(@grpc || {})
|
|
109
|
+
end
|
|
110
|
+
|
|
106
111
|
def self.get_url_for_domain_by_path(path, config)
|
|
107
112
|
config['paths'].select { |pattern| path =~ Regexp.new(pattern) }[0]
|
|
108
113
|
end
|
|
@@ -5,6 +5,14 @@ module StringExtensions
|
|
|
5
5
|
def to_rack_name
|
|
6
6
|
"HTTP_#{upcase.tr('-', '_')}"
|
|
7
7
|
end
|
|
8
|
+
|
|
9
|
+
def underscore
|
|
10
|
+
gsub(/::/, '/')
|
|
11
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
|
12
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
|
13
|
+
.tr('-', '_')
|
|
14
|
+
.downcase
|
|
15
|
+
end
|
|
8
16
|
end
|
|
9
17
|
|
|
10
18
|
String.include StringExtensions
|
data/lib/tshield/grpc.rb
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: false
|
|
2
|
+
|
|
3
|
+
require 'grpc'
|
|
4
|
+
|
|
5
|
+
require 'tshield/configuration'
|
|
6
|
+
require 'tshield/grpc/vcr'
|
|
7
|
+
|
|
8
|
+
module TShield
|
|
9
|
+
module Grpc
|
|
10
|
+
module RequestHandler
|
|
11
|
+
include TShield::Grpc::VCR
|
|
12
|
+
def handler(method_name, request, parameters)
|
|
13
|
+
options = self.class.options
|
|
14
|
+
handler_in_vcr_mode(method_name, request, parameters, options)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
def self.run!
|
|
18
|
+
@configuration = TShield::Configuration.singleton.grpc
|
|
19
|
+
|
|
20
|
+
lib_dir = File.join(Dir.pwd, @configuration['proto_dir'])
|
|
21
|
+
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
|
|
22
|
+
|
|
23
|
+
TShield.logger.info("loading proto files from #{lib_dir}")
|
|
24
|
+
|
|
25
|
+
bind = "0.0.0.0:#{@configuration['port']}"
|
|
26
|
+
TShield.logger.info("Starting gRPC server in #{bind}")
|
|
27
|
+
|
|
28
|
+
server = GRPC::RpcServer.new
|
|
29
|
+
server.add_http2_port(bind, :this_port_is_insecure)
|
|
30
|
+
|
|
31
|
+
services = load_services(@configuration['services'])
|
|
32
|
+
services.each do |class_service|
|
|
33
|
+
class_service.include RequestHandler
|
|
34
|
+
server.handle(class_service)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
server.run_till_terminated_or_interrupted([1, 'int', 'SIGQUIT']) unless services.empty?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.load_services(services)
|
|
41
|
+
handlers = []
|
|
42
|
+
number_of_handlers = 0
|
|
43
|
+
services.each do |file, options|
|
|
44
|
+
require file
|
|
45
|
+
|
|
46
|
+
base = Object.const_get("#{options['module']}::Service")
|
|
47
|
+
number_of_handlers += 1
|
|
48
|
+
|
|
49
|
+
implementation = build_handler(base, base.rpc_descs, number_of_handlers, options)
|
|
50
|
+
handlers << implementation
|
|
51
|
+
end
|
|
52
|
+
handlers
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def self.build_handler(base, descriptions, number_of_handlers, options)
|
|
56
|
+
handler = Class.new(base) do
|
|
57
|
+
class << self
|
|
58
|
+
attr_writer :options
|
|
59
|
+
attr_reader :options
|
|
60
|
+
end
|
|
61
|
+
descriptions.each do |service_name, description|
|
|
62
|
+
puts description
|
|
63
|
+
method_name = service_name.to_s.underscore.to_sym
|
|
64
|
+
define_method(method_name) do |request, parameters|
|
|
65
|
+
handler(__method__, request, parameters)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
handler.options = options
|
|
70
|
+
TShield::Grpc.const_set "GrpcService#{number_of_handlers}", handler
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'tshield/sessions'
|
|
4
|
+
|
|
5
|
+
module TShield
|
|
6
|
+
module Grpc
|
|
7
|
+
module VCR
|
|
8
|
+
def handler_in_vcr_mode(method_name, request, parameters, options)
|
|
9
|
+
parameters.peer =~ /\[(.+?)\]/
|
|
10
|
+
@session = TShield::Sessions.current(Regexp.last_match(1))
|
|
11
|
+
|
|
12
|
+
TShield.logger.info("grpc using session #{@session || 'default'}")
|
|
13
|
+
module_name = options['module']
|
|
14
|
+
|
|
15
|
+
path = create_destiny(module_name, method_name, request)
|
|
16
|
+
response = saved_response(path)
|
|
17
|
+
if response
|
|
18
|
+
TShield.logger.info("returning saved response for request #{request.to_json} saved into #{hexdigest(request)}")
|
|
19
|
+
return response
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
TShield.logger.info("calling server to get response for #{request.to_json}")
|
|
23
|
+
client_class = Object.const_get("#{module_name}::Stub")
|
|
24
|
+
client_instance = client_class.new(options['hostname'], :this_channel_is_insecure)
|
|
25
|
+
response = client_instance.send(method_name, request)
|
|
26
|
+
save_request_and_response(path, request, response)
|
|
27
|
+
response
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def saved_response(path)
|
|
31
|
+
response_file = File.join(path, 'response')
|
|
32
|
+
return false unless File.exist? response_file
|
|
33
|
+
|
|
34
|
+
content = JSON.parse File.open(response_file).read
|
|
35
|
+
response_class = File.open(File.join(path, 'response_class')).read.strip
|
|
36
|
+
Kernel.const_get(response_class).new(content)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def save_request_and_response(path, request, response)
|
|
40
|
+
save_request(path, request)
|
|
41
|
+
save_response(path, response)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def save_request(path, request)
|
|
45
|
+
file = File.open(File.join(path, 'original_request'), 'w')
|
|
46
|
+
file.puts request.to_json
|
|
47
|
+
file.close
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def save_response(path, response)
|
|
51
|
+
file = File.open(File.join(path, 'response'), 'w')
|
|
52
|
+
file.puts response.to_json
|
|
53
|
+
file.close
|
|
54
|
+
|
|
55
|
+
response_class = File.open(File.join(path, 'response_class'), 'w')
|
|
56
|
+
response_class.puts response.class.to_s
|
|
57
|
+
response_class.close
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def complete_path(module_name, method_name, request)
|
|
61
|
+
@session_name = (@session || {})[:name]
|
|
62
|
+
path = ['requests', 'grpc', @session_name, module_name, method_name.to_s, hexdigest(request)].compact
|
|
63
|
+
path
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def create_destiny(module_name, method_name, request)
|
|
67
|
+
current_path = []
|
|
68
|
+
|
|
69
|
+
path = complete_path(module_name, method_name, request)
|
|
70
|
+
TShield.logger.info("using path #{path}")
|
|
71
|
+
path.each do |path|
|
|
72
|
+
current_path << path
|
|
73
|
+
destiny = File.join current_path
|
|
74
|
+
Dir.mkdir destiny unless File.exist? destiny
|
|
75
|
+
end
|
|
76
|
+
path
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def hexdigest(request)
|
|
80
|
+
Digest::SHA1.hexdigest request.to_json
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
data/lib/tshield/server.rb
CHANGED
|
@@ -17,6 +17,7 @@ module TShield
|
|
|
17
17
|
set :views, File.join(File.dirname(__FILE__), 'views')
|
|
18
18
|
set :bind, '0.0.0.0'
|
|
19
19
|
set :port, TShield::Options.instance.port
|
|
20
|
+
set :server, :puma
|
|
20
21
|
|
|
21
22
|
configure do
|
|
22
23
|
enable :cross_origin
|
|
@@ -56,7 +57,6 @@ module TShield
|
|
|
56
57
|
|
|
57
58
|
def self.run!
|
|
58
59
|
register_resources
|
|
59
|
-
require 'byebug'
|
|
60
60
|
super
|
|
61
61
|
end
|
|
62
62
|
end
|
data/lib/tshield/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
|
@@ -35,6 +35,12 @@ describe TShield::Configuration do
|
|
|
35
35
|
)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
context 'on grpc configuration' do
|
|
39
|
+
it 'recover server port' do
|
|
40
|
+
expect(@configuration.grpc['port']).to(eq(5678))
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
38
44
|
context 'on load filters' do
|
|
39
45
|
it 'recover filters for a domain' do
|
|
40
46
|
expect(@configuration.get_filters('example.org')).to eq([ExampleFilter])
|
|
@@ -72,4 +78,17 @@ describe TShield::Configuration do
|
|
|
72
78
|
expect { TShield::Configuration.singleton }.to raise_error RuntimeError
|
|
73
79
|
end
|
|
74
80
|
end
|
|
81
|
+
|
|
82
|
+
context 'on config exists without grpc entry' do
|
|
83
|
+
before :each do
|
|
84
|
+
options_instance = double
|
|
85
|
+
allow(options_instance).to receive(:configuration_file)
|
|
86
|
+
.and_return('spec/tshield/fixtures/config/tshield-without-grpc.yml')
|
|
87
|
+
allow(TShield::Options).to receive(:instance).and_return(options_instance)
|
|
88
|
+
@configuration = TShield::Configuration.singleton
|
|
89
|
+
end
|
|
90
|
+
it 'should set default value for port' do
|
|
91
|
+
expect(@configuration.grpc).to eql('port' => 5678, 'proto_dir' => 'proto', 'services' => {})
|
|
92
|
+
end
|
|
93
|
+
end
|
|
75
94
|
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
request:
|
|
3
|
+
timeout: 0
|
|
4
|
+
domains:
|
|
5
|
+
'example.org':
|
|
6
|
+
name: 'example.org'
|
|
7
|
+
filters:
|
|
8
|
+
- 'ExampleFilter'
|
|
9
|
+
paths:
|
|
10
|
+
- '/api/one'
|
|
11
|
+
- '/api/two'
|
|
12
|
+
skip_query_params:
|
|
13
|
+
- 'a'
|
|
14
|
+
'example.com':
|
|
15
|
+
name: 'example.com'
|
|
16
|
+
paths:
|
|
17
|
+
- '/api/three'
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
require 'tshield/grpc'
|
|
6
|
+
|
|
7
|
+
describe TShield::Grpc do
|
|
8
|
+
context 'on load services' do
|
|
9
|
+
before :each do
|
|
10
|
+
lib_dir = File.join(__dir__, 'fixtures/proto')
|
|
11
|
+
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
|
|
12
|
+
|
|
13
|
+
@services = {
|
|
14
|
+
'test_services_pb' => { 'module' => 'TestServices', 'hostname' => '0.0.0.0:5678' }
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'should implement a service from options' do
|
|
19
|
+
implementation = TShield::Grpc.load_services(@services).first
|
|
20
|
+
instance = implementation.new
|
|
21
|
+
expect(instance.respond_to?(:service_method)).to be_truthy
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
data/tshield.gemspec
CHANGED
|
@@ -25,8 +25,11 @@ Gem::Specification.new do |s|
|
|
|
25
25
|
s.required_ruby_version = '>= 2.3'
|
|
26
26
|
|
|
27
27
|
s.add_dependency('byebug', '~> 11.0', '>= 11.0.1')
|
|
28
|
+
s.add_dependency('grpc', '~> 1.28', '>= 1.28.0')
|
|
29
|
+
s.add_dependency('grpc-tools', '~> 1.28', '>= 1.28.0')
|
|
28
30
|
s.add_dependency('httparty', '~> 0.14', '>= 0.14.0')
|
|
29
31
|
s.add_dependency('json', '~> 2.0', '>= 2.0')
|
|
32
|
+
s.add_dependency('puma', '~> 4.3', '>= 4.3.3')
|
|
30
33
|
s.add_dependency('sinatra', '~> 1.4', '>= 1.4.0')
|
|
31
34
|
s.add_dependency('sinatra-cross_origin', '~> 0.4.0', '>= 0.4')
|
|
32
35
|
s.add_development_dependency('coveralls')
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tshield
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.11.
|
|
4
|
+
version: 0.11.18.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Diego Rubin
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2020-
|
|
12
|
+
date: 2020-07-09 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: byebug
|
|
@@ -31,6 +31,46 @@ dependencies:
|
|
|
31
31
|
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
33
|
version: 11.0.1
|
|
34
|
+
- !ruby/object:Gem::Dependency
|
|
35
|
+
name: grpc
|
|
36
|
+
requirement: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: 1.28.0
|
|
41
|
+
- - "~>"
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '1.28'
|
|
44
|
+
type: :runtime
|
|
45
|
+
prerelease: false
|
|
46
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
47
|
+
requirements:
|
|
48
|
+
- - ">="
|
|
49
|
+
- !ruby/object:Gem::Version
|
|
50
|
+
version: 1.28.0
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.28'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: grpc-tools
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: 1.28.0
|
|
61
|
+
- - "~>"
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: '1.28'
|
|
64
|
+
type: :runtime
|
|
65
|
+
prerelease: false
|
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
67
|
+
requirements:
|
|
68
|
+
- - ">="
|
|
69
|
+
- !ruby/object:Gem::Version
|
|
70
|
+
version: 1.28.0
|
|
71
|
+
- - "~>"
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '1.28'
|
|
34
74
|
- !ruby/object:Gem::Dependency
|
|
35
75
|
name: httparty
|
|
36
76
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -71,6 +111,26 @@ dependencies:
|
|
|
71
111
|
- - "~>"
|
|
72
112
|
- !ruby/object:Gem::Version
|
|
73
113
|
version: '2.0'
|
|
114
|
+
- !ruby/object:Gem::Dependency
|
|
115
|
+
name: puma
|
|
116
|
+
requirement: !ruby/object:Gem::Requirement
|
|
117
|
+
requirements:
|
|
118
|
+
- - "~>"
|
|
119
|
+
- !ruby/object:Gem::Version
|
|
120
|
+
version: '4.3'
|
|
121
|
+
- - ">="
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: 4.3.3
|
|
124
|
+
type: :runtime
|
|
125
|
+
prerelease: false
|
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
127
|
+
requirements:
|
|
128
|
+
- - "~>"
|
|
129
|
+
- !ruby/object:Gem::Version
|
|
130
|
+
version: '4.3'
|
|
131
|
+
- - ">="
|
|
132
|
+
- !ruby/object:Gem::Version
|
|
133
|
+
version: 4.3.3
|
|
74
134
|
- !ruby/object:Gem::Dependency
|
|
75
135
|
name: sinatra
|
|
76
136
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -367,6 +427,8 @@ files:
|
|
|
367
427
|
- lib/tshield/controllers/sessions.rb
|
|
368
428
|
- lib/tshield/counter.rb
|
|
369
429
|
- lib/tshield/extensions/string_extensions.rb
|
|
430
|
+
- lib/tshield/grpc.rb
|
|
431
|
+
- lib/tshield/grpc/vcr.rb
|
|
370
432
|
- lib/tshield/logger.rb
|
|
371
433
|
- lib/tshield/matching/filters.rb
|
|
372
434
|
- lib/tshield/options.rb
|
|
@@ -376,15 +438,17 @@ files:
|
|
|
376
438
|
- lib/tshield/response.rb
|
|
377
439
|
- lib/tshield/server.rb
|
|
378
440
|
- lib/tshield/sessions.rb
|
|
379
|
-
- lib/tshield/simple_tcp_server.rb
|
|
380
441
|
- lib/tshield/version.rb
|
|
381
442
|
- spec/spec_helper.rb
|
|
382
443
|
- spec/tshield/after_filter_spec.rb
|
|
383
444
|
- spec/tshield/configuration_spec.rb
|
|
384
445
|
- spec/tshield/controllers/requests_spec.rb
|
|
446
|
+
- spec/tshield/fixtures/config/tshield-without-grpc.yml
|
|
385
447
|
- spec/tshield/fixtures/config/tshield.yml
|
|
386
448
|
- spec/tshield/fixtures/filters/example_filter.rb
|
|
387
449
|
- spec/tshield/fixtures/matching/example.json
|
|
450
|
+
- spec/tshield/fixtures/proto/test_services_pb.rb
|
|
451
|
+
- spec/tshield/grpc_spec.rb
|
|
388
452
|
- spec/tshield/options_spec.rb
|
|
389
453
|
- spec/tshield/request_matching_spec.rb
|
|
390
454
|
- spec/tshield/request_vcr_spec.rb
|
|
@@ -415,11 +479,14 @@ summary: Proxy for mocks API responses
|
|
|
415
479
|
test_files:
|
|
416
480
|
- spec/spec_helper.rb
|
|
417
481
|
- spec/tshield/request_matching_spec.rb
|
|
482
|
+
- spec/tshield/grpc_spec.rb
|
|
418
483
|
- spec/tshield/configuration_spec.rb
|
|
419
484
|
- spec/tshield/request_vcr_spec.rb
|
|
420
485
|
- spec/tshield/controllers/requests_spec.rb
|
|
421
486
|
- spec/tshield/options_spec.rb
|
|
422
487
|
- spec/tshield/after_filter_spec.rb
|
|
423
488
|
- spec/tshield/fixtures/matching/example.json
|
|
489
|
+
- spec/tshield/fixtures/proto/test_services_pb.rb
|
|
424
490
|
- spec/tshield/fixtures/filters/example_filter.rb
|
|
425
491
|
- spec/tshield/fixtures/config/tshield.yml
|
|
492
|
+
- spec/tshield/fixtures/config/tshield-without-grpc.yml
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'socket'
|
|
4
|
-
|
|
5
|
-
module TShield
|
|
6
|
-
class SimpleTCPServer
|
|
7
|
-
def initialize
|
|
8
|
-
@running = true
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def on_connect(_client)
|
|
12
|
-
raise 'should implement method on_connect'
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def close
|
|
16
|
-
@running = false
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def listen(port)
|
|
20
|
-
puts "listening #{port}"
|
|
21
|
-
@server = TCPServer.new(port)
|
|
22
|
-
while @running
|
|
23
|
-
client = @server.accept
|
|
24
|
-
on_connect(client)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|