Class: KingSoa::Service

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts) ⇒ Service

Returns a new instance of Service.



21
22
23
24
25
26
# File 'lib/king_soa/service.rb', line 21

def initialize(opts)
  self.name = opts[:name].to_sym
  [:url, :queue, :auth, :debug ].each do |opt|
    self.send("#{opt}=", opts[opt]) if opts[opt]
  end     
end

Instance Attribute Details

#authObject

name<String/Symbol>

name of the service class to call

auth<String/Int>

password for the remote service. Used by rack middleware

to authentify the callee

queue<Boolean>

turn on queueing for this service call. The incoming

request(className+parameter) will be put onto a resque queue

debug<Boolean>

turn on verbose output for typhoeus request

request_method<Symbol>

:get :post, :put : delete, used for curl request



17
18
19
# File 'lib/king_soa/service.rb', line 17

def auth
  @auth
end

#debugObject

name<String/Symbol>

name of the service class to call

auth<String/Int>

password for the remote service. Used by rack middleware

to authentify the callee

queue<Boolean>

turn on queueing for this service call. The incoming

request(className+parameter) will be put onto a resque queue

debug<Boolean>

turn on verbose output for typhoeus request

request_method<Symbol>

:get :post, :put : delete, used for curl request



17
18
19
# File 'lib/king_soa/service.rb', line 17

def debug
  @debug
end

#nameObject

name<String/Symbol>

name of the service class to call

auth<String/Int>

password for the remote service. Used by rack middleware

to authentify the callee

queue<Boolean>

turn on queueing for this service call. The incoming

request(className+parameter) will be put onto a resque queue

debug<Boolean>

turn on verbose output for typhoeus request

request_method<Symbol>

:get :post, :put : delete, used for curl request



17
18
19
# File 'lib/king_soa/service.rb', line 17

def name
  @name
end

#queueObject

name<String/Symbol>

name of the service class to call

auth<String/Int>

password for the remote service. Used by rack middleware

to authentify the callee

queue<Boolean>

turn on queueing for this service call. The incoming

request(className+parameter) will be put onto a resque queue

debug<Boolean>

turn on verbose output for typhoeus request

request_method<Symbol>

:get :post, :put : delete, used for curl request



17
18
19
# File 'lib/king_soa/service.rb', line 17

def queue
  @queue
end

#raw_urlObject (readonly)

raw_url<String>

raw incoming url string with request method prefixed “GET whatever



19
20
21
# File 'lib/king_soa/service.rb', line 19

def raw_url
  @raw_url
end

#request_methodObject

name<String/Symbol>

name of the service class to call

auth<String/Int>

password for the remote service. Used by rack middleware

to authentify the callee

queue<Boolean>

turn on queueing for this service call. The incoming

request(className+parameter) will be put onto a resque queue

debug<Boolean>

turn on verbose output for typhoeus request

request_method<Symbol>

:get :post, :put : delete, used for curl request



17
18
19
# File 'lib/king_soa/service.rb', line 17

def request_method
  @request_method
end

Instance Method Details

#add_to_queue(*args) ⇒ Object

A queued method MUST have an associated resque worker running and the soa class MUST have the @queue attribute for redis set



58
59
60
61
# File 'lib/king_soa/service.rb', line 58

def add_to_queue(*args)
  # use low level resque method since class might not be local available for Resque.enqueue
  Resque::Job.create(queue, local_class_name, *args)
end

#call_remote(*args) ⇒ Object

Call a service living somewhere in the soa universe. This is done by making a POST request to the url



30
31
32
33
34
35
# File 'lib/king_soa/service.rb', line 30

def call_remote(*args)
  request = Typhoeus::Easy.new
  set_request_opts(request, args)
  resp_code = request.perform
  parse_response(resp_code, request)
end

#decode(string) ⇒ Object



167
168
169
170
171
172
173
# File 'lib/king_soa/service.rb', line 167

def decode(string)
  begin
    JSON.parse(string)
  rescue JSON::ParserError => e
    raise e
  end
end

#encode(string) ⇒ Object



163
164
165
# File 'lib/king_soa/service.rb', line 163

def encode(string)
  string.to_json
end

#local_classObject

The local class, if found



85
86
87
88
89
90
91
# File 'lib/king_soa/service.rb', line 85

def local_class
  begin
    local_class_name.constantize
  rescue NameError => e        # no local implementation
    false
  end
end

#local_class_nameObject

Return the class name infered from the camelized service name.

Example

save_attachment => class SaveAttachment



96
97
98
# File 'lib/king_soa/service.rb', line 96

def local_class_name
  self.name.to_s.camelize
end

#params(payload) ⇒ Object

Params for a soa request consist of following values: name => name of the soa class to call args => arguments for the soa class method -> Class.perform(args) auth => an authentication key. something like a api key or pass. To make it really secure you MUST use https or hide your soa endpoints from public web acces

Parameter

payload<Hash|Array|String>

will be json encoded

Returns

<HashString=>String>

params added to the POST body



157
158
159
160
161
# File 'lib/king_soa/service.rb', line 157

def params(payload)
  { 'name'    => name.to_s,
    'args'    => encode(payload),
    'auth'    => auth }
end

#parse_response(resp_code, request) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/king_soa/service.rb', line 37

def parse_response(resp_code, request)
  case resp_code
  when 200
    if request.response_header.include?('Content-Type: application/json')
      #decode incoming json .. most likely from KingSoa's rack middleware
      return self.decode(request.response_body)["result"]
    else # return plain body
      return request.response_body
    end
  else
    if request.response_header.include?('Content-Type: application/json')
      #decode incoming json carriing an error.. most likely from KingSoa's rack middleware
      return self.decode(request.response_body)["error"]
    else # return plain body
      return request.response_body
    end
  end
end

#perform(*args) ⇒ Object

Call a method:

* remote over http
* local by calling perform method on a class
* put a job onto a queue

Parameter

args

whatever arguments the service methods receives. A local service/method

gets thems as splatted params. For a remote service they are converted to json

Returns

<nil> for queued services dont answer <mixed> Whatever the method/service



74
75
76
77
78
79
80
81
82
# File 'lib/king_soa/service.rb', line 74

def perform(*args)
  if queue
    add_to_queue(*args)
    return nil
  else # call the local class if present, else got remote
    result = local_class ? local_class.send(:perform, *args) : call_remote(*args)
    return result
  end
end

#set_request_opts(req, args) ⇒ Object

Set options for the typhoeus curl request

Parameter

req<Typhoeus::Easy>

request object

args<Array[]>

arguments for the soa method, added to post body json encoded



104
105
106
107
108
109
110
111
112
# File 'lib/king_soa/service.rb', line 104

def set_request_opts(req, args)
  req.url         = url
  req.method      = request_method || :post
  req.timeout     = 10000 # milliseconds
  req.params      = params(args)
  req.user_agent  = 'KingSoa'
  req.follow_location = true
  req.verbose     = 1 if debug
end

#urlObject



142
143
144
# File 'lib/king_soa/service.rb', line 142

def url
  @url
end

#url=(url_string) ⇒ Object

Params

url_string<String>::service location to call.

POST(default) myUrl.com myUrl.com:3000/my_path myUrl.com:3000/soa

Request types can be defined within url string:

GET http://myUrl.com
DELETE http://myUrl.com:3000/my_path
PUT http://myUrl.com:3000/soa
POST http://myUrl.com:3000/custom_post_receiving_path

Returns

url<String>

service Url



132
133
134
135
136
137
138
139
140
# File 'lib/king_soa/service.rb', line 132

def url=(url_string)
  # grab leading req type, case-insensitive
  if req_type = url_string[/^(GET|POST|PUT|DELETE)/i, 0]
    @request_method = req_type.downcase.to_sym
  end
  @raw_url = url_string
  # grab only url string starting with ht until its end
  @url = url_string[/ht.*/i, 0]
end