macaw_framework 1.3.0 → 1.3.3
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/.rubocop.yml +13 -9
- data/CHANGELOG.md +14 -0
- data/Gemfile +11 -9
- data/README.md +28 -10
- data/Rakefile +6 -6
- data/lib/macaw_framework/aspects/cache_aspect.rb +3 -3
- data/lib/macaw_framework/aspects/logging_aspect.rb +4 -7
- data/lib/macaw_framework/aspects/prometheus_aspect.rb +3 -3
- data/lib/macaw_framework/cache.rb +91 -0
- data/lib/macaw_framework/core/common/server_base.rb +29 -28
- data/lib/macaw_framework/core/thread_server.rb +13 -17
- data/lib/macaw_framework/data_filters/log_data_filter.rb +9 -9
- data/lib/macaw_framework/data_filters/request_data_filtering.rb +26 -24
- data/lib/macaw_framework/data_filters/response_data_filter.rb +3 -3
- data/lib/macaw_framework/errors/endpoint_not_mapped_error.rb +1 -1
- data/lib/macaw_framework/macaw.rb +264 -0
- data/lib/macaw_framework/middlewares/prometheus_middleware.rb +7 -7
- data/lib/macaw_framework/utils/http_status_code.rb +61 -61
- data/lib/macaw_framework/utils/supported_ssl_versions.rb +6 -6
- data/lib/macaw_framework/version.rb +1 -1
- data/lib/macaw_framework.rb +5 -230
- metadata +6 -7
data/lib/macaw_framework.rb
CHANGED
|
@@ -1,233 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
require_relative "macaw_framework/middlewares/memory_invalidation_middleware"
|
|
7
|
-
require_relative "macaw_framework/core/cron_runner"
|
|
8
|
-
require_relative "macaw_framework/core/thread_server"
|
|
9
|
-
require_relative "macaw_framework/version"
|
|
10
|
-
require "prometheus/client"
|
|
11
|
-
require "securerandom"
|
|
12
|
-
require "pathname"
|
|
13
|
-
require "logger"
|
|
14
|
-
require "socket"
|
|
15
|
-
require "json"
|
|
3
|
+
##
|
|
4
|
+
# Main module for all Macaw classes
|
|
5
|
+
module MacawFramework; end
|
|
16
6
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
# Class responsible for creating endpoints and
|
|
20
|
-
# starting the web server.
|
|
21
|
-
class Macaw
|
|
22
|
-
attr_reader :routes, :macaw_log, :config, :jobs, :cached_methods, :secure_header, :session
|
|
23
|
-
attr_accessor :port, :bind, :threads
|
|
24
|
-
|
|
25
|
-
##
|
|
26
|
-
# Initialize Macaw Class
|
|
27
|
-
# @param {Logger} custom_log
|
|
28
|
-
# @param {ThreadServer} server
|
|
29
|
-
# @param {String?} dir
|
|
30
|
-
def initialize(custom_log: Logger.new($stdout), server: ThreadServer, dir: nil)
|
|
31
|
-
apply_options(custom_log)
|
|
32
|
-
create_endpoint_public_files(dir)
|
|
33
|
-
@port ||= 8080
|
|
34
|
-
@bind ||= "localhost"
|
|
35
|
-
@config ||= nil
|
|
36
|
-
@threads ||= 200
|
|
37
|
-
@endpoints_to_cache = []
|
|
38
|
-
@prometheus ||= nil
|
|
39
|
-
@prometheus_middleware ||= nil
|
|
40
|
-
@server_class = server
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
##
|
|
44
|
-
# Creates a GET endpoint associated
|
|
45
|
-
# with the respective path.
|
|
46
|
-
# @param {String} path
|
|
47
|
-
# @param {Proc} block
|
|
48
|
-
# @example
|
|
49
|
-
#
|
|
50
|
-
# macaw = MacawFramework::Macaw.new
|
|
51
|
-
# macaw.get("/hello") do |context|
|
|
52
|
-
# return "Hello World!", 200, { "Content-Type" => "text/plain" }
|
|
53
|
-
# end
|
|
54
|
-
def get(path, cache: [], &block)
|
|
55
|
-
map_new_endpoint("get", cache, path, &block)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
##
|
|
59
|
-
# Creates a POST endpoint associated
|
|
60
|
-
# with the respective path.
|
|
61
|
-
# @param {String} path
|
|
62
|
-
# @param {Boolean} cache
|
|
63
|
-
# @param {Proc} block
|
|
64
|
-
# @example
|
|
65
|
-
#
|
|
66
|
-
# macaw = MacawFramework::Macaw.new
|
|
67
|
-
# macaw.post("/hello") do |context|
|
|
68
|
-
# return "Hello World!", 200, { "Content-Type" => "text/plain" }
|
|
69
|
-
# end
|
|
70
|
-
def post(path, cache: [], &block)
|
|
71
|
-
map_new_endpoint("post", cache, path, &block)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
##
|
|
75
|
-
# Creates a PUT endpoint associated
|
|
76
|
-
# with the respective path.
|
|
77
|
-
# @param {String} path
|
|
78
|
-
# @param {Proc} block
|
|
79
|
-
# @example
|
|
80
|
-
#
|
|
81
|
-
# macaw = MacawFramework::Macaw.new
|
|
82
|
-
# macaw.put("/hello") do |context|
|
|
83
|
-
# return "Hello World!", 200, { "Content-Type" => "text/plain" }
|
|
84
|
-
# end
|
|
85
|
-
def put(path, cache: [], &block)
|
|
86
|
-
map_new_endpoint("put", cache, path, &block)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
##
|
|
90
|
-
# Creates a PATCH endpoint associated
|
|
91
|
-
# with the respective path.
|
|
92
|
-
# @param {String} path
|
|
93
|
-
# @param {Proc} block
|
|
94
|
-
# @example
|
|
95
|
-
#
|
|
96
|
-
# macaw = MacawFramework::Macaw.new
|
|
97
|
-
# macaw.patch("/hello") do |context|
|
|
98
|
-
# return "Hello World!", 200, { "Content-Type" => "text/plain" }
|
|
99
|
-
# end
|
|
100
|
-
def patch(path, cache: [], &block)
|
|
101
|
-
map_new_endpoint("patch", cache, path, &block)
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
##
|
|
105
|
-
# Creates a DELETE endpoint associated
|
|
106
|
-
# with the respective path.
|
|
107
|
-
# @param {String} path
|
|
108
|
-
# @param {Proc} block
|
|
109
|
-
# @example
|
|
110
|
-
#
|
|
111
|
-
# macaw = MacawFramework::Macaw.new
|
|
112
|
-
# macaw.delete("/hello") do |context|
|
|
113
|
-
# return "Hello World!", 200, { "Content-Type" => "text/plain" }
|
|
114
|
-
# end
|
|
115
|
-
def delete(path, cache: [], &block)
|
|
116
|
-
map_new_endpoint("delete", cache, path, &block)
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
##
|
|
120
|
-
# Spawn and start a thread running the defined cron job.
|
|
121
|
-
# @param {Integer} interval
|
|
122
|
-
# @param {Integer?} start_delay
|
|
123
|
-
# @param {String} job_name
|
|
124
|
-
# @param {Proc} block
|
|
125
|
-
# @example
|
|
126
|
-
#
|
|
127
|
-
# macaw = MacawFramework::Macaw.new
|
|
128
|
-
# macaw.setup_job(interval: 60, start_delay: 60, job_name: "job 1") do
|
|
129
|
-
# puts "I'm a cron job that runs every minute"
|
|
130
|
-
# end
|
|
131
|
-
def setup_job(interval: 60, start_delay: 0, job_name: "job_#{SecureRandom.uuid}", &block)
|
|
132
|
-
@cron_runner ||= CronRunner.new(self)
|
|
133
|
-
@jobs ||= []
|
|
134
|
-
@cron_runner.start_cron_job_thread(interval, start_delay, job_name, &block)
|
|
135
|
-
@jobs << job_name
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
##
|
|
139
|
-
# Starts the web server
|
|
140
|
-
def start!
|
|
141
|
-
if @macaw_log.nil?
|
|
142
|
-
puts("---------------------------------")
|
|
143
|
-
puts("Starting server at port #{@port}")
|
|
144
|
-
puts("Number of threads: #{@threads}")
|
|
145
|
-
puts("---------------------------------")
|
|
146
|
-
else
|
|
147
|
-
@macaw_log.info("---------------------------------")
|
|
148
|
-
@macaw_log.info("Starting server at port #{@port}")
|
|
149
|
-
@macaw_log.info("Number of threads: #{@threads}")
|
|
150
|
-
@macaw_log.info("---------------------------------")
|
|
151
|
-
end
|
|
152
|
-
@server = @server_class.new(self, @endpoints_to_cache, @cache, @prometheus, @prometheus_middleware)
|
|
153
|
-
server_loop(@server)
|
|
154
|
-
rescue Interrupt
|
|
155
|
-
if @macaw_log.nil?
|
|
156
|
-
puts("Stopping server")
|
|
157
|
-
@server.close
|
|
158
|
-
puts("Macaw stop flying for some seeds...")
|
|
159
|
-
else
|
|
160
|
-
@macaw_log.info("Stopping server")
|
|
161
|
-
@server.close
|
|
162
|
-
@macaw_log.info("Macaw stop flying for some seeds...")
|
|
163
|
-
end
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
##
|
|
167
|
-
# This method is intended to start the framework
|
|
168
|
-
# without an web server. This can be useful when
|
|
169
|
-
# you just want to keep cron jobs running, without
|
|
170
|
-
# mapping any HTTP endpoints.
|
|
171
|
-
def start_without_server!
|
|
172
|
-
@macaw_log.nil? ? puts("Application starting") : @macaw_log.info("Application starting")
|
|
173
|
-
loop { sleep(3600) }
|
|
174
|
-
rescue Interrupt
|
|
175
|
-
@macaw_log.nil? ? puts("Macaw stop flying for some seeds.") : @macaw_log.info("Macaw stop flying for some seeds.")
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
private
|
|
179
|
-
|
|
180
|
-
def apply_options(custom_log)
|
|
181
|
-
@routes = []
|
|
182
|
-
@cached_methods = {}
|
|
183
|
-
@macaw_log ||= custom_log
|
|
184
|
-
@config = JSON.parse(File.read("application.json"))
|
|
185
|
-
@port = @config["macaw"]["port"] || 8080
|
|
186
|
-
@bind = @config["macaw"]["bind"] || "localhost"
|
|
187
|
-
@session = false
|
|
188
|
-
unless @config["macaw"]["session"].nil?
|
|
189
|
-
@session = true
|
|
190
|
-
@secure_header = @config["macaw"]["session"]["secure_header"] || "X-Session-ID"
|
|
191
|
-
end
|
|
192
|
-
@threads = @config["macaw"]["threads"] || 200
|
|
193
|
-
unless @config["macaw"]["cache"].nil?
|
|
194
|
-
@cache = MemoryInvalidationMiddleware.new(@config["macaw"]["cache"]["cache_invalidation"].to_i || 3_600)
|
|
195
|
-
end
|
|
196
|
-
@prometheus = Prometheus::Client::Registry.new if @config["macaw"]["prometheus"]
|
|
197
|
-
@prometheus_middleware = PrometheusMiddleware.new if @config["macaw"]["prometheus"]
|
|
198
|
-
@prometheus_middleware.configure_prometheus(@prometheus, @config, self) if @config["macaw"]["prometheus"]
|
|
199
|
-
rescue StandardError => e
|
|
200
|
-
@macaw_log&.warn(e.message)
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
def server_loop(server)
|
|
204
|
-
server.run
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
def map_new_endpoint(prefix, cache, path, &block)
|
|
208
|
-
@endpoints_to_cache << "#{prefix}.#{RequestDataFiltering.sanitize_method_name(path)}" unless cache.empty?
|
|
209
|
-
@cached_methods["#{prefix}.#{RequestDataFiltering.sanitize_method_name(path)}"] = cache unless cache.empty?
|
|
210
|
-
path_clean = RequestDataFiltering.extract_path(path)
|
|
211
|
-
slash = path[0] == "/" ? "" : "/"
|
|
212
|
-
@macaw_log&.info("Defining #{prefix.upcase} endpoint at #{slash}#{path}")
|
|
213
|
-
define_singleton_method("#{prefix}.#{path_clean}", block || lambda {
|
|
214
|
-
|context = { headers: {}, body: "", params: {} }|
|
|
215
|
-
})
|
|
216
|
-
@routes << "#{prefix}.#{path_clean}"
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
def get_files_public_folder(dir)
|
|
220
|
-
return [] if dir.nil?
|
|
221
|
-
|
|
222
|
-
folder_path = Pathname.new(File.expand_path("public", dir))
|
|
223
|
-
file_paths = folder_path.glob("**/*").select(&:file?)
|
|
224
|
-
file_paths.map { |path| "public/#{path.relative_path_from(folder_path)}" }
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
def create_endpoint_public_files(dir)
|
|
228
|
-
get_files_public_folder(dir).each do |file|
|
|
229
|
-
get(file) { |_context| return File.read(file).to_s, 200, {} }
|
|
230
|
-
end
|
|
231
|
-
end
|
|
232
|
-
end
|
|
233
|
-
end
|
|
7
|
+
require_relative 'macaw_framework/macaw'
|
|
8
|
+
require_relative 'macaw_framework/cache'
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: macaw_framework
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.3.
|
|
4
|
+
version: 1.3.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Aria Diniz
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: prometheus-client
|
|
@@ -46,6 +45,7 @@ files:
|
|
|
46
45
|
- lib/macaw_framework/aspects/cache_aspect.rb
|
|
47
46
|
- lib/macaw_framework/aspects/logging_aspect.rb
|
|
48
47
|
- lib/macaw_framework/aspects/prometheus_aspect.rb
|
|
48
|
+
- lib/macaw_framework/cache.rb
|
|
49
49
|
- lib/macaw_framework/core/common/server_base.rb
|
|
50
50
|
- lib/macaw_framework/core/cron_runner.rb
|
|
51
51
|
- lib/macaw_framework/core/thread_server.rb
|
|
@@ -54,6 +54,7 @@ files:
|
|
|
54
54
|
- lib/macaw_framework/data_filters/response_data_filter.rb
|
|
55
55
|
- lib/macaw_framework/errors/endpoint_not_mapped_error.rb
|
|
56
56
|
- lib/macaw_framework/errors/too_many_requests_error.rb
|
|
57
|
+
- lib/macaw_framework/macaw.rb
|
|
57
58
|
- lib/macaw_framework/middlewares/memory_invalidation_middleware.rb
|
|
58
59
|
- lib/macaw_framework/middlewares/prometheus_middleware.rb
|
|
59
60
|
- lib/macaw_framework/middlewares/rate_limiter_middleware.rb
|
|
@@ -76,7 +77,6 @@ metadata:
|
|
|
76
77
|
documentation_uri: https://rubydoc.info/gems/macaw_framework
|
|
77
78
|
homepage_uri: https://github.com/ariasdiniz/macaw_framework
|
|
78
79
|
source_code_uri: https://github.com/ariasdiniz/macaw_framework
|
|
79
|
-
post_install_message:
|
|
80
80
|
rdoc_options: []
|
|
81
81
|
require_paths:
|
|
82
82
|
- lib
|
|
@@ -84,15 +84,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
84
84
|
requirements:
|
|
85
85
|
- - ">="
|
|
86
86
|
- !ruby/object:Gem::Version
|
|
87
|
-
version:
|
|
87
|
+
version: 3.0.0
|
|
88
88
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
89
|
requirements:
|
|
90
90
|
- - ">="
|
|
91
91
|
- !ruby/object:Gem::Version
|
|
92
92
|
version: '0'
|
|
93
93
|
requirements: []
|
|
94
|
-
rubygems_version:
|
|
95
|
-
signing_key:
|
|
94
|
+
rubygems_version: 4.0.3
|
|
96
95
|
specification_version: 4
|
|
97
96
|
summary: A lightweight back-end web framework
|
|
98
97
|
test_files: []
|