restful-trades 0.8.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,266 @@
1
+ # encoding: UTF-8
2
+
3
+ # ######################################################################## #
4
+ # File: razor_risk/cassini/applications/route_verb_adaptors/trades/collection_get.rb
5
+ #
6
+ # Purpose: Adaptor for Trades microservice's collection GET verb
7
+ #
8
+ # Author: Matthew Wilson
9
+ #
10
+ # Copyright (c) 2018, Razor Risk Technologies Pty Ltd
11
+ # All rights reserved.
12
+ #
13
+ # ######################################################################## #
14
+
15
+
16
+ # ##########################################################################
17
+ # requires
18
+
19
+ require 'razor_risk/cassini/applications/rest_framework/verb_handler'
20
+ require 'razor_risk/cassini/applications/route_verb_adaptors/utilities/collection_get_helper'
21
+
22
+ require 'razor_risk/razor/connectivity/razor_3/entity_connectors/trades_connector'
23
+ require 'razor_risk/razor/connectivity/search/parsers/multi_value_conjunction_parser'
24
+
25
+ require 'razor_risk/core/diagnostics/logger'
26
+
27
+ require 'pantheios'
28
+ require 'xqsr3/conversion/integer_parser'
29
+
30
+ require 'xmlhasher'
31
+
32
+ # ##########################################################################
33
+ # module
34
+
35
+ module RazorRisk
36
+ module Cassini
37
+ module Applications
38
+ module RouteVerbAdaptors
39
+ module Trades
40
+
41
+ # ##########################################################################
42
+ # classes
43
+
44
+ class CollectionGet < RESTFramework::VerbHandler
45
+
46
+ include ::RazorRisk::Cassini::Applications::RouteVerbAdaptors::Utilities::CollectionGetHelper
47
+
48
+ include ::RazorRisk::Razor::Connectivity::EntityConnectors::Exceptions
49
+ include ::RazorRisk::Razor::Connectivity::Razor3::EntityConnectors
50
+ include ::RazorRisk::Razor::Connectivity::Search::Parsers
51
+
52
+ include ::RazorRisk::Core::Diagnostics::Logger
53
+
54
+ include ::Pantheios
55
+
56
+ HTTP_VERB = :get
57
+
58
+ HTTP_ACCEPTS = %w{ application/xml application/json text/xml }
59
+
60
+ QUERY_PARAMETERS = %w{
61
+
62
+ field-search
63
+
64
+ filter-name
65
+
66
+ page-base
67
+ page-extent
68
+
69
+ result-form
70
+
71
+ sort-field
72
+ sort-direction
73
+
74
+ linked-to-portfolio
75
+ }
76
+
77
+ def handle env, params, request, response
78
+
79
+ trace ParamNames[ :env, :params, :request, :response ], env, params, request, response
80
+
81
+ # params
82
+
83
+ validate_exclusive_search_parameters params, 'filter-name', 'field-search', message_scope: 'invalid search specifier'
84
+
85
+ field_srch = params['field-search'].to_s.strip
86
+ field_srch = nil if field_srch.empty?
87
+ filter_name = params['filter-name'].to_s.strip
88
+ filter_name = nil if filter_name.empty?
89
+ page_base = ::Xqsr3::Conversion::IntegerParser.to_integer(params['page-base'] || 0) { |x, arg| halt *[ 422, {}, "invalid page specifier: 'page-base'=#{arg}" ] }
90
+ page_extent = ::Xqsr3::Conversion::IntegerParser.to_integer(params['page-extent'] || 1000) { |x, arg| halt *[ 422, {}, "invalid page specifier: 'page-extent'=#{arg}" ] }
91
+ sort_field = params['sort-field'].to_s.strip
92
+ sort_field = nil if sort_field.empty?
93
+ sort_direction = params['sort-direction'].to_s.strip
94
+ sort_direction = nil if sort_direction.empty?
95
+ linked_to_portfolio = params['linked-to-portfolio']
96
+ linked_to_portfolio = ::Xqsr3::Conversion::IntegerParser.to_integer(params['linked-to-portfolio']) { |x, arg| halt *[ 422, {}, "invalid Trade ID: 'linked-to-portfolio'=#{arg}" ] } unless linked_to_portfolio.nil?
97
+
98
+ rf = case rf = (params['result-form'] || '').to_s
99
+ when '', 'default'
100
+ :body
101
+ when 'children'
102
+ :array
103
+ else
104
+ log(:warning) { "unrecognised result-form '#{rf}'" }
105
+ :body
106
+ end
107
+
108
+ if page_base < 0 || page_extent < 1
109
+
110
+ halt *[ 416, {}, "invalid page specifier: 'page-base'=#{page_base}; 'page-extent'=#{page_extent}" ]
111
+ end
112
+
113
+ unless sort_direction.nil? || sort_direction =~ /ascending|descending/i
114
+
115
+ halt *[ 422, {}, "sort-direction must be 'ascending' or 'descending'" ]
116
+ end
117
+
118
+ if field_srch
119
+ begin
120
+ cp = MultiValueConjunctionParser.new
121
+ field_srch = cp.parse_conjunction_list field_srch
122
+ unless field_srch.keys.all? { |k| k.is_a? ::String }
123
+ halt 422, {'Content-Type' => 'text/plain'}, 'Field Search does not support key paths'
124
+ end
125
+ rescue MultiValueConjunctionParser::SyntaxError => x
126
+ halt 422, {'Content-Type' => 'text/plain'}, x.message
127
+ end
128
+ end
129
+
130
+ rq_opts = {
131
+
132
+ :field_search => field_srch,
133
+ :filter_name => filter_name,
134
+ :page_base => page_base,
135
+ :page_extent => page_extent,
136
+ :sort_field => sort_field,
137
+ :sort_direction => sort_direction,
138
+ :linked_to_portfolio => linked_to_portfolio,
139
+ }
140
+
141
+ # get credentials
142
+
143
+ cr = get_required_credentials
144
+
145
+ # get requester
146
+
147
+ rr = settings.razor_requester
148
+
149
+ # get connector
150
+
151
+ ec = TradesConnector.new(rr, credentials: cr, **rq_opts)
152
+
153
+ # issue request
154
+
155
+ begin
156
+
157
+ qr = ec.get_trades indicate_result_by: :qualified_result, result_form: rf
158
+ rescue EntityConnectorInternalStepException => x
159
+
160
+ log :failure, "exception (#{x.class}): #{x}"
161
+
162
+ headers = {
163
+
164
+ 'Content-Type' => 'text/plain',
165
+ }
166
+
167
+ code = 500
168
+ msg = x.message
169
+
170
+ halt(code, headers, msg)
171
+ end
172
+
173
+ log :debug1, "qr(#{qr.class})='#{qr}'"
174
+
175
+ unless qr.succeeded?
176
+
177
+ if false
178
+
179
+ ;
180
+ elsif :no_such_filter == qr.result
181
+
182
+ log :debug1, "failed to retrieve trades: no such filter '#{filter_name}'"
183
+
184
+ halt *[ 422, {}, "no such filter '#{filter_name}'" ]
185
+ elsif r = qr.failure_qualifier.reasons.lookup?('RZ0011')
186
+
187
+ log :debug1, 'failed to retrieve trades'
188
+
189
+ halt *[ 404, {}, "#{r.message}: #{r.details}" ]
190
+ else
191
+
192
+ log :warning, 'failed to retrieve trades'
193
+
194
+ halt *[ 500, {}, qr.failure_qualifier.reasons.join("\n") ]
195
+ end
196
+ end
197
+
198
+ r = case rf
199
+ when :array
200
+
201
+ xml_doc = ::Nokogiri.XML('<body/>')
202
+ root_node = xml_doc.children.first
203
+
204
+ qr.result.each do |pf_element|
205
+
206
+ root_node.add_child pf_element.to_s
207
+ end
208
+
209
+ xml_doc.to_s
210
+ else
211
+
212
+ qr.result.to_s
213
+ end
214
+
215
+ # return result
216
+
217
+ status 200
218
+
219
+ if false
220
+ elsif request.accept?('application/xml')
221
+
222
+ log :debug1, 'application/xml'
223
+
224
+ content_type 'application/xml'
225
+
226
+ r
227
+ elsif request.accept?('application/json')
228
+
229
+ log :debug1, 'application/json'
230
+
231
+ content_type 'application/json'
232
+
233
+ #resp_hash = Hash.from_xml r
234
+ resp_hash = XmlHasher.parse(r)
235
+
236
+ resp_json = resp_hash
237
+
238
+ JSON.generate resp_json
239
+ elsif request.accept?('text/xml')
240
+
241
+ log :debug1, 'text/xml'
242
+
243
+ content_type 'text/xml'
244
+
245
+ r
246
+ else
247
+
248
+ log :violation, "unexpected failure to match given 'Accept' header '#{request.accept}'"
249
+
250
+ status 500
251
+ end
252
+ end
253
+ end # class CollectionGet
254
+
255
+ # ##########################################################################
256
+ # module
257
+
258
+ end # module Trades
259
+ end # module RouteVerbAdaptors
260
+ end # module Applications
261
+ end # module Cassini
262
+ end # module RazorRisk
263
+
264
+ # ############################## end of file ############################# #
265
+
266
+
@@ -0,0 +1,204 @@
1
+ # encoding: UTF-8
2
+
3
+ # ######################################################################## #
4
+ # File: razor_risk/cassini/applications/route_verb_adaptors/trades/collection_get.rb
5
+ #
6
+ # Purpose: Adaptor for Trades microservice's collection GET verb
7
+ #
8
+ # Author: Matthew Wilson
9
+ #
10
+ # Copyright (c) 2018, Razor Risk Technologies Pty Ltd
11
+ # All rights reserved.
12
+ #
13
+ # ######################################################################## #
14
+
15
+
16
+ # ##########################################################################
17
+ # requires
18
+
19
+ require 'razor_risk/cassini/applications/rest_framework/verb_handler'
20
+ require 'razor_risk/cassini/applications/route_verb_adaptors/utilities/collection_get_helper'
21
+
22
+ require 'razor_risk/razor/connectivity/razor_3/entity_connectors/trades_connector'
23
+ require 'razor_risk/razor/connectivity/search/parsers/multi_value_conjunction_parser'
24
+
25
+ require 'razor_risk/core/diagnostics/logger'
26
+
27
+ require 'pantheios'
28
+ require 'xqsr3/conversion/integer_parser'
29
+
30
+ require 'xmlhasher'
31
+
32
+ # ##########################################################################
33
+ # module
34
+
35
+ module RazorRisk
36
+ module Cassini
37
+ module Applications
38
+ module RouteVerbAdaptors
39
+ module Trades
40
+
41
+ # ##########################################################################
42
+ # classes
43
+
44
+ class CollectionPost < RESTFramework::VerbHandler
45
+
46
+ include ::RazorRisk::Cassini::Applications::RouteVerbAdaptors::Utilities::CollectionGetHelper
47
+
48
+ include ::RazorRisk::Razor::Connectivity::EntityConnectors::Exceptions
49
+ include ::RazorRisk::Razor::Connectivity::Razor3::EntityConnectors
50
+ include ::RazorRisk::Razor::Connectivity::Search::Parsers
51
+
52
+ include ::RazorRisk::Core::Diagnostics::Logger
53
+
54
+ include ::Pantheios
55
+
56
+ HTTP_VERB = :post
57
+
58
+ HTTP_ACCEPTS = %w{ application/xml application/json text/xml }
59
+
60
+ QUERY_PARAMETERS = %w{
61
+ }
62
+
63
+ def handle env, params, request, response
64
+
65
+ trace ParamNames[ :env, :params, :request, :response ], env, params, request, response
66
+
67
+ # params
68
+ request.body.rewind
69
+
70
+ rf = :body
71
+ body_text = request.body.read
72
+
73
+ # print("body_text #{body_text}")
74
+
75
+ rq_opts = {
76
+ :body_text => body_text,
77
+ }
78
+
79
+ # get credentials
80
+
81
+ cr = get_required_credentials
82
+
83
+ # get requester
84
+
85
+ rr = settings.razor_requester
86
+
87
+ # get connector
88
+
89
+ ec = TradesConnector.new(rr, credentials: cr, **rq_opts)
90
+
91
+ # issue request
92
+
93
+ begin
94
+
95
+ qr = ec.get_trades_contribution body_text, indicate_result_by: :qualified_result, result_form: rf
96
+ rescue EntityConnectorInternalStepException => x
97
+
98
+ log :failure, "exception (#{x.class}): #{x}"
99
+
100
+ headers = {
101
+
102
+ 'Content-Type' => 'text/plain',
103
+ }
104
+
105
+ code = 500
106
+ msg = x.message
107
+
108
+ halt(code, headers, msg)
109
+ end
110
+
111
+ log :debug1, "qr(#{qr.class})='#{qr}'"
112
+
113
+ unless qr.succeeded?
114
+
115
+ if false
116
+
117
+ ;
118
+ elsif :no_such_filter == qr.result
119
+
120
+ log :debug1, "failed to retrieve trades: no such filter '#{filter_name}'"
121
+
122
+ halt *[ 422, {}, "no such filter '#{filter_name}'" ]
123
+ elsif r = qr.failure_qualifier.reasons.lookup?('RZ0011')
124
+
125
+ log :debug1, 'failed to retrieve trades'
126
+
127
+ halt *[ 404, {}, "#{r.message}: #{r.details}" ]
128
+ else
129
+
130
+ log :warning, 'failed to retrieve trades'
131
+
132
+ halt *[ 500, {}, qr.failure_qualifier.reasons.join("\n") ]
133
+ end
134
+ end
135
+
136
+ r = case rf
137
+ when :array
138
+
139
+ xml_doc = ::Nokogiri.XML('<body/>')
140
+ root_node = xml_doc.children.first
141
+
142
+ qr.result.each do |pf_element|
143
+
144
+ root_node.add_child pf_element.to_s
145
+ end
146
+
147
+ xml_doc.to_s
148
+ else
149
+
150
+ qr.result.to_s
151
+ end
152
+
153
+ # return result
154
+
155
+ status 200
156
+
157
+ if false
158
+ elsif request.accept?('application/xml')
159
+
160
+ log :debug1, 'application/xml'
161
+
162
+ content_type 'application/xml'
163
+
164
+ r
165
+ elsif request.accept?('application/json')
166
+
167
+ log :debug1, 'application/json'
168
+
169
+ content_type 'application/json'
170
+
171
+ #resp_hash = Hash.from_xml r
172
+ resp_hash = XmlHasher.parse(r)
173
+
174
+ resp_json = resp_hash
175
+
176
+ JSON.generate resp_json
177
+ elsif request.accept?('text/xml')
178
+
179
+ log :debug1, 'text/xml'
180
+
181
+ content_type 'text/xml'
182
+
183
+ r
184
+ else
185
+
186
+ log :violation, "unexpected failure to match given 'Accept' header '#{request.accept}'"
187
+
188
+ status 500
189
+ end
190
+ end
191
+ end # class CollectionGet
192
+
193
+ # ##########################################################################
194
+ # module
195
+
196
+ end # module Trades
197
+ end # module RouteVerbAdaptors
198
+ end # module Applications
199
+ end # module Cassini
200
+ end # module RazorRisk
201
+
202
+ # ############################## end of file ############################# #
203
+
204
+
@@ -0,0 +1,182 @@
1
+ # encoding: UTF-8
2
+
3
+ # ######################################################################## #
4
+ # File: razor_risk/cassini/applications/route_verb_adaptors/trades/item_delete.rb
5
+ #
6
+ # Purpose: Adaptor for Trades microservice's item DELETE verb
7
+ #
8
+ # Copyright (c) 2018, Razor Risk Technologies Pty Ltd
9
+ # All rights reserved.
10
+ #
11
+ # ######################################################################## #
12
+
13
+
14
+ # ##########################################################################
15
+ # requires
16
+
17
+ require 'razor_risk/cassini/applications/rest_framework/verb_handler'
18
+
19
+ require 'razor_risk/razor/connectivity/razor_3/entity_connectors/trades_connector'
20
+
21
+ require 'razor_risk/core/diagnostics/logger'
22
+
23
+ require 'pantheios'
24
+
25
+ require 'xqsr3/conversion/integer_parser'
26
+
27
+ # ##########################################################################
28
+ # module
29
+
30
+ module RazorRisk
31
+ module Cassini
32
+ module Applications
33
+ module RouteVerbAdaptors
34
+ module Trades
35
+
36
+ # ##########################################################################
37
+ # classes
38
+
39
+ class ItemDelete < RESTFramework::VerbHandler
40
+
41
+ include ::RazorRisk::Razor::Connectivity::Razor3::EntityConnectors
42
+
43
+ include ::RazorRisk::Core::Diagnostics::Logger
44
+
45
+ include ::Pantheios
46
+
47
+ include ::Xqsr3::Conversion
48
+
49
+ HTTP_VERB = :delete
50
+
51
+ HTTP_ACCEPTS = %w{ application/xml application/json text/xml }
52
+
53
+ ROUTE_VARIABLES = %w{
54
+
55
+ sysId
56
+ }
57
+
58
+ QUERY_PARAMETERS = %w{
59
+
60
+ result-form
61
+ }
62
+
63
+ def handle env, params, request, response
64
+
65
+ trace ParamNames[ :env, :params, :request, :response ], env, params, request, response
66
+
67
+ # params
68
+
69
+ sysId = IntegerParser.to_integer(params['sysId'], allow_nil: true) { halt *[ 422, {}, 'invalid identifier for DELETE verb - must be an integer' ] }
70
+
71
+ rf = case rf = (params['result-form'] || '').to_s
72
+ when '', 'default'
73
+ :default
74
+ when 'body'
75
+ :body
76
+ else
77
+ log(:warning) { "unrecognised result-form '#{rf}'" }
78
+ :default
79
+ end
80
+
81
+ # get credentials
82
+
83
+ cr = get_required_credentials
84
+
85
+ # get requester
86
+
87
+ rr = settings.razor_requester
88
+
89
+ # get connector
90
+
91
+ ec = TradesConnector.new(rr, credentials: cr)
92
+
93
+ # issue request
94
+
95
+ qr = ec.delete_trade sysId, indicate_result_by: :qualified_result, result_form: rf
96
+
97
+ log :debug1, "qr(#{qr.class})='#{qr}'"
98
+
99
+ unless qr.succeeded?
100
+
101
+ if false
102
+
103
+ ;
104
+ elsif qr.result.nil?
105
+
106
+ log :debug1, 'failed to delete trade'
107
+
108
+ halt *[ 404, {}, "trade with sysId '#{sysId}' does not exist" ]
109
+ elsif qr.failure_qualifier.reasons.empty?
110
+
111
+ log :debug1, 'failed to delete trade'
112
+
113
+ halt *[ 404, {}, "trade with sysId '#{sysId}' does not exist" ]
114
+ elsif r = qr.failure_qualifier.reasons.lookup?('RZ0011')
115
+
116
+ log :debug1, 'failed to delete trade'
117
+
118
+ halt *[ 404, {}, "#{r.message}: #{r.details}" ]
119
+ else
120
+
121
+ log :warning, 'failed to delete trade'
122
+
123
+ halt *[ 500, {}, qr.failure_qualifier.reasons.join("\n") ]
124
+ end
125
+ end
126
+
127
+ status 200
128
+
129
+ unless rf == :boolean
130
+
131
+ r = qr.result.to_s
132
+
133
+ # return result
134
+
135
+ if false
136
+ elsif request.accept?('application/xml')
137
+
138
+ log :debug1, 'application/xml'
139
+
140
+ content_type 'application/xml'
141
+
142
+ r
143
+ elsif request.accept?('application/json')
144
+
145
+ log :debug1, 'application/json'
146
+
147
+ content_type 'application/json'
148
+
149
+ resp_hash = Hash.from_xml r
150
+
151
+ resp_json = resp_hash
152
+
153
+ JSON.generate resp_json
154
+ elsif request.accept?('text/xml')
155
+
156
+ log :debug1, 'text/xml'
157
+
158
+ content_type 'text/xml'
159
+
160
+ r
161
+ else
162
+
163
+ log :violation, "unexpected failure to match given 'Accept' header '#{request.accept}'"
164
+
165
+ status 500
166
+ end
167
+ end
168
+ end
169
+ end # class ItemDelete
170
+
171
+ # ##########################################################################
172
+ # module
173
+
174
+ end # module Trades
175
+ end # module RouteVerbAdaptors
176
+ end # module Applications
177
+ end # module Cassini
178
+ end # module RazorRisk
179
+
180
+ # ############################## end of file ############################# #
181
+
182
+