healthcheck_endpoint 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +213 -0
  3. data/.circleci/gemspecs/compatible +25 -0
  4. data/.circleci/gemspecs/latest +33 -0
  5. data/.circleci/linter_configs/.bundler-audit.yml +4 -0
  6. data/.circleci/linter_configs/.commitspell.yml +33 -0
  7. data/.circleci/linter_configs/.cspell.yml +32 -0
  8. data/.circleci/linter_configs/.fasterer.yml +4 -0
  9. data/.circleci/linter_configs/.lefthook.yml +44 -0
  10. data/.circleci/linter_configs/.markdownlint.yml +9 -0
  11. data/.circleci/linter_configs/.rubocop.yml +143 -0
  12. data/.circleci/linter_configs/.yamllint.yml +7 -0
  13. data/.circleci/scripts/changeloglint.sh +22 -0
  14. data/.circleci/scripts/commitspell.sh +22 -0
  15. data/.circleci/scripts/release.sh +69 -0
  16. data/.circleci/scripts/set_publisher_credentials.sh +12 -0
  17. data/.codeclimate.yml +17 -0
  18. data/.github/BRANCH_NAMING_CONVENTION.md +36 -0
  19. data/.github/DEVELOPMENT_ENVIRONMENT_GUIDE.md +26 -0
  20. data/.github/FUNDING.yml +3 -0
  21. data/.github/ISSUE_TEMPLATE/bug_report.md +28 -0
  22. data/.github/ISSUE_TEMPLATE/feature_request.md +27 -0
  23. data/.github/ISSUE_TEMPLATE/issue_report.md +32 -0
  24. data/.github/ISSUE_TEMPLATE/question.md +22 -0
  25. data/.github/PULL_REQUEST_TEMPLATE.md +49 -0
  26. data/.gitignore +11 -0
  27. data/.reek.yml +39 -0
  28. data/.rspec +2 -0
  29. data/.ruby-gemset +1 -0
  30. data/.ruby-version +1 -0
  31. data/CHANGELOG.md +52 -0
  32. data/CODE_OF_CONDUCT.md +74 -0
  33. data/CONTRIBUTING.md +48 -0
  34. data/Gemfile +5 -0
  35. data/LICENSE.txt +21 -0
  36. data/README.md +256 -0
  37. data/Rakefile +8 -0
  38. data/bin/console +15 -0
  39. data/bin/setup +8 -0
  40. data/healthcheck_endpoint.gemspec +28 -0
  41. data/lib/healthcheck_endpoint/configuration.rb +139 -0
  42. data/lib/healthcheck_endpoint/core.rb +20 -0
  43. data/lib/healthcheck_endpoint/error/configuration/argument_type.rb +13 -0
  44. data/lib/healthcheck_endpoint/error/configuration/enpoint_pattern.rb +13 -0
  45. data/lib/healthcheck_endpoint/error/configuration/http_status_failure.rb +13 -0
  46. data/lib/healthcheck_endpoint/error/configuration/http_status_success.rb +13 -0
  47. data/lib/healthcheck_endpoint/error/configuration/not_callable_service.rb +13 -0
  48. data/lib/healthcheck_endpoint/error/configuration/not_configured.rb +13 -0
  49. data/lib/healthcheck_endpoint/error/configuration/unknown_service.rb +13 -0
  50. data/lib/healthcheck_endpoint/rack_middleware.rb +25 -0
  51. data/lib/healthcheck_endpoint/resolver.rb +82 -0
  52. data/lib/healthcheck_endpoint/version.rb +5 -0
  53. data/lib/healthcheck_endpoint.rb +25 -0
  54. metadata +171 -0
data/README.md ADDED
@@ -0,0 +1,256 @@
1
+ # ![HealthcheckEndpoint - Simple configurable application healthcheck rack middleware](https://repository-images.githubusercontent.com/769335579/012755ac-8757-43b1-8191-7cac167396fa)
2
+
3
+ [![Maintainability](https://api.codeclimate.com/v1/badges/e1da0941cf2234c1d110/maintainability)](https://codeclimate.com/github/obstools/healthcheck-endpoint/maintainability)
4
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/e1da0941cf2234c1d110/test_coverage)](https://codeclimate.com/github/obstools/healthcheck-endpoint/test_coverage)
5
+ [![CircleCI](https://circleci.com/gh/obstools/healthcheck-endpoint/tree/master.svg?style=svg)](https://circleci.com/gh/obstools/healthcheck-endpoint/tree/master)
6
+ [![Gem Version](https://badge.fury.io/rb/healthcheck_endpoint.svg)](https://badge.fury.io/rb/healthcheck_endpoint)
7
+ [![Downloads](https://img.shields.io/gem/dt/healthcheck_endpoint.svg?colorA=004d99&colorB=0073e6)](https://rubygems.org/gems/healthcheck_endpoint)
8
+ [![GitHub](https://img.shields.io/github/license/obstools/healthcheck-endpoint)](LICENSE.txt)
9
+ [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v1.4%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md)
10
+
11
+ Simple configurable application healthcheck rack middleware. This middleware allows you to embed healthcheck endpoints into your rack based application to perform healthcheck probes. Make your application compatible with [Docker](https://docs.docker.com/reference/dockerfile/#healthcheck)/[Kubernetes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-a-liveness-http-request) healthchecks in a seconds.
12
+
13
+ ## Table of Contents
14
+
15
+ - [Features](#features)
16
+ - [Requirements](#requirements)
17
+ - [Installation](#installation)
18
+ - [Configuring](#configuring)
19
+ - [Usage](#usage)
20
+ - [Integration](#integration)
21
+ - [Rack](#rack)
22
+ - [Roda](#roda)
23
+ - [Hanami](#hanami)
24
+ - [Rails](#rails)
25
+ - [Healthcheck endpoint response](#healthcheck-endpoint-response)
26
+ - [Contributing](#contributing)
27
+ - [License](#license)
28
+ - [Code of Conduct](#code-of-conduct)
29
+ - [Credits](#credits)
30
+ - [Versioning](#versioning)
31
+ - [Changelog](CHANGELOG.md)
32
+
33
+ ## Features
34
+
35
+ - Built-in default configuration
36
+ - Configurable services for startup/liveness/readiness probes
37
+ - Configurable root endpoints namespace
38
+ - Configurable startup/liveness/readiness probes endpoints
39
+ - Configurable successful/failure response statuses
40
+
41
+ ## Requirements
42
+
43
+ Ruby MRI 2.5.0+
44
+
45
+ ## Installation
46
+
47
+ Add this line to your application's Gemfile:
48
+
49
+ ```ruby
50
+ gem 'healthcheck_endpoint'
51
+ ```
52
+
53
+ And then execute:
54
+
55
+ ```bash
56
+ bundle
57
+ ```
58
+
59
+ Or install it yourself as:
60
+
61
+ ```bash
62
+ gem install healthcheck_endpoint
63
+ ```
64
+
65
+ ## Configuring
66
+
67
+ To start working with this gem, you must configure it first as in the example below:
68
+
69
+ ```ruby
70
+ # config/initializers/healthcheck_endpoint.rb
71
+
72
+ require 'healthcheck_endpoint'
73
+
74
+ HealthcheckEndpoint.configure do |config|
75
+ # Optional parameter. The list of services that can be triggered
76
+ # during running probes. Each value of this hash should be callable
77
+ # and return boolean.
78
+ # It is equal to empty hash by default.
79
+ config.services = {
80
+ postgres: -> { true },
81
+ redis: -> { true },
82
+ rabbit: -> { false }
83
+ }
84
+
85
+ # Optional parameter. The list of services that will be checked
86
+ # during running startup probe. As array items must be used an
87
+ # existing keys, defined in config.services.
88
+ # It is equal to empty array by default.
89
+ config.services_startup = %i[postgres]
90
+
91
+ # Optional parameter. The list of services that will be checked
92
+ # during running liveness probe. As array items must be used an
93
+ # existing keys, defined in config.services.
94
+ # It is equal to empty array by default.
95
+ config.services_liveness = %i[redis]
96
+
97
+ # Optional parameter. The list of services that will be checked
98
+ # during running liveness probe. As array items must be used an
99
+ # existing keys, defined in config.services.
100
+ # It is equal to empty array by default.
101
+ config.services_readiness = %i[postgres redis rabbit]
102
+
103
+ # Optional parameter. The name of middleware's root
104
+ # endpoints namespace. Use '/' if you want to use root
105
+ # namespace. It is equal to /healthcheck by default.
106
+ config.endpoints_namespace = '/application-healthcheck'
107
+
108
+ # Optional parameter. The startup endpoint path.
109
+ # It is equal to /startup by default.
110
+ config.endpoint_startup = '/startup-probe'
111
+
112
+ # Optional parameter. The liveness endpoint path.
113
+ # It is equal to /liveness by default.
114
+ config.endpoint_liveness = '/liveness-probe'
115
+
116
+ # Optional parameter. The readiness endpoint path.
117
+ # It is equal to /readiness by default.
118
+ config.endpoint_readiness = '/readiness-probe'
119
+
120
+ # Optional parameter. The HTTP successful status
121
+ # for startup probe. It is equal to 200 by default.
122
+ config.endpoint_startup_status_success = 201
123
+
124
+ # Optional parameter. The HTTP successful status
125
+ # for liveness probe. It is equal to 200 by default.
126
+ config.endpoint_liveness_status_success = 202
127
+
128
+ # Optional parameter. The HTTP successful status
129
+ # for readiness probe. It is equal to 200 by default.
130
+ config.endpoint_readiness_status_success = 203
131
+
132
+ # Optional parameter. The HTTP failure status
133
+ # for startup probe. It is equal to 500 by default.
134
+ config.endpoint_startup_status_failure = 501
135
+
136
+ # Optional parameter. The HTTP failure status
137
+ # for liveness probe. It is equal to 500 by default.
138
+ config.endpoint_liveness_status_failure = 502
139
+
140
+ # Optional parameter. The HTTP failure status
141
+ # for readiness probe. It is equal to 500 by default.
142
+ config.endpoint_readiness_status_failure = 503
143
+ end
144
+ ```
145
+
146
+ ## Usage
147
+
148
+ ### Integration
149
+
150
+ Please note, to start using this middleware you should configure `HealthcheckEndpoint` before and then you should to add `HealthcheckEndpoint::RackMiddleware` on the top of middlewares list.
151
+
152
+ #### Rack
153
+
154
+ ```ruby
155
+ require 'healthcheck_endpoint'
156
+
157
+ # Configuring HealthcheckEndpoint with default settings
158
+ HealthcheckEndpoint.configure
159
+
160
+ Rack::Builder.app do
161
+ use HealthcheckEndpoint::RackMiddleware
162
+ run YourApplication
163
+ end
164
+ ```
165
+
166
+ #### Roda
167
+
168
+ ```ruby
169
+ require 'healthcheck_endpoint'
170
+
171
+ # Configuring HealthcheckEndpoint with default settings
172
+ HealthcheckEndpoint.configure
173
+
174
+ class YourApplication < Roda
175
+ use HealthcheckEndpoint::RackMiddleware
176
+ end
177
+ ```
178
+
179
+ #### Hanami
180
+
181
+ ```ruby
182
+ # config/initializers/healthcheck_endpoint.rb
183
+
184
+ require 'healthcheck_endpoint'
185
+
186
+ # Configuring HealthcheckEndpoint with default settings
187
+ HealthcheckEndpoint.configure
188
+ ```
189
+
190
+ ```ruby
191
+ # config/environment.rb
192
+
193
+ Hanami.configure do
194
+ middleware.use HealthcheckEndpoint::RackMiddleware
195
+ end
196
+ ```
197
+
198
+ #### Rails
199
+
200
+ For Rails 7+, you can use the built-in healthcheck feature provided by Rails itself. See the [official Rails documentation on healthchecks](https://edgeapi.rubyonrails.org/classes/Rails/HealthController.html) for details. However, if you need more advanced healthcheck functionality or want to maintain consistency across different frameworks, you can still use this gem with Rails as follows:
201
+
202
+ ```ruby
203
+ # config/initializers/healthcheck_endpoint.rb
204
+
205
+ require 'healthcheck_endpoint'
206
+
207
+ # Configuring HealthcheckEndpoint with default settings
208
+ HealthcheckEndpoint.configure
209
+ ```
210
+
211
+ ```ruby
212
+ # config/application.rb
213
+
214
+ class Application < Rails::Application
215
+ config.middleware.use HealthcheckEndpoint::RackMiddleware
216
+ end
217
+ ```
218
+
219
+ ### Healthcheck endpoint response
220
+
221
+ Each healthcheck endpoint returns proper HTTP status and body. Determining the response status is based on the general result of service checks (when all are successful the status is successful, at least one failure - the status is failure). The response body represented as JSON document with a structure like in the example below:
222
+
223
+ ```json
224
+ {
225
+ "data": {
226
+ "id": "a09efd18-e09f-4207-9a43-b4bf89f76b47",
227
+ "type": "application-startup-healthcheck",
228
+ "attributes": {
229
+ "postgres": true,
230
+ "redis": true,
231
+ "rabbit": true
232
+ }
233
+ }
234
+ }
235
+ ```
236
+
237
+ ## Contributing
238
+
239
+ Bug reports and pull requests are welcome on GitHub at <https://github.com/obstools/healthcheck-endpoint>. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. Please check the [open tickets](https://github.com/obstools/healthcheck-endpoint/issues). Be sure to follow Contributor Code of Conduct below and our [Contributing Guidelines](CONTRIBUTING.md).
240
+
241
+ ## License
242
+
243
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
244
+
245
+ ## Code of Conduct
246
+
247
+ Everyone interacting in the `healthcheck_endpoint` project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](CODE_OF_CONDUCT.md).
248
+
249
+ ## Credits
250
+
251
+ - [The Contributors](https://github.com/obstools/healthcheck-endpoint/graphs/contributors) for code and awesome suggestions
252
+ - [The Stargazers](https://github.com/obstools/healthcheck-endpoint/stargazers) for showing their support
253
+
254
+ ## Versioning
255
+
256
+ `healthcheck_endpoint` uses [Semantic Versioning 2.0.0](https://semver.org)
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'healthcheck_endpoint'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/healthcheck_endpoint/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'healthcheck_endpoint'
7
+ spec.version = HealthcheckEndpoint::VERSION
8
+ spec.authors = ['Vladislav Trotsenko']
9
+ spec.email = %w[admin@bestweb.com.ua]
10
+ spec.summary = %(Simple configurable application healthcheck rack middleware)
11
+ spec.description = %(Simple configurable application healthcheck rack middleware.)
12
+ spec.homepage = 'https://github.com/obstools/healthcheck-endpoint'
13
+ spec.license = 'MIT'
14
+
15
+ current_ruby_version = ::Gem::Version.new(::RUBY_VERSION)
16
+ ffaker_version = current_ruby_version >= ::Gem::Version.new('3.0.0') ? '~> 2.23' : '~> 2.21'
17
+
18
+ spec.required_ruby_version = '>= 2.5.0'
19
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
+ spec.require_paths = %w[lib]
21
+
22
+ spec.add_runtime_dependency 'rack', '>= 2.0.1'
23
+
24
+ spec.add_development_dependency 'ffaker', ffaker_version
25
+ spec.add_development_dependency 'json_matchers', '~> 0.11.1'
26
+ spec.add_development_dependency 'rake', '~> 13.2', '>= 13.2.1'
27
+ spec.add_development_dependency 'rspec', '~> 3.13'
28
+ end
@@ -0,0 +1,139 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HealthcheckEndpoint
4
+ class Configuration
5
+ ATTRIBUTES = %i[
6
+ services
7
+ services_startup
8
+ services_liveness
9
+ services_readiness
10
+ endpoints_namespace
11
+ endpoint_startup
12
+ endpoint_liveness
13
+ endpoint_readiness
14
+ endpoint_startup_status_success
15
+ endpoint_liveness_status_success
16
+ endpoint_readiness_status_success
17
+ endpoint_startup_status_failure
18
+ endpoint_liveness_status_failure
19
+ endpoint_readiness_status_failure
20
+ ].freeze
21
+ ENDPOINTS_NAMESPACE = '/healthcheck'
22
+ ENDPOINT_STARTUP = '/startup'
23
+ ENDPOINT_LIVENESS = '/liveness'
24
+ ENDPOINT_READINESS = '/readiness'
25
+ DEFAULT_HTTP_STATUS_SUCCESS = 200
26
+ DEFAULT_HTTP_STATUS_FAILURE = 500
27
+ AVILABLE_HTTP_STATUSES_SUCCESS = (DEFAULT_HTTP_STATUS_SUCCESS..226).freeze
28
+ AVILABLE_HTTP_STATUSES_FAILURE = (DEFAULT_HTTP_STATUS_FAILURE..511).freeze
29
+
30
+ Settings = ::Struct.new(*HealthcheckEndpoint::Configuration::ATTRIBUTES, keyword_init: true) do
31
+ def update(&block)
32
+ return self unless block
33
+
34
+ tap(&block)
35
+ end
36
+ end
37
+
38
+ attr_reader(*HealthcheckEndpoint::Configuration::ATTRIBUTES)
39
+
40
+ def initialize(&block)
41
+ configuration_settings = build_configuration_settings(&block)
42
+ HealthcheckEndpoint::Configuration::ATTRIBUTES.each do |attribute|
43
+ public_send(:"#{attribute}=", configuration_settings.public_send(attribute))
44
+ end
45
+ end
46
+
47
+ HealthcheckEndpoint::Configuration::ATTRIBUTES.each do |attribute|
48
+ define_method(:"#{attribute}=") do |argument|
49
+ validate_attribute(__method__, attribute, argument)
50
+ instance_variable_set(:"@#{attribute}", argument)
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def build_configuration_settings(&block) # rubocop:disable Metrics/MethodLength
57
+ HealthcheckEndpoint::Configuration::Settings.new(
58
+ services: {},
59
+ services_startup: [],
60
+ services_liveness: [],
61
+ services_readiness: [],
62
+ endpoints_namespace: HealthcheckEndpoint::Configuration::ENDPOINTS_NAMESPACE,
63
+ endpoint_startup: HealthcheckEndpoint::Configuration::ENDPOINT_STARTUP,
64
+ endpoint_liveness: HealthcheckEndpoint::Configuration::ENDPOINT_LIVENESS,
65
+ endpoint_readiness: HealthcheckEndpoint::Configuration::ENDPOINT_READINESS,
66
+ endpoint_startup_status_success: HealthcheckEndpoint::Configuration::DEFAULT_HTTP_STATUS_SUCCESS,
67
+ endpoint_liveness_status_success: HealthcheckEndpoint::Configuration::DEFAULT_HTTP_STATUS_SUCCESS,
68
+ endpoint_readiness_status_success: HealthcheckEndpoint::Configuration::DEFAULT_HTTP_STATUS_SUCCESS,
69
+ endpoint_startup_status_failure: HealthcheckEndpoint::Configuration::DEFAULT_HTTP_STATUS_FAILURE,
70
+ endpoint_liveness_status_failure: HealthcheckEndpoint::Configuration::DEFAULT_HTTP_STATUS_FAILURE,
71
+ endpoint_readiness_status_failure: HealthcheckEndpoint::Configuration::DEFAULT_HTTP_STATUS_FAILURE
72
+ ).update(&block)
73
+ end
74
+
75
+ def validate_attribute(method, attribute, value) # rubocop:disable Metrics/AbcSize
76
+ raise_unless(HealthcheckEndpoint::Error::Configuration::ArgumentType, method, *validator_argument_type(attribute, value))
77
+ case attribute
78
+ when HealthcheckEndpoint::Configuration::ATTRIBUTES[0]
79
+ raise_unless(HealthcheckEndpoint::Error::Configuration::NotCallableService, method, *validator_services_callable(value))
80
+ when *HealthcheckEndpoint::Configuration::ATTRIBUTES[1..3]
81
+ raise_unless(HealthcheckEndpoint::Error::Configuration::UnknownService, method, *validator_services_conformity(value))
82
+ when *HealthcheckEndpoint::Configuration::ATTRIBUTES[4..7]
83
+ raise_unless(HealthcheckEndpoint::Error::Configuration::EnpointPattern, method, *validator_endpoint(value))
84
+ when *HealthcheckEndpoint::Configuration::ATTRIBUTES[8..10]
85
+ raise_unless(HealthcheckEndpoint::Error::Configuration::HttpStatusSuccess, method, *validator_http_status_success(value))
86
+ when *HealthcheckEndpoint::Configuration::ATTRIBUTES[11..13]
87
+ raise_unless(HealthcheckEndpoint::Error::Configuration::HttpStatusFailure, method, *validator_http_status_failure(value))
88
+ end
89
+ end
90
+
91
+ def validator_argument_type(method_name, argument)
92
+ [
93
+ argument,
94
+ argument.is_a?(
95
+ case method_name
96
+ when :services then ::Hash
97
+ when *HealthcheckEndpoint::Configuration::ATTRIBUTES[1..3] then ::Array
98
+ when *HealthcheckEndpoint::Configuration::ATTRIBUTES[4..7] then ::String
99
+ when *HealthcheckEndpoint::Configuration::ATTRIBUTES[8..13] then ::Integer
100
+ end
101
+ )
102
+ ]
103
+ end
104
+
105
+ def validator_endpoint(argument)
106
+ [argument, argument[%r{\A/.*\z}]]
107
+ end
108
+
109
+ def validator_http_status_success(argument)
110
+ [argument, HealthcheckEndpoint::Configuration::AVILABLE_HTTP_STATUSES_SUCCESS.include?(argument)]
111
+ end
112
+
113
+ def validator_http_status_failure(argument)
114
+ [argument, HealthcheckEndpoint::Configuration::AVILABLE_HTTP_STATUSES_FAILURE.include?(argument)]
115
+ end
116
+
117
+ def validator_services_callable(services_to_check, target_service = nil)
118
+ result = services_to_check.all? do |service_name, service_context|
119
+ target_service = service_name
120
+ service_context.respond_to?(:call)
121
+ end
122
+
123
+ [target_service, result]
124
+ end
125
+
126
+ def validator_services_conformity(services_to_check, target_service = nil)
127
+ result = services_to_check.all? do |service_name|
128
+ target_service = service_name
129
+ services.key?(service_name)
130
+ end
131
+
132
+ [target_service, result]
133
+ end
134
+
135
+ def raise_unless(exception_class, argument_name, argument_context, condition)
136
+ raise exception_class.new(argument_context, argument_name) unless condition
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HealthcheckEndpoint
4
+ module Error
5
+ module Configuration
6
+ require_relative 'error/configuration/argument_type'
7
+ require_relative 'error/configuration/unknown_service'
8
+ require_relative 'error/configuration/not_callable_service'
9
+ require_relative 'error/configuration/enpoint_pattern'
10
+ require_relative 'error/configuration/http_status_success'
11
+ require_relative 'error/configuration/http_status_failure'
12
+ require_relative 'error/configuration/not_configured'
13
+ end
14
+ end
15
+
16
+ require_relative 'version'
17
+ require_relative 'configuration'
18
+ require_relative 'resolver'
19
+ require_relative 'rack_middleware'
20
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HealthcheckEndpoint
4
+ module Error
5
+ module Configuration
6
+ ArgumentType = ::Class.new(::ArgumentError) do
7
+ def initialize(arg_value, arg_name)
8
+ super("#{arg_value} is not a valid #{arg_name}")
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HealthcheckEndpoint
4
+ module Error
5
+ module Configuration
6
+ EnpointPattern = ::Class.new(::ArgumentError) do
7
+ def initialize(arg_value, arg_name)
8
+ super("#{arg_value} does not match a valid enpoint pattern for #{arg_name}")
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HealthcheckEndpoint
4
+ module Error
5
+ module Configuration
6
+ HttpStatusFailure = ::Class.new(::ArgumentError) do
7
+ def initialize(arg_value, arg_name)
8
+ super("Status #{arg_value} is wrong HTTP failure status for #{arg_name}. It should be in the range 500-511")
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HealthcheckEndpoint
4
+ module Error
5
+ module Configuration
6
+ HttpStatusSuccess = ::Class.new(::ArgumentError) do
7
+ def initialize(arg_value, arg_name)
8
+ super("Status #{arg_value} is wrong HTTP successful status for #{arg_name}. It should be in the range 200-226")
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HealthcheckEndpoint
4
+ module Error
5
+ module Configuration
6
+ NotCallableService = ::Class.new(::ArgumentError) do
7
+ def initialize(service_name, services_setter)
8
+ super("Service #{service_name} is not callable. All values for #{services_setter} should be a callable objects")
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HealthcheckEndpoint
4
+ module Error
5
+ module Configuration
6
+ NotConfigured = ::Class.new(::RuntimeError) do
7
+ def initialize
8
+ super('The configuration is empty. Please use HealthcheckEndpoint.configure before')
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HealthcheckEndpoint
4
+ module Error
5
+ module Configuration
6
+ UnknownService = ::Class.new(::ArgumentError) do
7
+ def initialize(service_name, services_setter)
8
+ super("Unknown #{service_name} service name for #{services_setter}. You should define it in config.services firstly")
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HealthcheckEndpoint
4
+ class RackMiddleware
5
+ def initialize(
6
+ app,
7
+ resolver = HealthcheckEndpoint::Resolver,
8
+ counfigured = !!HealthcheckEndpoint.configuration
9
+ )
10
+ @app = app
11
+ @resolver = resolver
12
+ @counfigured = counfigured
13
+ end
14
+
15
+ def call(env)
16
+ raise HealthcheckEndpoint::Error::Configuration::NotConfigured unless counfigured
17
+
18
+ resolver.call(env) || app.call(env)
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :app, :resolver, :counfigured
24
+ end
25
+ end