Class: KingSoa::Rack::Middleware

Inherits:
Object
  • Object
show all
Defined in:
lib/king_soa/rack/middleware.rb

Instance Method Summary collapse

Constructor Details

#initialize(app, config = {}) ⇒ Middleware

Params

app

Application to call next

config<HashSymbol=>String>

config hash

:endpoint_path<RegEx>

Path which is getting all incoming soa requests.

Defaults to /^/soa/ => /soa Make sure your service url’s have it set too.



11
12
13
14
15
# File 'lib/king_soa/rack/middleware.rb', line 11

def initialize(app, config={})
  @app = app
  @config = config
  @config[:endpoint_path] ||= /^\/soa/
end

Instance Method Details

#authenticated?(service, key) ⇒ Boolean

TODO raise and rescue specific error

Returns:

  • (Boolean)


54
55
56
# File 'lib/king_soa/rack/middleware.rb', line 54

def authenticated?(service, key)
  raise "Please provide a valid authentication key" unless service.auth == key
end

#call(env) ⇒ Object

Takes incoming soa requests and calls the passed in method with given params



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/king_soa/rack/middleware.rb', line 18

def call(env)
  if env["PATH_INFO"] =~ @config[:endpoint_path]
    begin
      req = Rack::Request.new(env)
      # find service
      service = KingSoa.find(req.params["name"])
      #  TODO rescue service class not found
      raise "The service: #{req.params["name"]} could not be found" unless service
      # authenticate
      authenticated?(service, req.params["auth"])
      # perform method with decoded params
      result = service.perform(*service.decode( req.params["args"] ))
      # encode result
      encoded_result = service.encode({"result" => result})
      # and return
      [
        200,
        {'Content-Type' => 'application/json', 'Content-Length' => "#{encoded_result.length}"},
        [encoded_result] 
      ]

    rescue Exception => e
      if service
        encoded_error = service.encode({"error" => e})
        [500, {'Content-Type' => 'application/json', 'Content-Length' => "#{encoded_error.length}"}, [encoded_error]]
      else
        encoded_error = {"error" => "An error occurred => #{e.message}"}.to_json
        [500, {'Content-Type' => "application/json", 'Content-Length' => "#{encoded_error.length}"}, [encoded_error]]
      end
    end
  else
    @app.call(env)
  end
end