tshield 0.11.14.0 → 0.11.19.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 +36 -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 +87 -0
- data/lib/tshield/server.rb +0 -1
- data/lib/tshield/sessions.rb +3 -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 +2 -0
- metadata +50 -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: d7be1450b970496e9bc17514f42fcda00e98cf8e0b5e269b54b809f38e752653
|
4
|
+
data.tar.gz: fd139f9746a3cd6470aec409b809f0d62b6af0915ca0db910a64a7470ad6f44b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9727017f7c245277e64ab4bb4eca0a82f08eaf8ceb0c4b4424693f42dc2267eb0420ea15b557adadba4a69eb3116e7fca60717686a641b8602e77a4d99f183e
|
7
|
+
data.tar.gz: c4d633f5d08a2801de7e30e56a2a947b64d3e91db13ca803689a2f05d15053812eeb82585f7058e6a0a2ee9a72170b9d0f5f44557c751f7ce77800073aa23f2e
|
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,35 @@ _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
|
+
- Matching
|
269
|
+
|
270
|
+
### Configuration
|
271
|
+
|
272
|
+
First, generate ruby files from proto files. Use `grpc_tools_ruby_protoc`
|
273
|
+
present in the gem `grpc-tools`. Example:
|
274
|
+
|
275
|
+
`grpc_tools_ruby_protoc -I proto --ruby_out=proto --grpc_out=proto proto/<INPUT>.proto`
|
276
|
+
|
277
|
+
Call example in component_tests using [grpcurl](https://github.com/fullstorydev/grpcurl):
|
278
|
+
|
279
|
+
`grpcurl -plaintext -import-path component_tests/proto -proto helloworld.proto -d '{"name": "teste"}' localhost:5678 helloworld.Greeter/SayHello`
|
280
|
+
|
281
|
+
### Using in VCR mode
|
252
282
|
|
253
283
|
## Custom controllers
|
254
284
|
|
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,87 @@
|
|
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 =~ /ipv6:\[(.+?)\]|ipv4:(.+?):/
|
10
|
+
peer = Regexp.last_match(1) || Regexp.last_match(2)
|
11
|
+
|
12
|
+
TShield.logger.info("request from #{parameters.peer}")
|
13
|
+
@session = TShield::Sessions.current(peer)
|
14
|
+
|
15
|
+
TShield.logger.info("grpc using session #{@session || 'default'}")
|
16
|
+
module_name = options['module']
|
17
|
+
|
18
|
+
path = create_destiny(module_name, method_name, request)
|
19
|
+
response = saved_response(path)
|
20
|
+
if response
|
21
|
+
TShield.logger.info("returning saved response for request #{request.to_json} saved into #{hexdigest(request)}")
|
22
|
+
return response
|
23
|
+
end
|
24
|
+
|
25
|
+
TShield.logger.info("calling server to get response for #{request.to_json}")
|
26
|
+
client_class = Object.const_get("#{module_name}::Stub")
|
27
|
+
client_instance = client_class.new(options['hostname'], :this_channel_is_insecure)
|
28
|
+
response = client_instance.send(method_name, request)
|
29
|
+
save_request_and_response(path, request, response)
|
30
|
+
response
|
31
|
+
end
|
32
|
+
|
33
|
+
def saved_response(path)
|
34
|
+
response_file = File.join(path, 'response')
|
35
|
+
return false unless File.exist? response_file
|
36
|
+
|
37
|
+
content = JSON.parse File.open(response_file).read
|
38
|
+
response_class = File.open(File.join(path, 'response_class')).read.strip
|
39
|
+
Kernel.const_get(response_class).new(content)
|
40
|
+
end
|
41
|
+
|
42
|
+
def save_request_and_response(path, request, response)
|
43
|
+
save_request(path, request)
|
44
|
+
save_response(path, response)
|
45
|
+
end
|
46
|
+
|
47
|
+
def save_request(path, request)
|
48
|
+
file = File.open(File.join(path, 'original_request'), 'w')
|
49
|
+
file.puts request.to_json
|
50
|
+
file.close
|
51
|
+
end
|
52
|
+
|
53
|
+
def save_response(path, response)
|
54
|
+
file = File.open(File.join(path, 'response'), 'w')
|
55
|
+
file.puts response.to_json
|
56
|
+
file.close
|
57
|
+
|
58
|
+
response_class = File.open(File.join(path, 'response_class'), 'w')
|
59
|
+
response_class.puts response.class.to_s
|
60
|
+
response_class.close
|
61
|
+
end
|
62
|
+
|
63
|
+
def complete_path(module_name, method_name, request)
|
64
|
+
@session_name = (@session || {})[:name]
|
65
|
+
path = ['requests', 'grpc', @session_name, module_name, method_name.to_s, hexdigest(request)].compact
|
66
|
+
path
|
67
|
+
end
|
68
|
+
|
69
|
+
def create_destiny(module_name, method_name, request)
|
70
|
+
current_path = []
|
71
|
+
|
72
|
+
path = complete_path(module_name, method_name, request)
|
73
|
+
TShield.logger.info("using path #{path}")
|
74
|
+
path.each do |path|
|
75
|
+
current_path << path
|
76
|
+
destiny = File.join current_path
|
77
|
+
Dir.mkdir destiny unless File.exist? destiny
|
78
|
+
end
|
79
|
+
path
|
80
|
+
end
|
81
|
+
|
82
|
+
def hexdigest(request)
|
83
|
+
Digest::SHA1.hexdigest request.to_json
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/tshield/server.rb
CHANGED
data/lib/tshield/sessions.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'byebug'
|
4
3
|
require 'tshield/counter'
|
5
4
|
|
6
5
|
module TShield
|
@@ -9,14 +8,17 @@ module TShield
|
|
9
8
|
# Start and stop session for ip
|
10
9
|
module Sessions
|
11
10
|
def self.start(ip, name)
|
11
|
+
TShield.logger.info("starting session #{name} for ip #{normalize_ip(ip)}")
|
12
12
|
sessions[normalize_ip(ip)] = { name: name, counter: TShield::Counter.new }
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.stop(ip)
|
16
|
+
TShield.logger.info("stoping session for ip #{normalize_ip(ip)}")
|
16
17
|
sessions[normalize_ip(ip)] = nil
|
17
18
|
end
|
18
19
|
|
19
20
|
def self.current(ip)
|
21
|
+
TShield.logger.info("fetching session for ip #{normalize_ip(ip)}")
|
20
22
|
sessions[normalize_ip(ip)]
|
21
23
|
end
|
22
24
|
|
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,6 +25,8 @@ 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')
|
30
32
|
s.add_dependency('puma', '~> 4.3', '>= 4.3.3')
|
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.19.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
|
@@ -387,6 +427,8 @@ files:
|
|
387
427
|
- lib/tshield/controllers/sessions.rb
|
388
428
|
- lib/tshield/counter.rb
|
389
429
|
- lib/tshield/extensions/string_extensions.rb
|
430
|
+
- lib/tshield/grpc.rb
|
431
|
+
- lib/tshield/grpc/vcr.rb
|
390
432
|
- lib/tshield/logger.rb
|
391
433
|
- lib/tshield/matching/filters.rb
|
392
434
|
- lib/tshield/options.rb
|
@@ -396,15 +438,17 @@ files:
|
|
396
438
|
- lib/tshield/response.rb
|
397
439
|
- lib/tshield/server.rb
|
398
440
|
- lib/tshield/sessions.rb
|
399
|
-
- lib/tshield/simple_tcp_server.rb
|
400
441
|
- lib/tshield/version.rb
|
401
442
|
- spec/spec_helper.rb
|
402
443
|
- spec/tshield/after_filter_spec.rb
|
403
444
|
- spec/tshield/configuration_spec.rb
|
404
445
|
- spec/tshield/controllers/requests_spec.rb
|
446
|
+
- spec/tshield/fixtures/config/tshield-without-grpc.yml
|
405
447
|
- spec/tshield/fixtures/config/tshield.yml
|
406
448
|
- spec/tshield/fixtures/filters/example_filter.rb
|
407
449
|
- spec/tshield/fixtures/matching/example.json
|
450
|
+
- spec/tshield/fixtures/proto/test_services_pb.rb
|
451
|
+
- spec/tshield/grpc_spec.rb
|
408
452
|
- spec/tshield/options_spec.rb
|
409
453
|
- spec/tshield/request_matching_spec.rb
|
410
454
|
- spec/tshield/request_vcr_spec.rb
|
@@ -435,11 +479,14 @@ summary: Proxy for mocks API responses
|
|
435
479
|
test_files:
|
436
480
|
- spec/spec_helper.rb
|
437
481
|
- spec/tshield/request_matching_spec.rb
|
482
|
+
- spec/tshield/grpc_spec.rb
|
438
483
|
- spec/tshield/configuration_spec.rb
|
439
484
|
- spec/tshield/request_vcr_spec.rb
|
440
485
|
- spec/tshield/controllers/requests_spec.rb
|
441
486
|
- spec/tshield/options_spec.rb
|
442
487
|
- spec/tshield/after_filter_spec.rb
|
443
488
|
- spec/tshield/fixtures/matching/example.json
|
489
|
+
- spec/tshield/fixtures/proto/test_services_pb.rb
|
444
490
|
- spec/tshield/fixtures/filters/example_filter.rb
|
445
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
|