Class: RazorRisk::Cassini::Applications::Microservice

Inherits:
Sinatra::Base
  • Object
show all
Includes:
RazorRisk::Core::Diagnostics::Logger, Xqsr3::Quality::ParameterChecking
Defined in:
lib/razor_risk/cassini/applications/microservice.rb

Overview

Common base-class for all microservices

Notable features:

  • provide class attribute full_description, which assumes the deriving class has defined the constants FULL_DESIGNATION SERVICE_TYPE and SHORT_DESIGNATION, that obtains a human-readable "full Cassini' service description
  • provides class method init_base_service that is used to initialise the microservice class. It must be called within a class initialiser of a derived class
  • provides class method run! that ensures class initialisation (by a derived microservice class) has been performed
  • provides global 'before' handler that:
    • trace
    • log of request details
    • before handle that:
      • sets 'Content-Type' to 'text/plain'

Direct Known Subclasses

SecurableMicroservice, UnsecuredMicroservice

Class Method Summary collapse

Class Method Details

.define_catch_all_handlers ⇒ Object

Defines catch-all handlers for all available verbs

Unless given a block, it will create catch-all handlers with a basic message and obtaining a 404. If a block given, it will be invoked with two parameters - the method name symbol and an options hash within which are the options :env, :params, :request, and :response - and should return an array consisting of the HTTP status code and the body message.

NOTE: Must be the last component defining the application!



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/razor_risk/cassini/applications/microservice.rb', line 153

def self.define_catch_all_handlers

    methods =   %i(delete get head link options patch post put unlink)

    if block_given?

        methods.each do |method|

            send method, // do

                yield method, env: env, params: params, request: request, response: response
            end
        end
    else

        methods.each do |method|

            send method, // do

                [ 404, "'#{env['PATH_INFO']}' [#{method.to_s.upcase}] not found" ]
            end
        end
    end
end

.full_description ⇒ Object

Provides a full description of an including type, which must have the constants FULL_DESIGNATION, SERVICE_TYPE, and SHORT_DESIGNATION.



138
139
140
141
# File 'lib/razor_risk/cassini/applications/microservice.rb', line 138

def self.full_description

    "#{self::FULL_DESIGNATION} #{self::SERVICE_TYPE.to_s.capitalize} (#{self::SHORT_DESIGNATION})"
end

.init_base_service(host: to_nil(host_not_given_ = true), port: to_nil(port_not_given_ = true), **options) ⇒ Object

This must be invoked prior to activation of the application

Signature

  • Parameters:

    - host

    [String] The host to which the application binds. May be: nil, in which case no binding is performed and the Sinatra defaults are observed; +'0.0.0.0', in which case the server will listen on all available interfaces; a specific IP addres, in which case the server will listen only on that address. It is recommend that a specific address is used. Required

    - port

    [Integer] The port on which to activate. Required

Raises:

  • (ArgumentError)


190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/razor_risk/cassini/applications/microservice.rb', line 190

def self.init_base_service \
    host: to_nil(host_not_given_ = true),
    port: to_nil(port_not_given_ = true),
    **options

    trace ParamNames[ :host, :port, :options ], host, port, options

    raise ArgumentError, 'missing keyword: host' if host_not_given_

    raise ArgumentError, 'missing keyword: port' if port_not_given_
    check_parameter port, 'port', type: Integer

    init_base_service_ host, port, options
end

.run!(options = {}, &block) ⇒ Object

Refinement of ::Sinatra::Base.run! that ensures that the microservice class has been initialised



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/razor_risk/cassini/applications/microservice.rb', line 207

def self.run!(options = {}, &block)

    trace

    # TODO: Change this to use proper exception
    unless settings.respond_to?(:microservice_is_initialised) &&
            settings.respond_to?(:microservice_base_is_initialised)

        raise ArgumentError, "#{self} microservice application class is not initialised. Must first call #{self}.init_service()"
    end

    # Configures settings in backend service (e.g. thin, webrick)
    begin

        super do |server|

            # Set the timeout for the backend service. This prevents thin
            # from closing connections
            server.timeout = nil if server.respond_to? :timeout

            # This configures ssl in the backend service, which must be
            # thin.
            if settings.respond_to? :cassini_tls_settings

                cts = settings.cassini_tls_settings
                ssl_opts = {

                    cert_chain_file: cts[:tls_certificate_file],
                    private_key_file: cts[:tls_private_key_file],
                    verify_peer: false,
                }
                server.ssl = true
                server.ssl_options = ssl_opts
            end
        end
    rescue ::ArgumentError, ::NameError, ::NoMethodError, ::TypeError => x

        log :violation, "unexpected exception (#{x.class}): '#{x.message}': #{x.backtrace}"
        raise
    rescue => x

        log :alert, "exception (#{x.class}): '#{x.message}': #{x.backtrace}"
        raise
    end
end