vwo-fme-ruby-sdk 1.0.0 → 1.1.0

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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/lib/vwo/api/get_flag.rb +236 -0
  3. data/lib/vwo/api/set_attribute.rb +57 -0
  4. data/lib/vwo/api/track_event.rb +77 -0
  5. data/lib/vwo/constants/constants.rb +54 -0
  6. data/lib/vwo/decorators/storage_decorator.rb +86 -0
  7. data/lib/vwo/{utils/logger_helper.rb → enums/api_enum.rb} +5 -10
  8. data/lib/vwo/enums/campaign_type_enum.rb +19 -0
  9. data/lib/vwo/enums/decision_types_enum.rb +18 -0
  10. data/lib/vwo/enums/event_enum.rb +19 -0
  11. data/lib/vwo/enums/headers_enum.rb +20 -0
  12. data/lib/vwo/enums/hooks_enum.rb +17 -0
  13. data/lib/vwo/enums/http_method_enum.rb +18 -0
  14. data/lib/vwo/enums/log_level_enum.rb +21 -0
  15. data/lib/vwo/enums/status_enum.rb +19 -0
  16. data/lib/vwo/enums/storage_enum.rb +22 -0
  17. data/lib/vwo/enums/url_enum.rb +21 -0
  18. data/lib/vwo/models/campaign/campaign_model.rb +192 -0
  19. data/lib/vwo/models/campaign/feature_model.rb +111 -0
  20. data/lib/vwo/models/campaign/impact_campaign_model.rb +38 -0
  21. data/lib/vwo/models/campaign/metric_model.rb +44 -0
  22. data/lib/vwo/models/campaign/rule_model.rb +56 -0
  23. data/lib/vwo/models/campaign/variable_model.rb +51 -0
  24. data/lib/vwo/models/campaign/variation_model.rb +137 -0
  25. data/lib/vwo/models/gateway_service_model.rb +39 -0
  26. data/lib/vwo/models/schemas/settings_schema_validation.rb +102 -0
  27. data/lib/vwo/models/settings/settings_model.rb +85 -0
  28. data/lib/vwo/models/storage/storage_data_model.rb +44 -0
  29. data/lib/vwo/models/user/context_model.rb +100 -0
  30. data/lib/vwo/models/user/context_vwo_model.rb +38 -0
  31. data/lib/vwo/{utils/feature_flag_response.rb → models/user/get_flag_response.rb} +14 -14
  32. data/lib/vwo/models/vwo_options_model.rb +107 -0
  33. data/lib/vwo/packages/decision_maker/decision_maker.rb +60 -0
  34. data/lib/vwo/packages/logger/core/log_manager.rb +90 -0
  35. data/lib/vwo/packages/logger/core/transport_manager.rb +87 -0
  36. data/lib/vwo/packages/logger/log_message_builder.rb +70 -0
  37. data/lib/vwo/packages/logger/logger.rb +38 -0
  38. data/lib/vwo/packages/logger/transports/console_transport.rb +49 -0
  39. data/lib/vwo/packages/network_layer/client/network_client.rb +107 -0
  40. data/lib/vwo/packages/network_layer/handlers/request_handler.rb +37 -0
  41. data/lib/vwo/packages/network_layer/manager/network_manager.rb +78 -0
  42. data/lib/vwo/packages/network_layer/models/global_request_model.rb +105 -0
  43. data/lib/vwo/packages/network_layer/models/request_model.rb +145 -0
  44. data/lib/vwo/packages/network_layer/models/response_model.rb +45 -0
  45. data/lib/vwo/packages/segmentation_evaluator/core/segmentation_manager.rb +76 -0
  46. data/lib/vwo/packages/segmentation_evaluator/enums/segment_operand_regex_enum.rb +29 -0
  47. data/lib/vwo/packages/segmentation_evaluator/enums/segment_operand_value_enum.rb +26 -0
  48. data/lib/vwo/packages/segmentation_evaluator/enums/segment_operator_value_enum.rb +30 -0
  49. data/lib/vwo/packages/segmentation_evaluator/evaluators/segment_evaluator.rb +210 -0
  50. data/lib/vwo/packages/segmentation_evaluator/evaluators/segment_operand_evaluator.rb +198 -0
  51. data/lib/vwo/packages/segmentation_evaluator/utils/segment_util.rb +44 -0
  52. data/lib/vwo/{constants.rb → packages/storage/connector.rb} +12 -10
  53. data/lib/vwo/packages/storage/storage.rb +45 -0
  54. data/lib/vwo/services/campaign_decision_service.rb +153 -0
  55. data/lib/vwo/services/hooks_service.rb +51 -0
  56. data/lib/vwo/services/logger_service.rb +83 -0
  57. data/lib/vwo/services/settings_service.rb +120 -0
  58. data/lib/vwo/services/storage_service.rb +65 -0
  59. data/lib/vwo/utils/campaign_util.rb +249 -0
  60. data/lib/vwo/utils/data_type_util.rb +105 -0
  61. data/lib/vwo/utils/decision_util.rb +253 -0
  62. data/lib/vwo/utils/function_util.rb +123 -0
  63. data/lib/vwo/utils/gateway_service_util.rb +101 -0
  64. data/lib/vwo/utils/impression_util.rb +49 -0
  65. data/lib/vwo/utils/log_message_util.rb +42 -0
  66. data/lib/vwo/utils/meg_util.rb +350 -0
  67. data/lib/vwo/utils/network_util.rb +235 -0
  68. data/lib/vwo/utils/rule_evaluation_util.rb +57 -0
  69. data/lib/vwo/utils/settings_util.rb +38 -0
  70. data/lib/vwo/utils/url_util.rb +46 -0
  71. data/lib/vwo/utils/uuid_util.rb +55 -0
  72. data/lib/vwo/vwo_builder.rb +156 -11
  73. data/lib/vwo/vwo_client.rb +163 -113
  74. data/lib/vwo.rb +49 -31
  75. metadata +187 -9
  76. data/lib/vwo/utils/request.rb +0 -89
@@ -0,0 +1,60 @@
1
+ # Copyright 2025 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'murmurhash3'
16
+
17
+ class DecisionMaker
18
+ SEED_VALUE = 1 # Seed value for the hash function
19
+
20
+ # Generates a bucket value based on the hash value, maximum value, and an optional multiplier.
21
+ #
22
+ # @param hash_value [Integer] The hash value used for calculation.
23
+ # @param max_value [Integer] The maximum value for bucket scaling.
24
+ # @param multiplier [Integer] Optional multiplier to adjust the value (default: 1).
25
+ # @return [Integer] The calculated bucket value.
26
+ def generate_bucket_value(hash_value, max_value, multiplier = 1)
27
+ ratio = hash_value.to_f / (2**32)
28
+ multiplied_value = ((max_value * ratio) + 1) * multiplier
29
+ multiplied_value.floor
30
+ end
31
+
32
+ # Gets the bucket value for a user based on the hash key and maximum value.
33
+ #
34
+ # @param hash_key [String] The hash key for the user.
35
+ # @param max_value [Integer] The maximum value for bucket scaling (default: 100).
36
+ # @return [Integer] The calculated bucket value for the user.
37
+ def get_bucket_value_for_user(hash_key, max_value = 100)
38
+ hash_value = MurmurHash3::V32.str_hash(hash_key, SEED_VALUE)
39
+ generate_bucket_value(hash_value, max_value)
40
+ end
41
+
42
+ # Calculates the bucket value for a given string with an optional multiplier and maximum value.
43
+ #
44
+ # @param str [String] The input string to calculate the bucket value for.
45
+ # @param multiplier [Integer] Optional multiplier to adjust the value (default: 1).
46
+ # @param max_value [Integer] The maximum value for bucket scaling (default: 10000).
47
+ # @return [Integer] The calculated bucket value.
48
+ def calculate_bucket_value(str, multiplier = 1, max_value = 10000)
49
+ hash_value = generate_hash_value(str)
50
+ generate_bucket_value(hash_value, max_value, multiplier)
51
+ end
52
+
53
+ # Generates the hash value for a given hash key using MurmurHash v3.
54
+ #
55
+ # @param hash_key [String] The hash key for which the hash value is generated.
56
+ # @return [Integer] The generated hash value.
57
+ def generate_hash_value(hash_key)
58
+ MurmurHash3::V32.str_hash(hash_key, SEED_VALUE)
59
+ end
60
+ end
@@ -0,0 +1,90 @@
1
+ # Copyright 2025 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ # log_manager.rb
16
+ require 'securerandom'
17
+ require_relative '../logger'
18
+ require_relative 'transport_manager'
19
+ require_relative '../transports/console_transport'
20
+
21
+ class LogManager < Logger
22
+ @instance = nil
23
+
24
+ # Use the `instance` method to initialize and get the instance
25
+ def self.instance(config = {})
26
+ # If an instance already exists, return it
27
+ if @instance.nil?
28
+ @instance = new(config)
29
+ end
30
+ @instance
31
+ end
32
+
33
+ def initialize(config = {})
34
+ # Store the config in an instance variable
35
+ @config = config
36
+
37
+ # Initialize default config values inside @config
38
+ @config[:name] ||= 'VWO Logger'
39
+ @config[:request_id] ||= SecureRandom.uuid
40
+ @config[:level] ||= 'ERROR'
41
+ @config[:prefix] ||= 'VWO-SDK'
42
+ @config[:date_time_format] ||= lambda { Time.now.iso8601 }
43
+
44
+ # Initialize the transport manager with the @config hash
45
+ @transport_manager = LogTransportManager.new(@config)
46
+ handle_transports
47
+ end
48
+
49
+ def trace(message)
50
+ @transport_manager.log('TRACE', message)
51
+ end
52
+
53
+ def debug(message)
54
+ @transport_manager.log('DEBUG', message)
55
+ end
56
+
57
+ def info(message)
58
+ @transport_manager.log('INFO', message)
59
+ end
60
+
61
+ def warn(message)
62
+ @transport_manager.log('WARN', message)
63
+ end
64
+
65
+ def error(message)
66
+ @transport_manager.log('ERROR', message)
67
+ end
68
+
69
+ private
70
+
71
+ def handle_transports
72
+ transports = @config[:transports] || []
73
+
74
+ if transports.any?
75
+ add_transports(transports)
76
+ elsif @config[:transport]
77
+ add_transport(@config[:transport])
78
+ else
79
+ add_transport(ConsoleTransport.new(level: @config[:level]))
80
+ end
81
+ end
82
+
83
+ def add_transport(transport)
84
+ @transport_manager.add_transport(transport)
85
+ end
86
+
87
+ def add_transports(transports)
88
+ transports.each { |transport| add_transport(transport) }
89
+ end
90
+ end
@@ -0,0 +1,87 @@
1
+ # Copyright 2025 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative '../log_message_builder'
16
+
17
+ class LogTransportManager
18
+ def initialize(config)
19
+ @transports = []
20
+ @config = config # This should be the global config passed to LogManager
21
+ end
22
+
23
+ def add_transport(transport)
24
+ @transports.push(transport)
25
+ end
26
+
27
+ def should_log?(transport_level, config_level)
28
+ target_level = log_level_to_number(transport_level)
29
+ desired_level = log_level_to_number(config_level || @config[:level])
30
+ target_level >= desired_level
31
+ end
32
+
33
+ def trace(message)
34
+ log('TRACE', message)
35
+ end
36
+
37
+ def debug(message)
38
+ log('DEBUG', message)
39
+ end
40
+
41
+ def info(message)
42
+ log('INFO', message)
43
+ end
44
+
45
+ def warn(message)
46
+ log('WARN', message)
47
+ end
48
+
49
+ def error(message)
50
+ log('ERROR', message)
51
+ end
52
+
53
+ def log(level, message)
54
+ @transports.each do |transport|
55
+ # Pass the global config (from LogManager) to LogMessageBuilder, not the transport
56
+ log_message_builder = LogMessageBuilder.new(@config, transport)
57
+ formatted_message = log_message_builder.format_message(level, message)
58
+
59
+ if should_log?(level, transport.level)
60
+ if transport.respond_to?(:log) && transport.method(:log).arity == 2
61
+ # Use custom log handler if available with correct arity
62
+ transport.log(level, message)
63
+ elsif transport.respond_to?(level.downcase.to_sym)
64
+ # Use level-specific method if available
65
+ transport.send(level.downcase.to_sym, formatted_message)
66
+ else
67
+ # Fallback to console_log
68
+ transport.console_log(level, formatted_message)
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ def log_level_to_number(level)
77
+ {
78
+ 'TRACE' => 0,
79
+ 'DEBUG' => 1,
80
+ 'INFO' => 2,
81
+ 'WARN' => 3,
82
+ 'ERROR' => 4
83
+ }[level.upcase] || 0
84
+ end
85
+ end
86
+
87
+
@@ -0,0 +1,70 @@
1
+ # Copyright 2025 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ class LogMessageBuilder
16
+ ANSI_COLOR_ENUM = {
17
+ bold: "\x1b[1m",
18
+ cyan: "\x1b[36m",
19
+ green: "\x1b[32m",
20
+ lightblue: "\x1b[94m",
21
+ red: "\x1b[31m",
22
+ reset: "\x1b[0m",
23
+ white: "\x1b[30m",
24
+ yellow: "\x1b[33m"
25
+ }
26
+
27
+ LOG_LEVEL_COLOR = {
28
+ 'TRACE' => ANSI_COLOR_ENUM[:white],
29
+ 'DEBUG' => ANSI_COLOR_ENUM[:lightblue],
30
+ 'INFO' => ANSI_COLOR_ENUM[:cyan],
31
+ 'WARN' => ANSI_COLOR_ENUM[:yellow],
32
+ 'ERROR' => ANSI_COLOR_ENUM[:red]
33
+ }
34
+
35
+ def initialize(logger_config, transport_config)
36
+ @logger_config = logger_config
37
+ @transport_config = transport_config
38
+
39
+ # Access the values directly from transport_config if available.
40
+ @prefix = transport_config.instance_variable_get(:@prefix) || logger_config[:prefix] || ''
41
+ @date_time_format = transport_config.respond_to?(:date_time_format) ? transport_config.date_time_format : logger_config[:date_time_format] || lambda { Time.now.iso8601 }
42
+ end
43
+
44
+ def format_message(level, message)
45
+ "[#{get_formatted_level(level)}]: #{get_formatted_prefix(@prefix)} #{get_formatted_date_time} #{message}"
46
+ end
47
+
48
+ private
49
+
50
+ def get_formatted_prefix(prefix)
51
+ if @logger_config[:is_ansi_color_enabled]
52
+ "#{ANSI_COLOR_ENUM[:bold]}#{ANSI_COLOR_ENUM[:green]}#{prefix}#{ANSI_COLOR_ENUM[:reset]}"
53
+ else
54
+ prefix
55
+ end
56
+ end
57
+
58
+ def get_formatted_level(level)
59
+ color = LOG_LEVEL_COLOR[level.upcase] || ''
60
+ level_string = level.upcase
61
+ return "#{color}#{level_string}#{ANSI_COLOR_ENUM[:reset]}" if @logger_config[:is_ansi_color_enabled]
62
+
63
+ level_string
64
+ end
65
+
66
+ def get_formatted_date_time
67
+ @date_time_format.call
68
+ end
69
+ end
70
+
@@ -0,0 +1,38 @@
1
+ # Copyright 2025 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ # logger.rb
16
+ class Logger
17
+ # Abstract method definitions for logging at different levels
18
+ def trace(message)
19
+ raise NotImplementedError, "You must implement the trace method"
20
+ end
21
+
22
+ def debug(message)
23
+ raise NotImplementedError, "You must implement the debug method"
24
+ end
25
+
26
+ def info(message)
27
+ raise NotImplementedError, "You must implement the info method"
28
+ end
29
+
30
+ def warn(message)
31
+ raise NotImplementedError, "You must implement the warn method"
32
+ end
33
+
34
+ def error(message)
35
+ raise NotImplementedError, "You must implement the error method"
36
+ end
37
+ end
38
+
@@ -0,0 +1,49 @@
1
+ # Copyright 2025 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ class ConsoleTransport
16
+ attr_reader :level, :prefix
17
+
18
+ def initialize(config = {})
19
+ @config = config
20
+ @level = @config[:level] || 'ERROR'
21
+ @prefix = @config[:prefix] || 'VWO-SDK' # Ensure `@prefix` is set here
22
+ end
23
+
24
+ # Define the logging methods
25
+ def trace(message)
26
+ console_log('TRACE', message)
27
+ end
28
+
29
+ def debug(message)
30
+ console_log('DEBUG', message)
31
+ end
32
+
33
+ def info(message)
34
+ console_log('INFO', message)
35
+ end
36
+
37
+ def warn(message)
38
+ console_log('WARN', message)
39
+ end
40
+
41
+ def error(message)
42
+ console_log('ERROR', message)
43
+ end
44
+
45
+ def console_log(level, message)
46
+ puts "#{message}" # Output the log to console
47
+ end
48
+ end
49
+
@@ -0,0 +1,107 @@
1
+ # Copyright 2025 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'json'
16
+ require 'uri'
17
+ require_relative '../models/request_model'
18
+ require_relative '../models/response_model'
19
+ require_relative '../../../utils/network_util'
20
+ require 'net/http'
21
+ require 'concurrent-ruby'
22
+ require_relative '../../../constants/constants'
23
+
24
+ class NetworkClient
25
+ HTTPS_SCHEME = 'https'
26
+
27
+ def initialize(options = {})
28
+ # options for threading
29
+ @should_use_threading = options.key?(:enabled) ? options[:enabled] : Constants::SHOULD_USE_THREADING
30
+ @thread_pool = Concurrent::FixedThreadPool.new(options.key?(:max_pool_size) ? options[:max_pool_size] : Constants::MAX_POOL_SIZE)
31
+ end
32
+
33
+ def get_thread_pool
34
+ @thread_pool
35
+ end
36
+
37
+ def get(request_model)
38
+ # Build the URL and headers
39
+ url = request_model.get_url + request_model.get_path
40
+ uri = URI(url)
41
+
42
+ # Create the HTTP GET request
43
+ request = Net::HTTP::Get.new(uri)
44
+ # Add headers to the request
45
+ request_model.get_headers.each { |k, v| request[k] = v }
46
+
47
+ # Send the GET request and get the response
48
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
49
+ http.request(request)
50
+ end
51
+
52
+ # Process the response
53
+ response_model = ResponseModel.new
54
+ response_model.set_status_code(response.code.to_i) # Convert status code to integer
55
+
56
+ begin
57
+ # Parse the response body as JSON
58
+ parsed_data = JSON.parse(response.body)
59
+ response_model.set_data(parsed_data)
60
+ rescue StandardError => e
61
+ # Handle any JSON parsing errors
62
+ response_model.set_error(e.message)
63
+ end
64
+
65
+ # Return the response model
66
+ response_model
67
+ end
68
+
69
+ def post(request_model)
70
+ def execute_post(request_model)
71
+ url = request_model.get_url + request_model.get_path
72
+ uri = URI(url)
73
+ headers = request_model.get_headers # Directly use the hash from the request model
74
+ body = JSON.dump(request_model.get_body)
75
+
76
+ request = Net::HTTP::Post.new(uri, headers) # Pass the hash of headers directly
77
+ request.body = body
78
+
79
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http| http.request(request) }
80
+
81
+ response_model = ResponseModel.new
82
+ response_model.set_status_code(response.code.to_i)
83
+
84
+ # Check if the response body is empty or invalid before parsing
85
+ if response.is_a?(Net::HTTPSuccess) && !response.body.strip.empty?
86
+ begin
87
+ parsed_data = JSON.parse(response.body)
88
+ response_model.set_data(parsed_data)
89
+ rescue JSON::ParserError => e
90
+ # Handle invalid JSON response
91
+ response_model.set_error("Invalid JSON response: #{e.message}")
92
+ end
93
+ else
94
+ end
95
+ rescue StandardError => e
96
+ LoggerService.log(LogLevelEnum::ERROR, "POST request failed: #{e.message}", nil)
97
+ end
98
+
99
+ # Check if threading is enabled in options
100
+ if @should_use_threading
101
+ @thread_pool.post { execute_post(request_model) }
102
+ else
103
+ execute_post(request_model)
104
+ end
105
+ end
106
+
107
+ end
@@ -0,0 +1,37 @@
1
+ # Copyright 2025 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative '../models/global_request_model'
16
+ require_relative '../models/request_model'
17
+
18
+ class RequestHandler
19
+ def create_request(request, config)
20
+ return nil if config.get_base_url.nil? && request.get_url.nil?
21
+
22
+ request.set_url(request.get_url || config.get_base_url)
23
+ request.set_timeout(request.get_timeout || config.get_timeout)
24
+ request.set_body(request.get_body || config.get_body)
25
+ request.set_headers(request.get_headers || config.get_headers)
26
+
27
+ request_query_params = request.get_query || {}
28
+ config_query_params = config.get_query || {}
29
+
30
+ config_query_params.each do |key, value|
31
+ request_query_params[key] ||= value
32
+ end
33
+
34
+ request.set_query(request_query_params)
35
+ request
36
+ end
37
+ end
@@ -0,0 +1,78 @@
1
+ # Copyright 2025 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative '../client/network_client'
16
+ require_relative '../handlers/request_handler'
17
+ require_relative '../models/global_request_model'
18
+ require_relative '../../../services/logger_service'
19
+ require_relative '../../../enums/log_level_enum'
20
+ require_relative '../../../constants/constants'
21
+ class NetworkManager
22
+ @instance = nil
23
+
24
+ def initialize(options = {})
25
+ @client = NetworkClient.new(options)
26
+ @config = GlobalRequestModel.new(nil, {}, {}, {})
27
+ @should_use_threading = options.key?(:enabled) ? options[:enabled] : Constants::SHOULD_USE_THREADING
28
+ end
29
+
30
+ def self.instance(options = {})
31
+ @instance ||= new(options)
32
+ end
33
+
34
+ def attach_client(client = nil)
35
+ @client = client || NetworkClient.new(@should_use_threading)
36
+ end
37
+
38
+ def get_client
39
+ @client
40
+ end
41
+
42
+ def set_config(config)
43
+ @config = config
44
+ end
45
+
46
+ def get_config
47
+ @config
48
+ end
49
+
50
+ def create_request(request)
51
+ RequestHandler.new.create_request(request, @config)
52
+ end
53
+
54
+ def get(request)
55
+ begin
56
+ network_options = create_request(request)
57
+ raise 'No URL found' if network_options.get_url.nil?
58
+
59
+ response = @client.get(network_options)
60
+ response
61
+ rescue => e
62
+ LoggerService.log(LogLevelEnum::ERROR, "Error getting: #{e.message}", nil)
63
+ raise e
64
+ end
65
+ end
66
+
67
+
68
+ def post(request)
69
+ begin
70
+ network_options = create_request(request)
71
+ raise 'No URL found' if network_options.get_url.nil?
72
+
73
+ @client.post(network_options)
74
+ rescue => e
75
+ LoggerService.log(LogLevelEnum::ERROR, "Error posting: #{e.message}", nil)
76
+ end
77
+ end
78
+ end