rule_engine_client 0.1.12 → 0.1.15

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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rule_engine_client.rb +161 -132
  3. metadata +5 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d27373373d63062d4e321ae93cc1fdaf9bc73a40f146abe7aece2cb83f3e2be5
4
- data.tar.gz: f00cdf230eaafba55cf74e6d0879c689bd4bbdd3e70f106ea8d14361d49f74ce
3
+ metadata.gz: 43f25de086c6b5cc8a77bb6c456e8f6d9a00a2648608ba8480289af653522590
4
+ data.tar.gz: a8bd4f5f717195d9f89a06c5ba4c9e4d4f854160af4ac13e8ac56e175fa20b92
5
5
  SHA512:
6
- metadata.gz: d2b034aa852ffc8d54b227cd48fd00ddecdb05ede88cc79f41671b1ef39dfe0478d7d5f59f2d24d7a7193d6211109bcea581a577751259c3a0b9237655a979bb
7
- data.tar.gz: 54e3c4104a48073c822ba807c4e53743f388da0e2496a1534a006d0b0c0682d10cdf99903dd305717f33f319afeafc4a31f1e52c00ed4db4cc5dbe7b6f01f17b
6
+ metadata.gz: 886543fd56e1aeb6d4d4f40c2e94c2f6635a45d755b32e7c4bed3e77c28cccd7a2e190417c79211a041a7fa00dfa66d4f24b7a57479410575908f04e01b8ee69
7
+ data.tar.gz: fd0a3f8011a6952bea2593d28b7c4d73d5e16408acd8ddcffc68456405b058d66d9970b8bdf4fddee0862416cf651ef0792539f60064d8d72cb5d71eea2a8f8d
@@ -1,132 +1,161 @@
1
- require 'net/http'
2
- require 'json'
3
- require 'logger'
4
- require 'timeout'
5
-
6
- # rule engine client class
7
- class RuleEngineClient
8
- def initialize(server = 'http://localhost:8088', request_timeout_in_s = 5, verbose = false)
9
- @server = server
10
- @verbose = verbose
11
- @logger = Logger.new($stdout)
12
- @request_timeout_in_s = request_timeout_in_s
13
- log("'#{server}' client is initialized")
14
- end
15
-
16
- def evaluate(engine, params, mode = 'production')
17
- url = URI.parse("#{@server}/run?e=#{engine}&m=#{mode}")
18
- log("params #{params}")
19
- params = params_mapper(params, engine)
20
- @result = create_request(url, 'POST', params)
21
- response = response_builder
22
- log("response #{response}")
23
- response
24
- end
25
-
26
- def engine_exists(engine)
27
- log("checking if engine (#{engine}) exists")
28
- response = export_engine(engine)
29
- response['body'] = {
30
- 'exists' => !response['body'].empty?
31
- }
32
- response
33
- end
34
-
35
- def get_engine_models(engine)
36
- log("get engine (#{engine}) models")
37
- response = export_engine(engine)
38
- models = response['body']['model']
39
- log("models #{models}")
40
- models
41
- end
42
-
43
- def params_mapper(params, engine)
44
- models = get_engine_models(engine)
45
- models_keys = models.keys
46
- params_keys = params.keys
47
- params_keys.each do |key|
48
- if models_keys.include? key
49
- props = models[key]['properties'].map do |prop|
50
- prop['name']
51
- end
52
- params[key].keys.each do |el|
53
- params[key].delete(el) unless props.include? el
54
- end
55
- else
56
- params.delete(key)
57
- end
58
- end
59
- log("filtered params #{params}")
60
- params
61
- end
62
-
63
- private
64
-
65
- def log(message)
66
- @logger.debug("rule engine: #{message}") if @verbose
67
- end
68
-
69
- def valid_json?(obj)
70
- !!JSON.parse(obj)
71
- rescue StandardError
72
- false
73
- end
74
-
75
- def response_hash(code, body, errors)
76
- {
77
- 'code' => code,
78
- 'body' => body,
79
- 'errors' => errors
80
- }
81
- end
82
-
83
- def response_builder
84
- if @time_out
85
- errors = ['HTTP Gateway timeout!']
86
- body = {}
87
- code = 504
88
- elsif @result.code == '502'
89
- errors = ['rule engine server down']
90
- body = {}
91
- code = @result.code
92
- elsif !valid_json?(@result.body)
93
- errors = ['could not parse response body to JSON']
94
- body = {}
95
- code = 500
96
- else
97
- body = JSON.parse(@result.body)
98
- errors = body['errors'] || []
99
- body = body.except('errors', 'status')
100
- code = @result.code
101
- end
102
- response_hash(code, body, errors)
103
- end
104
-
105
- def create_request(url, request_type, params = {})
106
- Timeout.timeout(@request_timeout_in_s) do
107
- http = Net::HTTP.new(url.host, url.port)
108
- http.use_ssl = true if url.instance_of? URI::HTTPS
109
- if request_type == 'GET'
110
- log("Will send get request: #{url}")
111
- request = Net::HTTP::Get.new(url.request_uri)
112
- else
113
- log("Will send post request: #{url}")
114
- request = Net::HTTP::Post.new(url.request_uri)
115
- request.body = params.to_json
116
- log("request body created #{request.body} ")
117
- end
118
- request['Content-Type'] = 'application/json'
119
- request['Accept'] = 'application/json'
120
- http.request(request)
121
- end
122
- rescue Timeout::Error
123
- log('HTTP Gateway timeout!')
124
- @time_out = true
125
- end
126
-
127
- def export_engine(engine)
128
- url = URI.parse("#{@server}/engine/export?e=#{engine}")
129
- @result = create_request(url, 'GET')
130
- response_builder
131
- end
132
- end
1
+ require 'net/http'
2
+ require 'json'
3
+ require 'logger'
4
+ require 'timeout'
5
+ require 'digest/md5'
6
+
7
+ # rule engine client class
8
+ class RuleEngineClient
9
+ def initialize(server = 'http://localhost:8088', request_timeout_in_s = 5, verbose = false)
10
+ @server = server
11
+ @verbose = verbose
12
+ @logger = Logger.new($stdout)
13
+ @request_timeout_in_s = request_timeout_in_s
14
+ log("'#{server}' client is initialized")
15
+ end
16
+
17
+ def evaluate(engine, params, mode = 'production')
18
+ url = URI.parse("#{@server}/run?e=#{engine}&m=#{mode}")
19
+ log("params #{params}")
20
+ params = params_mapper(params, engine)
21
+ @result = create_request(url, 'POST', params)
22
+ response = response_builder
23
+ log("response #{response}")
24
+ response
25
+ end
26
+
27
+ def engine_exists(engine)
28
+ log("checking if engine (#{engine}) exists")
29
+ response = export_engine(engine)
30
+ response['body'] = {
31
+ 'exists' => !response['body'].empty?
32
+ }
33
+ response
34
+ end
35
+
36
+ def get_engine_models(engine)
37
+ response = export_engine(engine)
38
+ models = !response['body'].empty? ? response['body']['model'] : {}
39
+ models_keys = models.keys
40
+ models_keys.each do |key|
41
+ get_nested_object(models, models[key]['properties'])
42
+ end
43
+ models
44
+ end
45
+
46
+ def get_nested_object(models, props)
47
+ props.each do |prop|
48
+ if prop['typeconcept'] && (prop['typeconcept'].is_a? String)
49
+ prop['typeconcept'] = models[prop['typeconcept']]
50
+ prop['typeconcept']['properties'] = get_nested_object(models, prop['typeconcept']['properties'])
51
+ end
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ def log(message)
58
+ @logger.debug("rule engine: #{message}") if @verbose
59
+ end
60
+
61
+ def valid_json?(obj)
62
+ !!JSON.parse(obj)
63
+ rescue StandardError
64
+ false
65
+ end
66
+
67
+ def response_hash(code, body, errors)
68
+ {
69
+ 'code' => code,
70
+ 'body' => body,
71
+ 'errors' => errors
72
+ }
73
+ end
74
+
75
+ def response_builder
76
+ if @time_out
77
+ errors = ['HTTP Gateway timeout!']
78
+ body = {}
79
+ code = 504
80
+ elsif @result.code == '502'
81
+ errors = ['rule engine server down']
82
+ body = {}
83
+ code = @result.code
84
+ elsif !valid_json?(@result.body)
85
+ errors = ['could not parse response body to JSON']
86
+ body = {}
87
+ code = 500
88
+ else
89
+ body = JSON.parse(@result.body)
90
+ errors = body['errors'] || []
91
+ body = body.except('errors', 'status')
92
+ code = @result.code
93
+ end
94
+ response_hash(code, body, errors)
95
+ end
96
+
97
+ def create_request(url, request_type, params = {})
98
+ Timeout.timeout(@request_timeout_in_s) do
99
+ http = Net::HTTP.new(url.host, url.port)
100
+ http.use_ssl = true if url.instance_of? URI::HTTPS
101
+ if request_type == 'GET'
102
+ log("Will send get request: #{url}")
103
+ request = Net::HTTP::Get.new(url.request_uri)
104
+ else
105
+ log("Will send post request: #{url}")
106
+ request = Net::HTTP::Post.new(url.request_uri)
107
+ request.body = params.to_json
108
+ log("request body created #{request.body} ")
109
+ end
110
+ # request.basic_auth(@user_name, @password)
111
+ request['Content-Type'] = 'application/json'
112
+ request['Accept'] = 'application/json'
113
+ http.request(request)
114
+ end
115
+ rescue Timeout::Error
116
+ log('HTTP Gateway timeout!')
117
+ @time_out = true
118
+ end
119
+
120
+ def export_engine(engine)
121
+ url = URI.parse("#{@server}/engine/export?e=#{engine}")
122
+ @result = create_request(url, 'GET')
123
+ response_builder
124
+ end
125
+
126
+ def params_mapper(params, engine)
127
+ @models = get_engine_models(engine)
128
+ @models_keys = @models.keys
129
+ params_keys = params.keys
130
+ params_keys.each do |key|
131
+ if !@models_keys.include? key
132
+ params.delete(key)
133
+ else
134
+ props = @models[key]['properties'].map do |prop|
135
+ prop['name']
136
+ end
137
+ filter_nested_params(params, key, props)
138
+ end
139
+ end
140
+ log("filtered params #{params}")
141
+ params
142
+ end
143
+
144
+ def filter_nested_params(params, key, props)
145
+ keys = params[key].keys
146
+ keys.each do |el|
147
+ if !props.include? el
148
+ params[key].delete(el)
149
+ elsif params[key][el].is_a? Hash
150
+ nested_el = @models[key]['properties'].find { |obj| obj['name'] == el }
151
+ if nested_el['datatype'] != 'object'
152
+ params[key].delete(el)
153
+ elsif nested_el && !nested_el['typeconcept']['any']
154
+ el_props = nested_el['typeconcept']['properties']
155
+ filter_nested_params(params[key], el, el_props) if el_props.length
156
+ end
157
+ end
158
+ end
159
+ params
160
+ end
161
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rule_engine_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.12
4
+ version: 0.1.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Areej Nour
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-18 00:00:00.000000000 Z
11
+ date: 2023-01-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: integration with rule server
14
14
  email:
@@ -23,7 +23,7 @@ licenses:
23
23
  - MIT
24
24
  metadata:
25
25
  homepage_uri: https://rubygems.org/gems/rule_engine_client
26
- post_install_message:
26
+ post_install_message:
27
27
  rdoc_options: []
28
28
  require_paths:
29
29
  - lib
@@ -39,7 +39,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
39
39
  version: '0'
40
40
  requirements: []
41
41
  rubygems_version: 3.3.7
42
- signing_key:
42
+ signing_key:
43
43
  specification_version: 4
44
44
  summary: Rule Engine Client
45
45
  test_files: []