boechat 0.0.1 → 0.1.0.pre.RC1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 666155b02a02293152a1fe3ab9f25517f47c4795224d33b0e1124d2a31adb219
4
- data.tar.gz: 630e27e95ce5160648c4d4a31efa9580146ec89a9d55770b40ab2da85f85d623
3
+ metadata.gz: 60b8e03cd088bd8ac98206d892f0c9b4ade7809caaf2d7cc718f618ac6b332d8
4
+ data.tar.gz: dbe45040d76298c1583178cdb60b077b194254d8c433e9bd5ebb5595f7016f12
5
5
  SHA512:
6
- metadata.gz: b6637c22a3f0b67c59af54032c45c120ad972179a3298b996584d12c609ddd6a2898e2a1a887e693c3531076423a196a3b61777ad220ead863bae7554814b70f
7
- data.tar.gz: 1e79404dfd944972e195215b459ae3c41e4369a8b9b930f1210dcc1740e88f250878b750d2a04a47647c627c1464027c357a693b86f23c90f6c0fe04c2912c6d
6
+ metadata.gz: a41626ca7550fa8a479f4be057e5d5c696424ba808d7c8b2cd2719c09af6ba92674706d0ba5532da46f57e8014f9e026ffcd7894f5b4ed8a5a7bc4ff91fb0346
7
+ data.tar.gz: 1798b02cc56eff1c2824a6b0728b55d3c734c37ac066a34ab71292d71b7128c5ff3d560e8cd6b1b0c77e840a69cd53eef0140f3de58574b312fb4f5f2717b7cd
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *.gem
2
+ .yardoc
3
+ doc/**/*
data/Gemfile.lock CHANGED
@@ -3,8 +3,8 @@ PATH
3
3
  specs:
4
4
  boechat (0.0.1)
5
5
  dry-validation (~> 0.11.1)
6
- oj (~> 3.5.0)
7
- typhoeus (~> 1.3.0)
6
+ oj (~> 3.5)
7
+ typhoeus (~> 1.3)
8
8
 
9
9
  GEM
10
10
  remote: https://rubygems.org/
@@ -43,7 +43,6 @@ GEM
43
43
  dry-equalizer (~> 0.2)
44
44
  dry-logic (~> 0.4, >= 0.4.0)
45
45
  dry-types (~> 0.12.0)
46
- dry-validation-matchers (0.4.0)
47
46
  ethon (0.11.0)
48
47
  ffi (>= 1.3.0)
49
48
  ffi (1.9.23)
@@ -89,6 +88,7 @@ GEM
89
88
  typhoeus (1.3.0)
90
89
  ethon (>= 0.9.0)
91
90
  unicode-display_width (1.3.2)
91
+ yard (0.9.12)
92
92
 
93
93
  PLATFORMS
94
94
  ruby
@@ -98,13 +98,13 @@ DEPENDENCIES
98
98
  bundler (~> 1.16)
99
99
  codeclimate-test-reporter
100
100
  dry-validation
101
- dry-validation-matchers (~> 0.4.0)
102
101
  pry
103
102
  rake (~> 10.0)
104
103
  rspec (~> 3.0)
105
104
  rubocop
106
105
  simplecov
107
106
  typhoeus
107
+ yard (~> 0.9)
108
108
 
109
109
  BUNDLED WITH
110
110
  1.16.1
data/TODO.md CHANGED
@@ -2,5 +2,7 @@
2
2
 
3
3
  + [DONE] Create Result class to store the result after call each request
4
4
  + [DONE] Define boechat.yml expected format and adapt config classes
5
+ + [DONE] Fix call for multiple services, that don't run the requesters when using Typhoeus Hydra...
6
+ + [WIP ] Refactor version validation
5
7
  + [WIP ] Write tests for Core classes
6
- + [ ] Fix call for multiple services, that have error with Typhoeus Hydra...
8
+ + [WIP ] Document the project with YARD
data/bin/boechat ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/boechat_core'
5
+ require_relative '../lib/boechat/core/command_runner'
6
+
7
+ aliases = { 'v' => 'verify', 'c' => 'console' }
8
+
9
+ command = ARGV.first
10
+ Boechat::Core::CommandRunner.call(aliases[command] || command)
data/boechat.gemspec CHANGED
@@ -4,6 +4,7 @@ lib = File.expand_path('lib', __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require 'boechat/internal/version'
6
6
 
7
+ # rubocop:disable Metrics/BlockLength
7
8
  Gem::Specification.new do |spec|
8
9
  spec.name = 'boechat'
9
10
  spec.version = Boechat::Internal::VERSION
@@ -26,10 +27,11 @@ Gem::Specification.new do |spec|
26
27
  # rubocop:enable Style/GuardClause
27
28
 
28
29
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|bin)/}) }
29
- spec.bindir = 'exe'
30
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
+ spec.bindir = 'bin'
31
+ spec.executables = ['boechat']
31
32
  spec.require_paths = ['lib']
32
33
  spec.required_ruby_version = '>= 2.5.0'
34
+ spec.metadata['yard.run'] = 'yri'
33
35
 
34
36
  # Dependencies that your gem needs at runtime
35
37
  spec.add_runtime_dependency 'dry-validation', '~> 0.11.1'
@@ -40,4 +42,6 @@ Gem::Specification.new do |spec|
40
42
  spec.add_development_dependency 'bundler', '~> 1.16'
41
43
  spec.add_development_dependency 'rake', '~> 10.0'
42
44
  spec.add_development_dependency 'rspec', '~> 3.0'
45
+ spec.add_development_dependency 'yard', '~> 0.9'
43
46
  end
47
+ # rubocop:enable Metrics/BlockLength
data/config/boechat.yml CHANGED
@@ -3,8 +3,8 @@ services:
3
3
  - name: empresas
4
4
  base_url: http://empresasservice.ad.vagastec.com.br
5
5
  status_endpoint: status
6
- http_verb: get
6
+ version: '>= 1.15.0'
7
7
  - name: processos
8
8
  base_url: http://qa-processosseletivosservice.ad.vagastec.com.br
9
9
  status_endpoint: healthcheck
10
- http_verb: get
10
+ version: '> 1.14.0'
data/lib/boechat/core.rb CHANGED
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'boechat/internal/version'
4
+ require 'boechat/core/service/verifier'
5
+ require 'pry'
4
6
 
5
7
  # :nodoc:
6
- module MyGem
8
+ module Boechat
7
9
  # :nodoc:
8
10
  module Core
9
11
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './service/verifier'
4
+
5
+ module Boechat
6
+ module Core
7
+ # Class responsible for run the commands passed to the boechat binary
8
+ class CommandRunner
9
+ def self.call(command)
10
+ if command == 'verify'
11
+ puts '-' * 80
12
+ puts 'Version Verification Result'
13
+ puts Boechat::Core::Service::Verifier.new.call.result
14
+ puts '-' * 80
15
+ else # runs help for help itself and any other not recognized command
16
+ puts "\nUSAGE:"
17
+ puts ' boechat [COMMAND]'
18
+ puts "\nCOMMANDS:"
19
+ puts ' h, help # Shows help instructions'
20
+ puts " v, verify # Verifies versions of all services contained in boachat.yml file\n"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -12,8 +12,8 @@ module Boechat
12
12
  schema do
13
13
  required('name').filled(:str?)
14
14
  required('base_url').filled(:str?)
15
+ required('version').filled(:str?)
15
16
  optional('status_endpoint').filled(:str?)
16
- optional('http_verb').filled(included_in?: %w[get post])
17
17
  end
18
18
  end
19
19
  end
@@ -1,34 +1,39 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'typhoeus'
4
+
3
5
  module Boechat
4
6
  module Core
5
7
  module Service
6
- # Class to save all user request objects to execute them one at a time or all in parallel
8
+ # Class to save all user Requester objects to execute them one at a time or all in parallel
7
9
  class RequestList
8
- attr_reader :requests
10
+ attr_reader :requesters
9
11
 
10
- def initialize(requests = {})
11
- @requests = requests
12
+ def initialize(requesters = {})
13
+ @requesters = requesters
12
14
  end
13
15
 
14
- def call(request_identifier = nil)
15
- if request_identifier.nil?
16
+ # @todo Add support for multiple HTTP Clients with parallel requests
17
+ # Initially only Typhoeus HTTP client is supported for make multiple API calls in parallel.
18
+ # It will be good to support other clients, as the user wants to configure
19
+ def call(requester_identifier = nil)
20
+ if requester_identifier.nil?
16
21
  hydra = Typhoeus::Hydra.hydra
17
- requests.each_pair { |_key, request| hydra.queue(request.call) }
22
+ requesters.each_pair { |_key, requester| hydra.queue(requester.request) }
18
23
  hydra.run
19
- elsif requests.key?(request_identifier)
20
- requests[request_identifier].call
24
+ elsif requesters.key?(requester_identifier)
25
+ requesters[requester_identifier].call
21
26
  end
22
27
 
23
28
  self
24
29
  end
25
30
 
26
31
  def []=(key, requester)
27
- requests[key] = requester
32
+ requesters[key] = requester
28
33
  end
29
34
 
30
35
  def [](key)
31
- requests[key]
36
+ requesters[key]
32
37
  end
33
38
  end
34
39
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../internal/string_extensions'
4
+ require_relative 'result'
5
+ require_relative 'response_handler'
6
+ require 'typhoeus'
7
+
8
+ module Boechat
9
+ module Core
10
+ # Module to group all classes related to the Request/Response/Validation cycle
11
+ module Service
12
+ using StringExtensions
13
+
14
+ # Class responsible for make the request to one service
15
+ class Requester
16
+ attr_reader :request, :response, :result, :service_uri, :parameters, :body, :headers
17
+ BASIC_HEADER = { 'User-Agent' => 'Boechat - API Version Verifier' }.freeze
18
+
19
+ def initialize(service_uri, parameters: nil, body: nil, headers: nil)
20
+ @service_uri = service_uri
21
+ @parameters = parameters
22
+ @body = body
23
+ @headers = headers
24
+ @request = Typhoeus::Request.new(@service_uri, method: :get, params: @parameters,
25
+ body: @body, headers: http_header)
26
+ @request.on_complete do |res|
27
+ @response = res
28
+ @result = Result.new(ResponseHandler.call(res))
29
+ end
30
+ end
31
+
32
+ def call
33
+ @request.run
34
+ end
35
+
36
+ private
37
+
38
+ def http_header
39
+ return BASIC_HEADER.merge(@headers) if @headers
40
+ BASIC_HEADER
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'oj'
4
+ require 'json'
5
+ require_relative '../../internal/string_extensions'
6
+
7
+ module Boechat
8
+ module Core
9
+ # Module to group all classes related to the Request/Response/Validation cycle
10
+ module Service
11
+ using StringExtensions
12
+
13
+ # Class responsible for handle the response after Request has been called
14
+ class ResponseHandler
15
+ HTTP_UNPROCESSABLE_ENTITY = 422
16
+
17
+ class << self
18
+ def call(response)
19
+ raise ArgumentError, 'Argument must respond to :body and :code' unless valid_response(response)
20
+ body = response.body
21
+
22
+ return response_error(response) if body.empty?
23
+ return response_invalid_format unless body.valid_json?
24
+ Oj.load(body, symbol_keys: true).merge(status: response.code)
25
+ end
26
+
27
+ private
28
+
29
+ def valid_response(response)
30
+ response.respond_to?(:body) && response.respond_to?(:code)
31
+ end
32
+
33
+ def response_error(response)
34
+ code = response.code
35
+
36
+ case code
37
+ when 404
38
+ Oj.load({ error: 'Not Found', status: code }.to_json, symbol_keys: true)
39
+ when 500
40
+ Oj.load({ error: 'Service Internal Error', status: code }.to_json, symbol_keys: true)
41
+ else
42
+ Oj.load({ error: 'Service Unexpected Error', status: code }.to_json, symbol_keys: true)
43
+ end
44
+ end
45
+
46
+ def response_invalid_format
47
+ Oj.load({ error: 'Invalid JSON format', status: HTTP_UNPROCESSABLE_ENTITY }.to_json, symbol_keys: true)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -14,11 +14,14 @@ module Boechat
14
14
  end
15
15
 
16
16
  def success?
17
- @parsed_response && @parsed_response[:status] < 400
17
+ @parsed_response &&
18
+ @parsed_response[:status].positive? &&
19
+ @parsed_response[:status] < 400
18
20
  end
19
21
 
20
22
  def failure?
21
- @parsed_response && @parsed_response[:status] >= 400
23
+ @parsed_response.nil? ||
24
+ (@parsed_response[:status].zero? || @parsed_response[:status] >= 400)
22
25
  end
23
26
  end
24
27
  end
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative './request'
3
+ require_relative './requester'
4
4
  require_relative './request_list'
5
+ require_relative './verifier_result'
5
6
  require_relative '../config/reader'
6
7
  require 'typhoeus'
7
8
  require 'json'
@@ -11,27 +12,37 @@ module Boechat
11
12
  module Service
12
13
  # Class responsible for call the endpoints and return all the results
13
14
  class Verifier
14
- attr_reader :config, :request_list
15
+ attr_reader :config, :request_list, :result
15
16
 
16
17
  def initialize
17
- @config = ConfigReader.new.call.config
18
+ @config = Config::Reader.new.call.config
19
+ @request_list = RequestList.new
18
20
  build_request_list
19
21
  end
20
22
 
21
23
  def call(service = nil)
22
24
  @request_list.call(service)
25
+ @result = VerifierResult.call(self)
26
+
27
+ self
23
28
  end
24
29
 
25
30
  private
26
31
 
27
32
  def build_request_list
28
- @request_list = RequestList.new
33
+ @config['services'].each_with_index do |service, index|
34
+ identifier = service['name'] || index.to_s
35
+ url = build_url(service)
29
36
 
30
- @config['services'].each do |service|
31
- key, value = service.first
32
- @request_list.requests[key] = Request.new(value['url'])
37
+ @request_list.requesters[identifier] = Requester.new(url)
33
38
  end
34
39
  end
40
+
41
+ def build_url(service)
42
+ base_url = service['base_url']
43
+ url = base_url.end_with?('/') ? base_url : "#{base_url}/"
44
+ "#{url}#{service['status_endpoint']}"
45
+ end
35
46
  end
36
47
  end
37
48
  end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './requester'
4
+ require_relative './request_list'
5
+ require_relative '../../internal/errors'
6
+ require 'typhoeus'
7
+ require 'json'
8
+
9
+ module Boechat
10
+ module Core
11
+ module Service
12
+ # Class responsible for call the endpoints and return all the results
13
+ class VerifierResult
14
+ include Internal
15
+
16
+ attr_reader :verifier, :output
17
+
18
+ class << self
19
+ def call(verifier)
20
+ raise BoechatError, "Verifier class expected, given #{verifier.class}." unless verifier.class == Verifier
21
+ @verifier = verifier
22
+ @output = []
23
+
24
+ @verifier.request_list.requesters.each_pair do |key, requester|
25
+ next unless requester.result
26
+ @output << { name: key,
27
+ parsed_response: requester.result.parsed_response,
28
+ valid_version: validate_response_version(key) }
29
+ end
30
+
31
+ @output
32
+ end
33
+
34
+ private
35
+
36
+ def validate_response_version(requester_identifier)
37
+ service_config = get_service_config(requester_identifier)
38
+ current_version = get_service_current_version(requester_identifier)
39
+
40
+ operator, required_version = service_config['version'].split(' ')
41
+
42
+ current_version.send(operator.to_sym, required_version)
43
+ end
44
+
45
+ def get_service_config(requester_identifier)
46
+ services = @verifier.config['services'].select do |service|
47
+ service['name'] == requester_identifier
48
+ end
49
+ services.first
50
+ end
51
+
52
+ def get_service_current_version(requester_identifier)
53
+ @verifier.request_list[requester_identifier].result.parsed_response[:tag_versao]
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -3,7 +3,13 @@
3
3
  module Boechat
4
4
  module Internal
5
5
  # Custom error class
6
+ #
7
+ # @author Danilo Barion Nogueira
8
+ # @since 0.0.1
6
9
  class BoechatError < StandardError
10
+ # Constructor
11
+ #
12
+ # @param message [Object] Error message
7
13
  def initialize(message)
8
14
  super(message.to_s)
9
15
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Boechat
4
4
  module Internal
5
- VERSION = '0.0.1'
5
+ VERSION = '0.1.0-RC1'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: boechat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0.pre.RC1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danilo Barion Nogueira
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-02 00:00:00.000000000 Z
11
+ date: 2018-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-validation
@@ -94,13 +94,29 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: yard
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.9'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.9'
97
111
  description: Verify the version of external APIs that your project depends on!
98
112
  email:
99
113
  - danilo.barion@gmail.com
100
- executables: []
114
+ executables:
115
+ - boechat
101
116
  extensions: []
102
117
  extra_rdoc_files: []
103
118
  files:
119
+ - ".gitignore"
104
120
  - ".rubocop.yml"
105
121
  - ".ruby-version"
106
122
  - CHANGELOG.md
@@ -110,16 +126,20 @@ files:
110
126
  - README.md
111
127
  - Rakefile
112
128
  - TODO.md
129
+ - bin/boechat
113
130
  - boechat.gemspec
114
131
  - config/boechat.yml
115
132
  - lib/boechat/core.rb
133
+ - lib/boechat/core/command_runner.rb
116
134
  - lib/boechat/core/config/reader.rb
117
135
  - lib/boechat/core/config/schema_validator.rb
118
136
  - lib/boechat/core/config/wrapper.rb
119
- - lib/boechat/core/service/request.rb
120
137
  - lib/boechat/core/service/request_list.rb
138
+ - lib/boechat/core/service/requester.rb
139
+ - lib/boechat/core/service/response_handler.rb
121
140
  - lib/boechat/core/service/result.rb
122
141
  - lib/boechat/core/service/verifier.rb
142
+ - lib/boechat/core/service/verifier_result.rb
123
143
  - lib/boechat/internal/constants.rb
124
144
  - lib/boechat/internal/errors.rb
125
145
  - lib/boechat/internal/string_extensions.rb
@@ -130,6 +150,7 @@ licenses:
130
150
  - MIT
131
151
  metadata:
132
152
  allowed_push_host: https://rubygems.org
153
+ yard.run: yri
133
154
  post_install_message:
134
155
  rdoc_options: []
135
156
  require_paths:
@@ -141,9 +162,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
141
162
  version: 2.5.0
142
163
  required_rubygems_version: !ruby/object:Gem::Requirement
143
164
  requirements:
144
- - - ">="
165
+ - - ">"
145
166
  - !ruby/object:Gem::Version
146
- version: '0'
167
+ version: 1.3.1
147
168
  requirements: []
148
169
  rubyforge_project:
149
170
  rubygems_version: 2.7.3
@@ -1,76 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'oj'
4
- require_relative '../../internal/string_extensions'
5
- require_relative 'result'
6
-
7
- module Boechat
8
- module Core
9
- # Module to group all classes related to the Request/Response/Validation cycle
10
- module Service
11
- using StringExtensions
12
-
13
-
14
- # Class responsible for make the request to one service
15
- class Request
16
- attr_reader :request, :response, :result, :service_uri, :verb, :parameters, :body, :headers
17
- HTTP_UNPROCESSABLE_ENTITY = 422
18
- BASIC_HEADER = { 'User-Agent' => 'Boechat - API Version Verifier' }
19
-
20
- def initialize(service_uri, verb: :get, parameters: nil, body: nil, headers: nil)
21
- @service_uri = service_uri
22
- @verb = verb
23
- @parameters = parameters
24
- @body = body
25
- @headers = headers
26
- @request = Typhoeus::Request.new(@service_uri, method: @verb, params: @parameters,
27
- body: @body, headers: http_header)
28
- end
29
-
30
- def call
31
- handle_request
32
- end
33
-
34
- private
35
-
36
- def http_header
37
- return BASIC_HEADER.merge(@headers) if @headers
38
- BASIC_HEADER
39
- end
40
-
41
- def handle_request
42
- @request.on_complete do |res|
43
- @response = res
44
- @result = Result.new(valid_response(res))
45
- end
46
- @request.run
47
- end
48
-
49
- def valid_response(response)
50
- body = response.body
51
-
52
- return response_error(response) if body.empty?
53
- return response_invalid_format unless body.valid_json?
54
- Oj.load(body, symbol_keys: true).merge(status: response.code)
55
- end
56
-
57
- def response_error(response)
58
- code = response.code
59
-
60
- case code
61
- when 404
62
- Oj.load({ error: 'Not Found', code: code }.to_json, symbol_keys: true)
63
- when 500
64
- Oj.load({ error: 'Service Internal Error', code: code }.to_json, symbol_keys: true)
65
- else
66
- Oj.load({ error: 'Service Unexpected Error', code: code }.to_json, symbol_keys: true)
67
- end
68
- end
69
-
70
- def response_invalid_format
71
- Oj.load({ error: 'Invalid JSON format', status: HTTP_UNPROCESSABLE_ENTITY }.to_json)
72
- end
73
- end
74
- end
75
- end
76
- end