restful-portfolios 0.13.17
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 +7 -0
- data/bin/razorrisk-microservice-portfolios +390 -0
- data/lib/razor_risk/cassini/applications/microservices/restful/portfolios/version.rb +51 -0
- data/lib/razor_risk/cassini/applications/microservices/restful/portfolios.rb +2 -0
- data/lib/razor_risk/cassini/applications/route_verb_adaptors/portfolios/collection_get.rb +253 -0
- data/lib/razor_risk/cassini/applications/route_verb_adaptors/portfolios/hierarchy_get.rb +207 -0
- data/lib/razor_risk/cassini/applications/route_verb_adaptors/portfolios/item_delete.rb +112 -0
- data/lib/razor_risk/cassini/applications/route_verb_adaptors/portfolios/item_get.rb +169 -0
- data/lib/razor_risk/cassini/applications/route_verb_adaptors/portfolios/item_post.rb +130 -0
- data/lib/razor_risk/cassini/applications/route_verb_adaptors/portfolios/item_put.rb +138 -0
- data/lib/razor_risk/cassini/applications/route_verb_adaptors/portfolios.rb +8 -0
- data/lib/razor_risk/cassini/applications/route_verb_adaptors/utilities/portfolios.rb +85 -0
- metadata +260 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: afdeee7dc34ce903cb034e7db4c531411206f2211fe9c931cd7d85fdc46ef6a8
|
4
|
+
data.tar.gz: 39c6de3caae664a82a9b630c6c05449962ab436ac6a62461292539b46defb334
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e398a4378657e62781dae9633fc4ba0f718f5b5af5ec5229ec26bcd30a5884558affa60eaff81a65e777c32e874f5f2d1b198262ac5137dec91e4f366e9b385e
|
7
|
+
data.tar.gz: f76d75976e8744eebce9321e7edb87222207e78256d97a55e09f576d27497ed3ab92fc3f75a5d87b7b4ef37da4585cb3ba89657876633dd661a48cd0fab44db8
|
@@ -0,0 +1,390 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
# ######################################################################## #
|
5
|
+
#
|
6
|
+
# Main module/entry file for the Portfolios Microservice
|
7
|
+
#
|
8
|
+
# Copyright (c) 2017 Razor Risk Technologies Pty Limited. All rights reserved.
|
9
|
+
#
|
10
|
+
# ######################################################################## #
|
11
|
+
|
12
|
+
|
13
|
+
# ##########################################################################
|
14
|
+
|
15
|
+
# Microservices: Portfolios (portfolios)
|
16
|
+
#
|
17
|
+
# Supported:
|
18
|
+
#
|
19
|
+
# - [GET] / {Unsecured}
|
20
|
+
# - [DELETE] /delete/:id {Secured}
|
21
|
+
# - [GET] /get {Secured}
|
22
|
+
# - [GET] /get/:id {Secured}
|
23
|
+
# - [PUT] /put/:id {Secured}
|
24
|
+
|
25
|
+
# ##########################################################################
|
26
|
+
# requires
|
27
|
+
|
28
|
+
require 'razor_risk/cassini/diagnostics/zeroth_include'
|
29
|
+
|
30
|
+
require 'razor_risk/cassini/applications/microservices/restful/portfolios'
|
31
|
+
|
32
|
+
require 'razor_risk/cassini/applications/route_verb_adaptors/portfolios'
|
33
|
+
|
34
|
+
require 'razor_risk/cassini/main'
|
35
|
+
|
36
|
+
require 'razor_risk/cassini/applications/rest_framework/route_verb_dispatcher'
|
37
|
+
require 'razor_risk/cassini/applications/secured_microservice'
|
38
|
+
require 'razor_risk/cassini/authorisation'
|
39
|
+
require 'razor_risk/cassini/common/version'
|
40
|
+
require 'razor_risk/cassini/util/version_util'
|
41
|
+
|
42
|
+
require 'razor_risk/razor/connectivity/razor_3/header_maker'
|
43
|
+
require 'razor_risk/razor/connectivity/razor_3/razor_requester'
|
44
|
+
require 'razor_risk/razor/connectivity/version'
|
45
|
+
|
46
|
+
require 'razor_risk/core/diagnostics/extensions/libclimate'
|
47
|
+
require 'razor_risk/core/diagnostics/logger'
|
48
|
+
|
49
|
+
require 'active_support/core_ext/hash'
|
50
|
+
require 'pantheios'
|
51
|
+
require 'xqsr3/version'
|
52
|
+
|
53
|
+
require 'csv'
|
54
|
+
require 'json'
|
55
|
+
require 'nokogiri'
|
56
|
+
|
57
|
+
# ##########################################################################
|
58
|
+
# includes
|
59
|
+
|
60
|
+
include ::RazorRisk::Cassini::Applications
|
61
|
+
include ::RazorRisk::Cassini::Applications::RESTFramework
|
62
|
+
include ::RazorRisk::Cassini::Applications::RouteVerbAdaptors
|
63
|
+
include ::RazorRisk::Cassini::Authorisation::SecurityModelHelpers
|
64
|
+
include ::RazorRisk::Cassini::Constants
|
65
|
+
include ::RazorRisk::Cassini::Util::SecretsUtil
|
66
|
+
include ::RazorRisk::Cassini::Util::VersionUtil
|
67
|
+
|
68
|
+
include ::RazorRisk::Razor::Connectivity::Razor3
|
69
|
+
|
70
|
+
include ::RazorRisk::Cassini::Diagnostics
|
71
|
+
|
72
|
+
include ::Pantheios
|
73
|
+
|
74
|
+
include ::RazorRisk::Core::Diagnostics::Logger
|
75
|
+
|
76
|
+
# ##########################################################################
|
77
|
+
# constants
|
78
|
+
|
79
|
+
PROGRAM_VERSION = ::RazorRisk::Cassini::Applications::Microservices::RESTful::Portfolios::VERSION
|
80
|
+
|
81
|
+
SUPPORTED_ROUTES = [
|
82
|
+
|
83
|
+
[ '/delete/:id', :delete, 'deletes the specified portfolio', ],
|
84
|
+
[ '/get', :get, 'gets the collection of portfolios', ],
|
85
|
+
[ '/get/:id', :get, 'gets the specified portfolio', ],
|
86
|
+
[ '/put/:id', :put, 'puts the specified portfolio', ],
|
87
|
+
]
|
88
|
+
|
89
|
+
HTTP_ACCEPTS = %w{ text/html application/json application/xml text/xml text/csv text/plain text/tab-separated-values text/tsv }
|
90
|
+
|
91
|
+
# ##########################################################################
|
92
|
+
# compatibility checks
|
93
|
+
|
94
|
+
check_version_compatibility ::RazorRisk::Cassini::Common, [ 0, 21 ], 'RazorRisk.Cassini.Common'
|
95
|
+
check_version_compatibility ::RazorRisk::Razor::Connectivity, [ 0, 11, 2 ], 'RazorRisk.Razor.Connectivity'
|
96
|
+
check_version_compatibility ::LibCLImate, '0.10'
|
97
|
+
check_version_compatibility ::Pantheios, '0.20'
|
98
|
+
check_version_compatibility ::Xqsr3::VERSION, '0.30'
|
99
|
+
|
100
|
+
# ##########################################################################
|
101
|
+
# functions
|
102
|
+
|
103
|
+
def make_CSV_routes routes
|
104
|
+
|
105
|
+
CSV.generate do |csv|
|
106
|
+
|
107
|
+
routes.each do |ar|
|
108
|
+
|
109
|
+
csv << ar
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def make_HTML_routes routes, **options
|
115
|
+
|
116
|
+
# TODO: use erb
|
117
|
+
|
118
|
+
routes = routes.map do |ar|
|
119
|
+
|
120
|
+
<<END_OF_tr
|
121
|
+
<tr>
|
122
|
+
<td>#{ar[0]}</td>
|
123
|
+
<td>#{ar[1]}</td>
|
124
|
+
<td>#{ar[2]}</td>
|
125
|
+
</tr>
|
126
|
+
END_OF_tr
|
127
|
+
end
|
128
|
+
|
129
|
+
<<END_OF_html
|
130
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.we.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
131
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
132
|
+
<head>
|
133
|
+
<title>Razor Risk Web Service API - Internal Microservice - Portfolio</title>
|
134
|
+
<meta name="revisit-after" content="24 hours" />
|
135
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
136
|
+
</head>
|
137
|
+
<body>
|
138
|
+
<h1>Routes</h1>
|
139
|
+
<table>
|
140
|
+
<tr>
|
141
|
+
<th>Route</th>
|
142
|
+
<th>Verb</th>
|
143
|
+
<th>Description</th>
|
144
|
+
</tr>
|
145
|
+
#{routes.map { |r| r.chomp("\n") }.join("\n")}
|
146
|
+
</table>
|
147
|
+
</body>
|
148
|
+
</html>
|
149
|
+
END_OF_html
|
150
|
+
end
|
151
|
+
|
152
|
+
def make_JSON_routes routes, **options
|
153
|
+
|
154
|
+
r = {
|
155
|
+
|
156
|
+
'routes' => []
|
157
|
+
}
|
158
|
+
|
159
|
+
r['routes'] = SUPPORTED_ROUTES.map { |ar| { route: ar[0], verb: ar[1].to_s.upcase, description: ar[2] } }
|
160
|
+
|
161
|
+
r.to_json
|
162
|
+
end
|
163
|
+
|
164
|
+
def make_Plain_routes routes
|
165
|
+
|
166
|
+
make_TSV_routes routes
|
167
|
+
end
|
168
|
+
|
169
|
+
def make_TSV_routes routes
|
170
|
+
|
171
|
+
routes.map { |ar| "#{ar[0]}\t#{ar[1]}\t#{ar[2]}\n" }
|
172
|
+
end
|
173
|
+
|
174
|
+
def make_XML_routes routes
|
175
|
+
|
176
|
+
<<END_OF_xml
|
177
|
+
<?xml version="1.0">
|
178
|
+
<routes>#{routes.map { |ar| %Q{ <route route="#{ar[0]}" verb="#{ar[1].to_s.upcase}" description="#{ar[2]}"/>}}.join(%Q{\n})}
|
179
|
+
</routes>
|
180
|
+
END_OF_xml
|
181
|
+
end
|
182
|
+
|
183
|
+
# ##########################################################################
|
184
|
+
# static set-up
|
185
|
+
|
186
|
+
# ##########################################################################
|
187
|
+
# lambdas
|
188
|
+
|
189
|
+
Lambdas_XML_to_JSON = lambda do |xml|
|
190
|
+
|
191
|
+
ConversionUtil.convert_XML_to_JSON xml
|
192
|
+
end
|
193
|
+
|
194
|
+
# ##########################################################################
|
195
|
+
# application
|
196
|
+
|
197
|
+
class PortfoliosApp < SecuredMicroservice
|
198
|
+
|
199
|
+
include RouteVerbDispatch
|
200
|
+
|
201
|
+
include ::Pantheios
|
202
|
+
|
203
|
+
|
204
|
+
FULL_DESIGNATION = 'Portfolios'
|
205
|
+
SHORT_DESIGNATION = 'portfolios'
|
206
|
+
SERVICE_TYPE = :microservice
|
207
|
+
|
208
|
+
PROGRAM_FEATURES = {
|
209
|
+
|
210
|
+
has_web_server: true,
|
211
|
+
|
212
|
+
has_host_and_port: true,
|
213
|
+
|
214
|
+
has_razor_connectivity: true,
|
215
|
+
|
216
|
+
authentication: :with_credentials_algorithm,
|
217
|
+
|
218
|
+
copyright_year: 2017,
|
219
|
+
}
|
220
|
+
|
221
|
+
|
222
|
+
def self.on_init_service options
|
223
|
+
|
224
|
+
trace ParamNames[ :options ], options
|
225
|
+
|
226
|
+
raise ArgumentError, 'missing keyword: razor_requester' unless options.has_key? :razor_requester
|
227
|
+
|
228
|
+
set :razor_requester, options[:razor_requester]
|
229
|
+
end
|
230
|
+
|
231
|
+
|
232
|
+
|
233
|
+
private
|
234
|
+
def sec
|
235
|
+
|
236
|
+
return '' if credentials.empty?
|
237
|
+
" (for #{credentials.join(':')})"
|
238
|
+
end
|
239
|
+
public
|
240
|
+
|
241
|
+
|
242
|
+
# functional routes (DELETE, GET, PUT)
|
243
|
+
|
244
|
+
delete '/delete/:id/?' do
|
245
|
+
|
246
|
+
# trace
|
247
|
+
|
248
|
+
trace ParamNames[ :request, :params ], request, params
|
249
|
+
|
250
|
+
dispatch Portfolios::ItemDelete
|
251
|
+
end
|
252
|
+
|
253
|
+
# === Query Parameters
|
254
|
+
#
|
255
|
+
# +page-base+:: [Numeric] (0) Specifies the (0-based) index index of the
|
256
|
+
# first element to be presented.
|
257
|
+
# +page-extent+:: [Numeric] (1000) Specifies the number of records to
|
258
|
+
# return in the retrieval window.
|
259
|
+
# +key-search+:: [String] Specifies a string inf the form of a series of
|
260
|
+
# keys and values to search for.
|
261
|
+
# +filter-name+:: [String] The name of a filter to use.
|
262
|
+
get '/get/hierarchy/?' do
|
263
|
+
|
264
|
+
trace ParamNames[ :request, :params ], request, params
|
265
|
+
|
266
|
+
dispatch Portfolios::HierarchyGet
|
267
|
+
end
|
268
|
+
|
269
|
+
# params:
|
270
|
+
# +result-form+:: Specifies the form of the result: +default+ gets the
|
271
|
+
# full Razor body, and is the default if none specified; +summary+ gets
|
272
|
+
# the portfolio-summary form; +portfolio+ gets the portfolio form
|
273
|
+
get '/get/:id/?' do
|
274
|
+
|
275
|
+
# trace
|
276
|
+
|
277
|
+
trace ParamNames[ :request, :params ], request, params
|
278
|
+
|
279
|
+
dispatch Portfolios::ItemGet
|
280
|
+
end
|
281
|
+
|
282
|
+
# params:
|
283
|
+
# +page-base+:: Specifies the (0-based) index index of the first element
|
284
|
+
# to be presented. Defaults to 0 if not specified
|
285
|
+
# +page-extent+:: Specifies the number of records to return in the
|
286
|
+
# retrieval window. Defaults to 1000 if not specified
|
287
|
+
# +quick-search+:: Specifies a quick-search string
|
288
|
+
# +key-search+:: Specifies a string inf the form of a series of keys and values to search for
|
289
|
+
get '/get/?' do
|
290
|
+
|
291
|
+
trace ParamNames[ :request, :params ], request, params
|
292
|
+
|
293
|
+
dispatch Portfolios::CollectionGet
|
294
|
+
end
|
295
|
+
|
296
|
+
post '/post/?' do
|
297
|
+
|
298
|
+
trace ParamNames[ :request, :params ], request, params
|
299
|
+
|
300
|
+
dispatch Portfolios::ItemPost
|
301
|
+
end
|
302
|
+
|
303
|
+
put '/put/:id/?' do
|
304
|
+
|
305
|
+
trace ParamNames[ :request, :params ], request, params
|
306
|
+
|
307
|
+
dispatch Portfolios::ItemPut
|
308
|
+
end
|
309
|
+
|
310
|
+
get '/' do
|
311
|
+
|
312
|
+
HTTP_ACCEPTS.each do |accept_type|
|
313
|
+
|
314
|
+
if request.accept? accept_type
|
315
|
+
|
316
|
+
content_type accept_type
|
317
|
+
|
318
|
+
case accept_type
|
319
|
+
when 'application/json'
|
320
|
+
|
321
|
+
r = make_JSON_routes SUPPORTED_ROUTES
|
322
|
+
when 'application/xml', 'text/xml'
|
323
|
+
|
324
|
+
r = make_XML_routes SUPPORTED_ROUTES
|
325
|
+
when 'text/csv'
|
326
|
+
|
327
|
+
r = make_CSV_routes SUPPORTED_ROUTES
|
328
|
+
when 'text/html'
|
329
|
+
|
330
|
+
r = make_HTML_routes SUPPORTED_ROUTES
|
331
|
+
when 'text/plain'
|
332
|
+
|
333
|
+
r = make_Plain_routes SUPPORTED_ROUTES
|
334
|
+
when 'text/tsv', 'text/tab-separated-values'
|
335
|
+
|
336
|
+
r = make_TSV_routes SUPPORTED_ROUTES
|
337
|
+
else
|
338
|
+
|
339
|
+
log :violation, 'unrecognised accept type \'', accept_type, '\''
|
340
|
+
|
341
|
+
halt *[ 500, {}, 'internal server failure' ]
|
342
|
+
end
|
343
|
+
|
344
|
+
return r
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
halt *[ 406, {}, "supports only the Accept types #{HTTP_ACCEPTS.map { |t| %Q<'#{t}'> }.join(', ')}" ]
|
349
|
+
end
|
350
|
+
|
351
|
+
define_catch_all_handlers
|
352
|
+
end
|
353
|
+
|
354
|
+
TheApp = PortfoliosApp
|
355
|
+
|
356
|
+
# now define the OPTIONS support
|
357
|
+
|
358
|
+
supported_routes = Hash.new { |h, k| h[k] = [] }
|
359
|
+
|
360
|
+
SUPPORTED_ROUTES.each do |ar|
|
361
|
+
|
362
|
+
supported_routes[ar[0]].push ar[1]
|
363
|
+
end
|
364
|
+
|
365
|
+
supported_routes.each do |k, v|
|
366
|
+
|
367
|
+
if k =~ /:id(?:\/\?)?$/
|
368
|
+
|
369
|
+
route = "#$`*"
|
370
|
+
else
|
371
|
+
|
372
|
+
route = k
|
373
|
+
end
|
374
|
+
|
375
|
+
TheApp.options route do
|
376
|
+
|
377
|
+
verbs = v.map { |t| t.upcase }.join(',')
|
378
|
+
|
379
|
+
halt *[200, { 'Allow' => verbs }, [ verbs ] ]
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
TheApp.options '/' do
|
384
|
+
|
385
|
+
halt *[200, { 'Allow' => 'GET' }, '' ]
|
386
|
+
end
|
387
|
+
|
388
|
+
# ############################## end of file ############################# #
|
389
|
+
|
390
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# ######################################################################## #
|
4
|
+
#
|
5
|
+
# Version for RazorRisk.Cassini.Microservices.RESTful.Portfolios library
|
6
|
+
#
|
7
|
+
# Copyright (c) 2019 Razor Risk Technologies Pty Limited. All rights reserved.
|
8
|
+
#
|
9
|
+
# ######################################################################## #
|
10
|
+
|
11
|
+
|
12
|
+
module RazorRisk
|
13
|
+
module Cassini
|
14
|
+
module Applications
|
15
|
+
module Microservices
|
16
|
+
module RESTful
|
17
|
+
|
18
|
+
module Portfolios
|
19
|
+
|
20
|
+
# Current version of the RazorRisk.Cassini.Microservices.RESTful.Portfolios library
|
21
|
+
VERSION = '0.13.17'
|
22
|
+
|
23
|
+
private
|
24
|
+
VERSION_PARTS_ = VERSION.split(/[.]/).collect { |n| n.to_i } # :nodoc:
|
25
|
+
public
|
26
|
+
# Major version of the RazorRisk.Cassini.Microservices.RESTful.Portfolios library
|
27
|
+
VERSION_MAJOR = VERSION_PARTS_[0] # :nodoc:
|
28
|
+
# Minor version of the RazorRisk.Cassini.Microservices.RESTful.Portfolios library
|
29
|
+
VERSION_MINOR = VERSION_PARTS_[1] # :nodoc:
|
30
|
+
# Patch version of the RazorRisk.Cassini.Microservices.RESTful.Portfolios library
|
31
|
+
VERSION_PATCH = VERSION_PARTS_[2] # :nodoc:
|
32
|
+
# Commit version of the RazorRisk.Cassini.Microservices.RESTful.Portfolios library
|
33
|
+
VERSION_COMMIT = VERSION_PARTS_[3] || 0 # :nodoc:
|
34
|
+
|
35
|
+
|
36
|
+
# The description of the framework
|
37
|
+
DESCRIPTION = "Razor Risk's Cassini Web-framework's Portfolios RESTful microservice"
|
38
|
+
|
39
|
+
# [DEPRECATED] Instead use +DESCRIPTION+
|
40
|
+
FRAMEWORK_DESCRIPTION = DESCRIPTION
|
41
|
+
end # module Portfolios
|
42
|
+
|
43
|
+
end # module RESTful
|
44
|
+
end # module Microservices
|
45
|
+
end # module Applications
|
46
|
+
end # module Cassini
|
47
|
+
end # module RazorRisk
|
48
|
+
|
49
|
+
# ############################## end of file ############################# #
|
50
|
+
|
51
|
+
|
@@ -0,0 +1,253 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# ######################################################################## #
|
4
|
+
#
|
5
|
+
# Adaptor for Portfolios microservice's collection GET verb
|
6
|
+
#
|
7
|
+
# Copyright (c) 2018 Razor Risk Technologies Pty Limited. All rights reserved.
|
8
|
+
#
|
9
|
+
# ######################################################################## #
|
10
|
+
|
11
|
+
|
12
|
+
# ##########################################################################
|
13
|
+
# requires
|
14
|
+
|
15
|
+
require 'razor_risk/cassini/applications/rest_framework/verb_handler'
|
16
|
+
require 'razor_risk/cassini/applications/route_verb_adaptors/utilities/collection_get_helper'
|
17
|
+
require 'razor_risk/cassini/applications/route_verb_adaptors/utilities/portfolios'
|
18
|
+
|
19
|
+
require 'razor_risk/razor/connectivity/entity_connectors/exceptions'
|
20
|
+
require 'razor_risk/razor/connectivity/razor_3/entity_connectors/portfolios_connector'
|
21
|
+
|
22
|
+
require 'razor_risk/core/diagnostics/logger'
|
23
|
+
|
24
|
+
require 'pantheios'
|
25
|
+
require 'xqsr3/conversion/integer_parser'
|
26
|
+
require 'xmlhasher'
|
27
|
+
|
28
|
+
# ##########################################################################
|
29
|
+
# module
|
30
|
+
|
31
|
+
module RazorRisk
|
32
|
+
module Cassini
|
33
|
+
module Applications
|
34
|
+
module RouteVerbAdaptors
|
35
|
+
module Portfolios
|
36
|
+
|
37
|
+
# ##########################################################################
|
38
|
+
# classes
|
39
|
+
|
40
|
+
class CollectionGet < RESTFramework::VerbHandler
|
41
|
+
|
42
|
+
include ::RazorRisk::Cassini::Applications::RouteVerbAdaptors::Utilities::CollectionGetHelper
|
43
|
+
include ::RazorRisk::Cassini::Applications::RouteVerbAdaptors::Utilities::Portfolios
|
44
|
+
|
45
|
+
include ::RazorRisk::Razor::Connectivity::EntityConnectors::Exceptions
|
46
|
+
include ::RazorRisk::Razor::Connectivity::Razor3::EntityConnectors
|
47
|
+
|
48
|
+
include ::Pantheios
|
49
|
+
include ::RazorRisk::Core::Diagnostics::Logger
|
50
|
+
|
51
|
+
HTTP_VERB = :get
|
52
|
+
|
53
|
+
HTTP_ACCEPTS = %w{ application/xml application/json text/xml }
|
54
|
+
|
55
|
+
QUERY_PARAMETERS = %w{
|
56
|
+
|
57
|
+
filter-name
|
58
|
+
|
59
|
+
page-base
|
60
|
+
page-extent
|
61
|
+
|
62
|
+
quick-search
|
63
|
+
|
64
|
+
key-search
|
65
|
+
|
66
|
+
linked-to-trade
|
67
|
+
}
|
68
|
+
|
69
|
+
def handle env, params, request, response
|
70
|
+
|
71
|
+
trace ParamNames[ :env, :params, :request, :response ], env, params, request, response
|
72
|
+
|
73
|
+
# params
|
74
|
+
|
75
|
+
filter_name = params['filter-name'].to_s.strip
|
76
|
+
filter_name = nil if filter_name.empty?
|
77
|
+
page_base = ::Xqsr3::Conversion::IntegerParser.to_integer(params['page-base'] || 0) { |x, arg|
|
78
|
+
halt 422, {}, "invalid page specifier: 'page-base'=#{arg}"
|
79
|
+
}
|
80
|
+
page_extent = ::Xqsr3::Conversion::IntegerParser.to_integer(params['page-extent'] || 1000) { |x, arg|
|
81
|
+
halt 422, {}, "invalid page specifier: 'page-extent'=#{arg}"
|
82
|
+
}
|
83
|
+
quick_search = params['quick-search']
|
84
|
+
quick_search = nil if String === quick_search && quick_search.strip.empty?
|
85
|
+
key_search = params['key-search']
|
86
|
+
key_search = nil if String === key_search && key_search.strip.empty?
|
87
|
+
linked_to_trade = params['linked-to-trade'].to_s.strip
|
88
|
+
linked_to_trade = nil if linked_to_trade.empty?
|
89
|
+
|
90
|
+
rf = case rf = (params['result-form'] || '').to_s
|
91
|
+
when '', 'default'
|
92
|
+
:body
|
93
|
+
when 'children'
|
94
|
+
:array
|
95
|
+
else
|
96
|
+
log(:warning) { "unrecognised result-form '#{rf}'" }
|
97
|
+
:body
|
98
|
+
end
|
99
|
+
|
100
|
+
if page_base < 0 || page_extent < 1
|
101
|
+
|
102
|
+
halt 416, {}, "invalid page specifier: 'page-base'=#{page_base}; 'page-extent'=#{page_extent}"
|
103
|
+
end
|
104
|
+
|
105
|
+
if filter_name and quick_search
|
106
|
+
|
107
|
+
halt 422, {}, "invalid search specifier: cannot specify 'filter-name' and 'quick-search' together"
|
108
|
+
end
|
109
|
+
|
110
|
+
if key_search
|
111
|
+
begin
|
112
|
+
key_search = MultiValueConjunctionParser.new.parse_conjunction_list key_search
|
113
|
+
rescue MultiValueConjunctionParser::SyntaxError => x
|
114
|
+
halt 422, {'Content-Type' => 'text/plain'}, x.message
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
rq_opts = {
|
119
|
+
|
120
|
+
:filter_name => filter_name,
|
121
|
+
:page_base => page_base,
|
122
|
+
:page_extent => page_extent,
|
123
|
+
:quick_search => quick_search,
|
124
|
+
:key_search => key_search,
|
125
|
+
:linked_to_trade => linked_to_trade,
|
126
|
+
}
|
127
|
+
|
128
|
+
# get credentials
|
129
|
+
|
130
|
+
cr = get_required_credentials
|
131
|
+
|
132
|
+
# get requester
|
133
|
+
|
134
|
+
rr = settings.razor_requester
|
135
|
+
|
136
|
+
# get connector
|
137
|
+
|
138
|
+
ec = PortfoliosConnector.new(rr, credentials: cr, **rq_opts)
|
139
|
+
|
140
|
+
# issue request
|
141
|
+
|
142
|
+
begin
|
143
|
+
|
144
|
+
qr = ec.get_portfolios indicate_result_by: :qualified_result, result_form: rf
|
145
|
+
rescue EntityConnectorInternalStepException => x
|
146
|
+
|
147
|
+
log :failure, "exception (#{x.class}): #{x}"
|
148
|
+
|
149
|
+
headers = {
|
150
|
+
|
151
|
+
'Content-Type' => 'text/plain',
|
152
|
+
}
|
153
|
+
|
154
|
+
code = 500
|
155
|
+
msg = x.message
|
156
|
+
|
157
|
+
halt(code, headers, msg)
|
158
|
+
end
|
159
|
+
|
160
|
+
log :debug1, "qr(#{qr.class})='#{qr}'"
|
161
|
+
|
162
|
+
unless qr.succeeded?
|
163
|
+
|
164
|
+
if false
|
165
|
+
|
166
|
+
;
|
167
|
+
elsif :no_such_filter == qr.result
|
168
|
+
|
169
|
+
log :debug1, "failed to retrieve portfolios: no such filter '#{filter_name}'"
|
170
|
+
|
171
|
+
halt 422, {}, "no such filter '#{filter_name}'"
|
172
|
+
elsif r = qr.failure_qualifier.reasons.lookup?('RZ0011')
|
173
|
+
|
174
|
+
log :debug1, 'failed to retrieve portfolios'
|
175
|
+
|
176
|
+
halt 404, {}, "#{r.message}: #{r.details}"
|
177
|
+
else
|
178
|
+
|
179
|
+
log :warning, 'failed to retrieve portfolios'
|
180
|
+
|
181
|
+
halt 500, {}, qr.failure_qualifier.reasons.join("\n")
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
r = case rf
|
186
|
+
when :array
|
187
|
+
|
188
|
+
xml_doc = ::Nokogiri.XML('<body/>')
|
189
|
+
root_node = xml_doc.children.first
|
190
|
+
|
191
|
+
qr.result.each do |pf_element|
|
192
|
+
|
193
|
+
root_node.add_child pf_element.to_s
|
194
|
+
end
|
195
|
+
|
196
|
+
xml_doc.to_s
|
197
|
+
else
|
198
|
+
|
199
|
+
qr.result.to_s
|
200
|
+
end
|
201
|
+
|
202
|
+
# return result
|
203
|
+
|
204
|
+
status 200
|
205
|
+
|
206
|
+
if false
|
207
|
+
elsif request.accept?('application/xml')
|
208
|
+
|
209
|
+
log :debug1, 'application/xml'
|
210
|
+
|
211
|
+
content_type 'application/xml'
|
212
|
+
|
213
|
+
r
|
214
|
+
elsif request.accept?('application/json')
|
215
|
+
|
216
|
+
log :debug1, 'application/json'
|
217
|
+
|
218
|
+
content_type 'application/json'
|
219
|
+
|
220
|
+
resp_hash = XmlHasher.parse(r)
|
221
|
+
|
222
|
+
#resp_hash = Hash.from_xml r
|
223
|
+
resp_json = resp_hash
|
224
|
+
|
225
|
+
JSON.generate resp_json
|
226
|
+
elsif request.accept?('text/xml')
|
227
|
+
|
228
|
+
log :debug1, 'text/xml'
|
229
|
+
|
230
|
+
content_type 'text/xml'
|
231
|
+
|
232
|
+
r
|
233
|
+
else
|
234
|
+
|
235
|
+
log :violation, "unexpected failure to match given 'Accept' header '#{request.accept}'"
|
236
|
+
|
237
|
+
status 500
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end # class CollectionGet
|
241
|
+
|
242
|
+
# ##########################################################################
|
243
|
+
# module
|
244
|
+
|
245
|
+
end # module Portfolios
|
246
|
+
end # module RouteVerbAdaptors
|
247
|
+
end # module Applications
|
248
|
+
end # module Cassini
|
249
|
+
end # module RazorRisk
|
250
|
+
|
251
|
+
# ############################## end of file ############################# #
|
252
|
+
|
253
|
+
|