opener-webservice 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,418 +1,19 @@
1
- require "uuidtools"
2
- require "sinatra/base"
3
- require "json"
4
- require "opener/webservice/version"
5
- require "opener/webservice/opt_parser"
6
- require 'opener/callback_handler'
7
-
8
- module Opener
9
- class Webservice < Sinatra::Base
10
- configure do
11
- enable :logging
12
- if ARGV && pos = ARGV.index("--")
13
- ws_options = ARGV[pos..-1]
14
- else
15
- ws_options = []
16
- end
17
- options = OptParser.parse!(ws_options)
18
-
19
- options.each do |k,v|
20
- Sinatra::Application.set k.to_sym, v
21
- end
22
- end
23
-
24
- configure :development do
25
- set :raise_errors, true
26
- set :dump_errors, true
27
- end
28
-
29
- before %r{^((?!.css|.jpg|.png|.js|.ico).)+$} do
30
- extract_params
31
- authenticate! if Sinatra::Application.respond_to?(:authentication)
32
- end
33
-
34
- ##
35
- # Presents a simple form that can be used for getting the NER of a KAF
36
- # document.
37
- #
38
- get '/' do
39
- erb :index
40
- end
41
-
42
- ##
43
- # Puts the text through the primary processor. This route either accepts
44
- # regular POST fields or a JSON payload.
45
- #
46
- # @param [Hash] params The POST parameters.
47
- #
48
- # @option params [String] :input the input to send to the processor
49
- #
50
- # @option params [Array<String>] :callbacks A collection of callback URLs
51
- # that act as a chain. The results are posted to the first URL which is
52
- # then shifted of the list.
53
- #
54
- # @option params [String] :error_callback Callback URL to send errors to
55
- # when using the asynchronous setup.
56
- #
57
- post '/' do
58
- input_params = get_input_params
59
- input = get_input(input_params)
60
-
61
- if !input or input.strip.empty?
62
- logger.error('Failed to process the request: no input specified')
63
-
64
- halt(400, 'No input specified')
65
- end
66
-
67
- input_params[:input] = input
68
-
69
- callbacks = extract_callbacks(input_params[:callbacks])
70
- error_callback = input_params[:error_callback]
71
-
72
- if callbacks.empty?
73
- process_sync(input_params)
74
- else
75
- process_async(input_params, callbacks, error_callback)
76
- end
77
- end
78
-
79
- ##
80
- # @return [HTTPClient]
81
- #
82
- def self.http_client
83
- return @http_client || new_http_client
84
- end
85
-
86
- ##
87
- # @return [Opener::CallbackHandler]
88
- #
89
- def self.callback_handler
90
- return @callback_handler || new_callback_handler
91
- end
92
-
93
- ##
94
- # @return [HTTPClient]
95
- #
96
- def self.new_http_client
97
- client = HTTPClient.new
98
- client.connect_timeout = 120
99
-
100
- return client
101
- end
102
-
103
- ##
104
- # @return [Opener::CallbackHandler]
105
- #
106
- def self.new_callback_handler
107
- handler = Opener::CallbackHandler.new
108
-
109
- return handler
110
- end
111
-
112
- ##
113
- # Specifies the text processor to use or returns it if no parameter is
114
- # given.
115
- #
116
- # @param [Class] processor
117
- # @return [Class]
118
- #
119
- def self.text_processor(processor=nil)
120
- if processor.nil?
121
- return @processor
122
- else
123
- @processor = processor
124
- end
125
- end
126
-
127
- ##
128
- # Specifies what parameters are accepted.
129
- #
130
- # @param [Array] array The parameters to accept.
131
- #
132
- def self.accepted_params(*array)
133
- if array.empty?
134
- return @accepted_params
135
- else
136
- @accepted_params = array
137
- end
138
- @accepted_params.concat([secret_symbol, token_symbol]) if Sinatra::Application.respond_to?(:authentication)
139
- end
140
-
141
- ##
142
- # @return [Class]
143
- #
144
- def text_processor
145
- self.class.text_processor
146
- end
147
-
148
- ##
149
- # @return [Array]
150
- #
151
- def accepted_params
152
- self.class.accepted_params
153
- end
154
-
155
- ##
156
- # Processes the request synchronously.
157
- #
158
- # @param [Hash] input_params
159
- #
160
- def process_sync(input_params)
161
- output, type = analyze(filtered_params(input_params))
162
- content_type(type)
163
-
164
- body(output)
165
- end
166
-
167
- ##
168
- # Filter the params hash based on the accepted_params
169
- #
170
- # @param [Hash] input_params
171
- # @return [Hash]
172
- #
173
- def filtered_params(input_params)
174
- options = input_params.select{|k,v| accepted_params.include?(k.to_sym)}
175
- cleaned = {}
176
-
177
- options.each do |k, v|
178
- v = true if v == "true"
179
- v = false if v == "false"
180
-
181
- cleaned[k.to_sym] = v
182
- end
183
-
184
- return cleaned
185
- end
186
-
187
- ##
188
- # Processes the request asynchronously.
189
- #
190
- # @param [Hash] input_params
191
- # @param [Array] callbacks The callback URLs to use.
192
- # @param [String] error_callback
193
- #
194
- def process_async(input_params, callbacks, error_callback)
195
- request_id = get_request_id
196
- output_url = callbacks.last
197
-
198
- Thread.new do
199
- analyze_async(
200
- filtered_params(input_params),
201
- request_id,
202
- callbacks,
203
- error_callback
204
- )
205
- end
206
-
207
- content_type :json
208
-
209
- {
210
- :request_id => request_id.to_s,
211
- :output_url => [output_url, request_id].join("/")
212
- }.to_json
213
- end
214
-
215
- ##
216
- # Gets the Analyzed output of an input.
217
- #
218
- # @param [Hash] options The options for the text_processor
219
- # @return [String] output the output of the text_processor
220
- # @return [Symbol] type the output type ot the text_processor
221
- #
222
- # @raise RunetimeError Raised when the tagging process failed.
223
- #
224
- def analyze(options)
225
- processor = text_processor.new(options)
226
- output, error, status = processor.run(options[:input])
1
+ require 'securerandom'
2
+ require 'json'
227
3
 
228
- if processor.respond_to?(:output_type)
229
- type = processor.output_type
230
- else
231
- type = :xml
232
- end
233
-
234
- raise(error) if !status.nil? && !status.success?
235
-
236
- return output, type
237
- end
238
-
239
- ##
240
- # Gets the NER of a KAF document and submits it to a callback URL.
241
- #
242
- # @param [Hash] options
243
- # @param [String] request_id
244
- # @param [Array] callbacks
245
- # @param [String] error_callback
246
- #
247
- def analyze_async(options, request_id, callbacks, error_callback = nil)
248
- begin
249
- output, _ = analyze(options)
250
- rescue => error
251
- logger.error("Failed to process input: #{error.inspect}")
252
-
253
- submit_error(error_callback, error.message) if error_callback
254
- end
255
-
256
- url = callbacks.shift
257
-
258
- logger.info("Submitting results to #{url}")
259
-
260
- begin
261
- process_callback(options, url, output, request_id, callbacks, error_callback)
262
- rescue => error
263
- logger.error("Failed to submit the results: #{error.inspect}")
264
-
265
- submit_error(error_callback, error.message) if error_callback
266
- end
267
- end
268
-
269
- ##
270
- # @param [Hash] options
271
- # @param [String] url
272
- # @param [String] text
273
- # @param [String] request_id
274
- # @param [Array] callbacks
275
- #
276
- def process_callback(options, url, text, request_id, callbacks, error_callback)
277
- if request.content_type == 'application/json'
278
- headers = {'Content-Type' => 'application/json'}
279
- output = JSON.dump(
280
- filtered_params(options).merge(
281
- :input => text,
282
- :request_id => request_id,
283
- :callbacks => callbacks,
284
- :error_callback => error_callback
285
- )
286
- )
287
- else
288
- headers = {}
289
- output = filtered_params(options).merge(
290
- :input => text,
291
- :request_id => request_id,
292
- :'callbacks[]' => callbacks,
293
- :error_callback => error_callback
294
- )
295
- end
296
-
297
- extract_params
298
-
299
- callback_handler.post(url, :body => output, :header => headers)
300
- end
301
-
302
- ##
303
- # @param [String] url
304
- # @param [String] message
305
- #
306
- def submit_error(url, message)
307
- callback_handler.post(url, :body => {:error => message})
308
- end
309
-
310
- ##
311
- # Returns an Array containing the callback URLs, ignoring empty values.
312
- #
313
- # @param [Array|String] input
314
- # @return [Array]
315
- #
316
- def extract_callbacks(input)
317
- return [] if input.nil? || input.empty?
318
-
319
- callbacks = input.compact.reject(&:empty?)
320
-
321
- return callbacks
322
- end
323
-
324
- ##
325
- # @return [String]
326
- #
327
- def get_request_id
328
- return params[:request_id] || UUIDTools::UUID.random_create
329
- end
330
-
331
- ##
332
- # @see Opener::Webservice.http_client
333
- #
334
- def http_client
335
- return self.class.http_client
336
- end
337
-
338
- ##
339
- # @see Opener::Webservice.callback_handler
340
- #
341
- def callback_handler
342
- return self.class.callback_handler
343
- end
344
-
345
- def authenticate!
346
- credentials = {
347
- secret_symbol => params[secret_symbol.to_s],
348
- token_symbol => params[token_symbol.to_s]
349
- }
350
- response = http_client.get(Sinatra::Application.authentication, credentials)
351
- halt response.body unless response.ok?
352
- end
353
-
354
- ##
355
- # Returns a Hash containing the input parameters to use. If a JSON payload
356
- # is submitted the parameters will be based on the payload.
357
- #
358
- # @return [Hash]
359
- #
360
- def get_input_params
361
- input = {}
362
-
363
- if request.content_type == 'application/json'
364
- JSON.load(request.body).each do |key, value|
365
- input[key.to_sym] = value
366
- end
367
- else
368
- input = params
369
- end
370
-
371
- return input
372
- end
373
-
374
- def extract_params
375
- if request.referrer
376
- uri = URI.parse(request.referrer)
377
- extracted = Rack::Utils.parse_nested_query(uri.query)
378
- params.merge!(extracted)
379
- end
380
- end
381
-
382
- def self.secret_symbol
383
- Sinatra::Application.respond_to?(:secret)? Sinatra::Application.secret.to_sym : :secret
384
- end
385
-
386
- def self.token_symbol
387
- Sinatra::Application.respond_to?(:token)? Sinatra::Application.token.to_sym : :token
388
- end
389
-
390
- def secret_symbol
391
- return self.class.secret_symbol
392
- end
393
-
394
- def token_symbol
395
- return self.class.token_symbol
396
- end
397
-
398
- ##
399
- # Returns the KAF/text input as a String.
400
- #
401
- # @param [Hash] params
402
- # @return [String]
403
- #
404
- def get_input(params)
405
- input = nil
406
-
407
- if params[:input]
408
- input = params[:input]
409
-
410
- elsif params[:input_url]
411
- resp = HTTPClient.get(params[:input_url], :follow_redirect => true)
412
- input = resp.body if resp.ok?
413
- end
414
-
415
- return input
416
- end
417
- end
418
- end
4
+ require 'puma/cli'
5
+ require 'slop'
6
+ require 'sinatra/base'
7
+ require 'opener/core'
8
+ require 'opener/callback_handler'
9
+ require 'rollbar'
10
+ require 'new_relic/control'
11
+
12
+ require_relative 'webservice/version'
13
+ require_relative 'webservice/configuration'
14
+ require_relative 'webservice/server'
15
+ require_relative 'webservice/uploader'
16
+ require_relative 'webservice/error_handler'
17
+ require_relative 'webservice/input_extractor'
18
+ require_relative 'webservice/input_sanitizer'
19
+ require_relative 'webservice/option_parser'
@@ -1,10 +1,10 @@
1
1
  require File.expand_path('../lib/opener/webservice/version', __FILE__)
2
2
 
3
3
  Gem::Specification.new do |spec|
4
- spec.name = "opener-webservice"
4
+ spec.name = 'opener-webservice'
5
5
  spec.version = Opener::Webservice::VERSION
6
- spec.authors = ["development@olery.com"]
7
- spec.summary = %q{Basic webservice hooks for the opener toolchain}
6
+ spec.authors = ['development@olery.com']
7
+ spec.summary = 'Basic webservice hooks for the OpeNER toolchain'
8
8
  spec.description = spec.summary
9
9
 
10
10
  spec.license = 'Apache 2.0'
@@ -16,13 +16,21 @@ Gem::Specification.new do |spec|
16
16
  'LICENSE.txt'
17
17
  ]).select { |file| File.file?(file) }
18
18
 
19
- spec.add_dependency "sinatra", "~> 1.4.3"
20
- spec.add_dependency "uuidtools"
21
- spec.add_dependency "json"
22
- spec.add_dependency "opener-callback-handler", '~> 1.0'
19
+ spec.add_dependency 'sinatra', '~> 1.4.3'
20
+ spec.add_dependency 'uuidtools'
21
+ spec.add_dependency 'json'
22
+ spec.add_dependency 'opener-callback-handler', '~> 1.0'
23
23
  spec.add_dependency 'httpclient', ['~> 2.0', '>= 2.5.3.3']
24
+ spec.add_dependency 'opener-core', '~> 2.0'
25
+ spec.add_dependency 'puma'
26
+ spec.add_dependency 'slop', '~> 3.0'
24
27
 
25
- spec.add_development_dependency "bundler", "~> 1.3"
26
- spec.add_development_dependency "rake"
27
- spec.add_development_dependency "pry"
28
+ spec.add_dependency 'newrelic_rpm'
29
+ spec.add_dependency 'rollbar', '~> 1.0'
30
+
31
+ spec.add_development_dependency 'bundler', '~> 1.3'
32
+ spec.add_development_dependency 'rake'
33
+ spec.add_development_dependency 'pry'
34
+ spec.add_development_dependency 'rspec'
35
+ spec.add_development_dependency 'rack-test'
28
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opener-webservice
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - development@olery.com
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-17 00:00:00.000000000 Z
11
+ date: 2014-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -86,6 +86,76 @@ dependencies:
86
86
  - - ">="
87
87
  - !ruby/object:Gem::Version
88
88
  version: 2.5.3.3
89
+ - !ruby/object:Gem::Dependency
90
+ name: opener-core
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '2.0'
96
+ type: :runtime
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '2.0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: puma
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: slop
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '3.0'
124
+ type: :runtime
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '3.0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: newrelic_rpm
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ type: :runtime
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ - !ruby/object:Gem::Dependency
146
+ name: rollbar
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '1.0'
152
+ type: :runtime
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '1.0'
89
159
  - !ruby/object:Gem::Dependency
90
160
  name: bundler
91
161
  requirement: !ruby/object:Gem::Requirement
@@ -128,7 +198,35 @@ dependencies:
128
198
  - - ">="
129
199
  - !ruby/object:Gem::Version
130
200
  version: '0'
131
- description: Basic webservice hooks for the opener toolchain
201
+ - !ruby/object:Gem::Dependency
202
+ name: rspec
203
+ requirement: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - ">="
206
+ - !ruby/object:Gem::Version
207
+ version: '0'
208
+ type: :development
209
+ prerelease: false
210
+ version_requirements: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
215
+ - !ruby/object:Gem::Dependency
216
+ name: rack-test
217
+ requirement: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - ">="
220
+ - !ruby/object:Gem::Version
221
+ version: '0'
222
+ type: :development
223
+ prerelease: false
224
+ version_requirements: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - ">="
227
+ - !ruby/object:Gem::Version
228
+ version: '0'
229
+ description: Basic webservice hooks for the OpeNER toolchain
132
230
  email:
133
231
  executables: []
134
232
  extensions: []
@@ -137,7 +235,13 @@ files:
137
235
  - LICENSE.txt
138
236
  - README.md
139
237
  - lib/opener/webservice.rb
140
- - lib/opener/webservice/opt_parser.rb
238
+ - lib/opener/webservice/configuration.rb
239
+ - lib/opener/webservice/error_handler.rb
240
+ - lib/opener/webservice/input_extractor.rb
241
+ - lib/opener/webservice/input_sanitizer.rb
242
+ - lib/opener/webservice/option_parser.rb
243
+ - lib/opener/webservice/server.rb
244
+ - lib/opener/webservice/uploader.rb
141
245
  - lib/opener/webservice/version.rb
142
246
  - opener-webservice.gemspec
143
247
  homepage:
@@ -163,6 +267,6 @@ rubyforge_project:
163
267
  rubygems_version: 2.2.2
164
268
  signing_key:
165
269
  specification_version: 4
166
- summary: Basic webservice hooks for the opener toolchain
270
+ summary: Basic webservice hooks for the OpeNER toolchain
167
271
  test_files: []
168
272
  has_rdoc: