conversant 1.0.16

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 (64) hide show
  1. checksums.yaml +7 -0
  2. data/.env.example +39 -0
  3. data/.gitignore +52 -0
  4. data/.gitlab-ci.yml +108 -0
  5. data/.rspec +3 -0
  6. data/.rubocop.yml +16 -0
  7. data/.yardopts +7 -0
  8. data/CHANGELOG.md +487 -0
  9. data/Gemfile +12 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +860 -0
  12. data/RELEASE.md +726 -0
  13. data/Rakefile +21 -0
  14. data/conversant.gemspec +49 -0
  15. data/examples/inheritance_integration.rb +348 -0
  16. data/examples/rails_initializer.rb +69 -0
  17. data/lib/conversant/configuration.rb +132 -0
  18. data/lib/conversant/v3/base.rb +47 -0
  19. data/lib/conversant/v3/http_client.rb +456 -0
  20. data/lib/conversant/v3/mixins/authentication.rb +221 -0
  21. data/lib/conversant/v3/services/authorization.rb +194 -0
  22. data/lib/conversant/v3/services/cdn/analytics.rb +483 -0
  23. data/lib/conversant/v3/services/cdn/audit.rb +71 -0
  24. data/lib/conversant/v3/services/cdn/business.rb +122 -0
  25. data/lib/conversant/v3/services/cdn/certificate.rb +180 -0
  26. data/lib/conversant/v3/services/cdn/dashboard.rb +109 -0
  27. data/lib/conversant/v3/services/cdn/domain.rb +223 -0
  28. data/lib/conversant/v3/services/cdn/monitoring.rb +65 -0
  29. data/lib/conversant/v3/services/cdn/partner/analytics.rb +233 -0
  30. data/lib/conversant/v3/services/cdn/partner.rb +60 -0
  31. data/lib/conversant/v3/services/cdn.rb +221 -0
  32. data/lib/conversant/v3/services/lms/dashboard.rb +99 -0
  33. data/lib/conversant/v3/services/lms/domain.rb +108 -0
  34. data/lib/conversant/v3/services/lms/job.rb +211 -0
  35. data/lib/conversant/v3/services/lms/partner/analytics.rb +266 -0
  36. data/lib/conversant/v3/services/lms/partner/business.rb +151 -0
  37. data/lib/conversant/v3/services/lms/partner/report.rb +170 -0
  38. data/lib/conversant/v3/services/lms/partner.rb +58 -0
  39. data/lib/conversant/v3/services/lms/preset.rb +57 -0
  40. data/lib/conversant/v3/services/lms.rb +173 -0
  41. data/lib/conversant/v3/services/oss/partner/analytics.rb +105 -0
  42. data/lib/conversant/v3/services/oss/partner.rb +48 -0
  43. data/lib/conversant/v3/services/oss.rb +128 -0
  44. data/lib/conversant/v3/services/portal/dashboard.rb +114 -0
  45. data/lib/conversant/v3/services/portal.rb +219 -0
  46. data/lib/conversant/v3/services/vms/analytics.rb +114 -0
  47. data/lib/conversant/v3/services/vms/business.rb +190 -0
  48. data/lib/conversant/v3/services/vms/partner/analytics.rb +133 -0
  49. data/lib/conversant/v3/services/vms/partner/business.rb +90 -0
  50. data/lib/conversant/v3/services/vms/partner.rb +57 -0
  51. data/lib/conversant/v3/services/vms/transcoding.rb +184 -0
  52. data/lib/conversant/v3/services/vms.rb +166 -0
  53. data/lib/conversant/v3.rb +36 -0
  54. data/lib/conversant/version.rb +5 -0
  55. data/lib/conversant.rb +108 -0
  56. data/publish.sh +107 -0
  57. data/sig/conversant/v3/services/authorization.rbs +34 -0
  58. data/sig/conversant/v3/services/cdn.rbs +123 -0
  59. data/sig/conversant/v3/services/lms.rbs +80 -0
  60. data/sig/conversant/v3/services/portal.rbs +22 -0
  61. data/sig/conversant/v3/services/vms.rbs +64 -0
  62. data/sig/conversant/v3.rbs +85 -0
  63. data/sig/conversant.rbs +37 -0
  64. metadata +267 -0
@@ -0,0 +1,223 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Conversant
4
+ module V3
5
+ module Services
6
+ class CDN
7
+ # Domain management service for CDN domains
8
+ #
9
+ # Provides comprehensive domain management functionality including:
10
+ # - Domain listing and filtering
11
+ # - Domain creation and configuration
12
+ # - Domain lookup and search
13
+ # - Storage usage calculations
14
+ #
15
+ # @example Basic domain operations
16
+ # domains = cdn.domain.all
17
+ # domain = cdn.domain.find(123)
18
+ # domain = cdn.domain.find_by(name: 'example.com')
19
+ #
20
+ # # Create new domain
21
+ # domain_id = cdn.domain.create({
22
+ # businessScenarioType: 1,
23
+ # name: "cdn.example.com",
24
+ # origins: [{ url_prefix: "1.2.3.4" }],
25
+ # redirect_http_to_https: true,
26
+ # http2_enabled: true
27
+ # })
28
+ #
29
+ # @since 1.0.1
30
+ class Domain
31
+ # @return [CDN] the parent CDN service instance
32
+ attr_reader :parent
33
+
34
+ # Initialize domain service
35
+ #
36
+ # @param parent [CDN] the parent CDN service instance
37
+ def initialize(parent)
38
+ @parent = parent
39
+ end
40
+
41
+ # Get all domains for the customer
42
+ #
43
+ # Retrieves all domains associated with the customer account.
44
+ # Results are cached in Redis for 10 minutes to improve performance.
45
+ #
46
+ # @return [Array<OpenStruct>, Array] array of domain objects with properties like id, name, status, etc.
47
+ # Returns empty array on error or if no domains exist.
48
+ #
49
+ # @example Get all domains
50
+ # domains = cdn.domain.all
51
+ # domains.each do |domain|
52
+ # puts "#{domain.name} (ID: #{domain.id}) - Status: #{domain.status}"
53
+ # puts " Business Type: #{domain.businessScenarioType}"
54
+ # puts " Current Usage: #{domain.current_disk_usage} bytes"
55
+ # end
56
+ #
57
+ # @since 1.0.1
58
+ def all
59
+ key = "customer.#{@parent.customer_id}.domain.all"
60
+ domains = redis.get(key)
61
+
62
+ if domains.nil?
63
+ response = @parent.send(:call, 'GET', '/api/delivery_domains?pageSize=-1&pageNumber=-1')
64
+ return [] if response.nil?
65
+
66
+ response = JSON.parse(response)
67
+ if response&.[]('list')
68
+ domains = response['list'].to_json
69
+ redis.set(key, domains, ex: 600)
70
+ else
71
+ return []
72
+ end
73
+ end
74
+
75
+ JSON.parse(domains).map do |item|
76
+ OpenStruct.new(item.merge(customer_id: @parent.customer_id))
77
+ end
78
+ rescue StandardError => e
79
+ logger.error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
80
+ []
81
+ end
82
+
83
+ # Find domain by ID
84
+ #
85
+ # @param domain_id [Integer, String] the domain ID to search for
86
+ #
87
+ # @return [OpenStruct, nil] domain object if found, nil otherwise
88
+ #
89
+ # @example Find domain by ID
90
+ # domain = cdn.domain.find(12345)
91
+ # if domain
92
+ # puts "Found domain: #{domain.name}"
93
+ # puts "Status: #{domain.status}"
94
+ # else
95
+ # puts "Domain not found"
96
+ # end
97
+ #
98
+ # @since 1.0.1
99
+ def find(domain_id)
100
+ all.find { |domain| domain.id == domain_id }
101
+ end
102
+
103
+ # Find domain by attributes
104
+ #
105
+ # @param params [Hash] search parameters
106
+ # @option params [String] :name domain name to search for
107
+ #
108
+ # @return [OpenStruct, nil] first domain matching the criteria, nil if not found
109
+ #
110
+ # @example Find domain by name
111
+ # domain = cdn.domain.find_by(name: 'cdn.example.com')
112
+ # if domain
113
+ # puts "Found domain with ID: #{domain.id}"
114
+ # end
115
+ #
116
+ # @since 1.0.1
117
+ def find_by(params)
118
+ all.find { |domain| domain.name == params[:name] }
119
+ end
120
+
121
+ # Create a new CDN domain
122
+ #
123
+ # Creates a new CDN domain with the specified configuration.
124
+ # Automatically clears the domain cache upon successful creation.
125
+ #
126
+ # @param payload [Hash] domain configuration
127
+ # @option payload [Integer] :businessScenarioType business scenario (1=CDN, 2=Storage)
128
+ # @option payload [String] :name domain name (e.g., "cdn.example.com")
129
+ # @option payload [String] :lfdName load balancer domain name (optional)
130
+ # @option payload [String] :origin_url origin server URL (optional)
131
+ # @option payload [String] :origin_proto origin protocol (optional)
132
+ # @option payload [Boolean] :redirect_http_to_https enable HTTP to HTTPS redirect
133
+ # @option payload [Boolean] :http2_enabled enable HTTP/2 support
134
+ # @option payload [Boolean] :streaming_service enable streaming capabilities
135
+ # @option payload [Boolean] :disabled initial disabled state
136
+ # @option payload [Boolean] :hwc_enabled enable hardware acceleration
137
+ # @option payload [Array] :multiCDN multi-CDN configuration
138
+ # @option payload [Array<Hash>] :origins array of origin servers
139
+ # @option payload [String] :ftpPassword FTP password (for storage domains)
140
+ # @option payload [String] :ftpPasswordRepeat FTP password confirmation
141
+ #
142
+ # @return [Integer, nil] the new domain ID if successful, nil on error
143
+ #
144
+ # @example Create a CDN domain
145
+ # domain_id = cdn.domain.create({
146
+ # businessScenarioType: 1,
147
+ # name: "cdn.example.com",
148
+ # origins: [{ url_prefix: "203.0.113.10" }],
149
+ # redirect_http_to_https: true,
150
+ # http2_enabled: true,
151
+ # streaming_service: false,
152
+ # disabled: false,
153
+ # hwc_enabled: false,
154
+ # multiCDN: []
155
+ # })
156
+ #
157
+ # if domain_id
158
+ # puts "Domain created with ID: #{domain_id}"
159
+ # else
160
+ # puts "Failed to create domain"
161
+ # end
162
+ #
163
+ # @example Create a storage domain
164
+ # domain_id = cdn.domain.create({
165
+ # businessScenarioType: 2,
166
+ # name: "storage.example.com",
167
+ # ftpPassword: "secure_password",
168
+ # ftpPasswordRepeat: "secure_password",
169
+ # origins: [{ url_prefix: "203.0.113.20" }]
170
+ # })
171
+ #
172
+ # @since 1.0.1
173
+ def create(payload)
174
+ response = @parent.send(:call, 'POST', '/api/v6/delivery_domain', payload)
175
+ return nil if response.nil?
176
+
177
+ response = JSON.parse(response)
178
+ return nil unless response.to_i.positive?
179
+
180
+ # Clear cache after creation
181
+ redis.del("customer.#{@parent.customer_id}.domain.all")
182
+ response
183
+ rescue StandardError => e
184
+ logger.error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
185
+ nil
186
+ end
187
+
188
+ # Calculate total disk usage for storage domains
189
+ #
190
+ # Calculates the total current disk usage across all active storage domains
191
+ # (businessScenarioType=2, status=1) for the customer.
192
+ #
193
+ # @return [Integer] total disk usage in bytes, 0 if no storage domains or on error
194
+ #
195
+ # @example Get total storage usage
196
+ # total_bytes = cdn.domain.total_current_disk_usage
197
+ # total_gb = total_bytes / (1024 ** 3)
198
+ # puts "Total storage usage: #{total_gb} GB"
199
+ #
200
+ # @since 1.0.1
201
+ def total_current_disk_usage
202
+ all.select do |item|
203
+ item.businessScenarioType == 2 && item.status == 1
204
+ end.map(&:current_disk_usage).sum
205
+ rescue StandardError => e
206
+ logger.error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
207
+ 0
208
+ end
209
+
210
+ private
211
+
212
+ def redis
213
+ @parent.send(:redis)
214
+ end
215
+
216
+ def logger
217
+ @parent.send(:logger)
218
+ end
219
+ end
220
+ end
221
+ end
222
+ end
223
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Conversant
4
+ module V3
5
+ module Services
6
+ class CDN
7
+ # Monitoring service for CDN performance tracking
8
+ #
9
+ # Provides real-time monitoring data and performance metrics
10
+ # for CDN infrastructure and service health.
11
+ #
12
+ # @example Monitor CDN health
13
+ # cdn = Conversant::V3.cdn(12345)
14
+ #
15
+ # spots = cdn.monitoring.spots({
16
+ # startTime: "2025-01-01T00:00:00Z",
17
+ # endTime: "2025-01-01T01:00:00Z",
18
+ # domains: ["example.com"]
19
+ # })
20
+ #
21
+ # spots.each do |spot|
22
+ # puts "#{spot['location']}: #{spot['status']}"
23
+ # end
24
+ #
25
+ # @since 1.0.0
26
+ class Monitoring
27
+ # @return [CDN] the parent CDN service instance
28
+ attr_reader :parent
29
+
30
+ # Initialize monitoring service
31
+ #
32
+ # @param parent [CDN] the parent CDN service instance
33
+ def initialize(parent)
34
+ @parent = parent
35
+ end
36
+
37
+ # Get monitoring spot data
38
+ #
39
+ # @param payload [Hash] monitoring parameters
40
+ # @option payload [String] :startTime start time in ISO 8601 format
41
+ # @option payload [String] :endTime end time in ISO 8601 format
42
+ # @option payload [Array<String>] :domains array of domains to monitor
43
+ #
44
+ # @return [Array] array of monitoring spots data, or empty array on error
45
+ #
46
+ # @example Get monitoring data
47
+ # spots = cdn.monitoring.spots({
48
+ # startTime: "2025-01-01T00:00:00Z",
49
+ # endTime: "2025-01-01T01:00:00Z",
50
+ # domains: ["example.com"]
51
+ # })
52
+ # spots.each { |spot| puts "#{spot['location']}: #{spot['status']}" }
53
+ #
54
+ # @since 1.0.0
55
+ def spots(payload)
56
+ JSON.parse(@parent.send(:call, 'POST', '/api/monitoring', payload))&.[]('spots') || []
57
+ rescue StandardError => e
58
+ @parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
59
+ []
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,233 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Conversant
4
+ module V3
5
+ module Services
6
+ class CDN
7
+ class Partner
8
+ # CDN analytics service for partner-level reporting
9
+ #
10
+ # Provides partner-level analytics and reporting for CDN services including
11
+ # bandwidth, volume, traffic usage, storage, and viewer metrics across
12
+ # multiple customer accounts.
13
+ #
14
+ # @example Usage
15
+ # cdn = Conversant::V3.cdn(customer_id)
16
+ # analytics = cdn.partner.analytics
17
+ #
18
+ # # Get bandwidth metrics
19
+ # bandwidth_data = analytics.bandwidth({
20
+ # startTime: '2024-01-01T00:00:00Z',
21
+ # endTime: '2024-01-31T23:59:59Z',
22
+ # interval: 'day'
23
+ # })
24
+ #
25
+ # @since 1.0.12
26
+ class Analytics
27
+ # @return [Conversant::V3::Services::CDN] the parent CDN service instance
28
+ attr_reader :parent
29
+
30
+ # Initialize partner CDN analytics service
31
+ #
32
+ # @param parent [Conversant::V3::Services::CDN] the parent CDN service instance
33
+ def initialize(parent)
34
+ @parent = parent
35
+ end
36
+
37
+ # Get partner-level bandwidth metrics
38
+ #
39
+ # Retrieves aggregated bandwidth usage across all customer accounts
40
+ # for the partner within the specified time range.
41
+ #
42
+ # @param payload [Hash] bandwidth query parameters
43
+ # @option payload [String] :startTime start time in ISO 8601 format
44
+ # @option payload [String] :endTime end time in ISO 8601 format
45
+ # @option payload [String] :interval time interval (e.g., "hour", "day", "month")
46
+ #
47
+ # @return [Hash] bandwidth data with timestamps and values, or nil on error
48
+ # @since 1.0.8
49
+ #
50
+ # @example Get daily bandwidth for January 2024
51
+ # analytics.bandwidth({
52
+ # startTime: '2024-01-01T00:00:00Z',
53
+ # endTime: '2024-01-31T23:59:59Z',
54
+ # interval: 'day'
55
+ # })
56
+ def bandwidth(payload)
57
+ response = @parent.send(:call, 'POST', '/api/report/bandwidth/partner', payload)
58
+ JSON.parse(response)
59
+ rescue StandardError => e
60
+ @parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
61
+ nil
62
+ end
63
+
64
+ # Get partner-level volume metrics
65
+ #
66
+ # @param payload [Hash] volume query parameters
67
+ # @option payload [String] :startTime start time in ISO 8601 format
68
+ # @option payload [String] :endTime end time in ISO 8601 format
69
+ # @option payload [String] :interval time interval
70
+ #
71
+ # @return [Hash] volume data, or nil on error
72
+ # @since 1.0.8
73
+ def volume(payload)
74
+ response = @parent.send(:call, 'POST', '/api/report/volume/partner', payload)
75
+ JSON.parse(response)
76
+ rescue StandardError => e
77
+ @parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
78
+ nil
79
+ end
80
+
81
+ # Get partner-level request per second metrics
82
+ #
83
+ # @param params [Hash] query parameters
84
+ #
85
+ # @return [Hash] RPS data, or nil on error
86
+ # @since 1.0.8
87
+ def request_per_second(params)
88
+ query_string = params.map { |k, v| "#{k}=#{v}" }.join('&')
89
+ response = @parent.send(:call, 'GET', "/api/rps_chart_data/partner?#{query_string}")
90
+ JSON.parse(response)
91
+ rescue StandardError => e
92
+ @parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
93
+ nil
94
+ end
95
+
96
+ # Get domain traffic usage for billing purposes
97
+ #
98
+ # @param payload [Hash] usage query parameters
99
+ # @option payload [String] :startTime start time in ISO 8601 format
100
+ # @option payload [String] :endTime end time in ISO 8601 format
101
+ # @option payload [Integer] :pageSize number of results per page
102
+ # @option payload [Integer] :pageNumber page number (0-based)
103
+ #
104
+ # @return [Hash] traffic usage data, or nil on error
105
+ # @since 1.0.8
106
+ def domain_traffic_usage(payload)
107
+ response = @parent.send(:call, 'POST', '/api/domain_traffic_usage', payload)
108
+ JSON.parse(response)
109
+ rescue StandardError => e
110
+ @parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
111
+ nil
112
+ end
113
+
114
+ # Get partner-level viewer metrics
115
+ #
116
+ # @param payload [Hash] viewer query parameters
117
+ # @option payload [String] :startTime start time in ISO 8601 format
118
+ # @option payload [String] :endTime end time in ISO 8601 format
119
+ # @option payload [String] :interval time interval
120
+ #
121
+ # @return [Hash] viewer data, or nil on error
122
+ # @since 1.0.8
123
+ def viewers(payload)
124
+ response = @parent.send(:call, 'POST', '/api/report/viewers/partner', payload)
125
+ JSON.parse(response)
126
+ rescue StandardError => e
127
+ @parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
128
+ nil
129
+ end
130
+
131
+ # Get storage usage for a customer
132
+ #
133
+ # Retrieves the disk usage for the current month or specified month.
134
+ # If no end date is provided in the payload, it defaults to the current date.
135
+ #
136
+ # @param payload [Hash, nil] query parameters (optional)
137
+ # @option payload [String, Date] :end end date to determine year/month (defaults to current date)
138
+ #
139
+ # @return [Integer] disk usage in bytes for the specified month, or 0 on error
140
+ # @since 1.0.8
141
+ #
142
+ # @example Get current month's storage usage
143
+ # analytics.usages(nil)
144
+ # # => 1024000
145
+ #
146
+ # @example Get specific month's storage usage
147
+ # analytics.usages({ end: '2024-03-15' })
148
+ # # => 2048000
149
+ def usages(payload)
150
+ payload = payload&.as_json
151
+ today = (payload&.[]('end') || Date.current).to_date
152
+
153
+ # puts @parent.inspect
154
+
155
+ response = @parent.send(:call, 'GET', "/api/customers/#{@parent.customer_id}/storage_usages/#{today.year}")
156
+ JSON.parse(response)&.find do |item|
157
+ item&.[]('month') == today.month
158
+ end&.[]('diskUsage') || 0
159
+ rescue StandardError => e
160
+ @parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
161
+ 0
162
+ end
163
+
164
+ # Get volume metrics for a specific domain
165
+ #
166
+ # @param payload [Hash] volume query parameters
167
+ # @option payload [String] :domain domain name
168
+ # @option payload [String] :startTime start time in ISO 8601 format
169
+ # @option payload [String] :endTime end time in ISO 8601 format
170
+ # @option payload [String] :interval time interval (e.g., "day")
171
+ # @option payload [Boolean] :fillFixedTime fill missing time slots
172
+ #
173
+ # @return [Hash] volume data for domain, or nil on error
174
+ # @since 1.0.8
175
+ def domain_volume(payload)
176
+ response = @parent.send(:call, 'POST', '/api/report/volume', payload)
177
+ JSON.parse(response)
178
+ rescue StandardError => e
179
+ @parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
180
+ nil
181
+ end
182
+
183
+ # Get HTTP status codes for specific domains
184
+ #
185
+ # Retrieves HTTP status code distribution for specified domains,
186
+ # useful for monitoring error rates and response codes.
187
+ #
188
+ # @param customer_id [String, Integer] customer ID
189
+ # @param payload [Hash] HTTP codes query parameters
190
+ # @option payload [Array<String>] :domains array of domain names
191
+ # @option payload [String] :startTime start time in ISO 8601 format
192
+ # @option payload [String] :endTime end time in ISO 8601 format
193
+ # @option payload [String] :interval time interval (e.g., "hour", "day")
194
+ # @option payload [String] :daHostName specific hostname filter (optional)
195
+ #
196
+ # @return [Hash] HTTP codes data grouped by status code, or nil on error
197
+ # @since 1.0.8
198
+ #
199
+ # @example Get HTTP codes for specific domains
200
+ # analytics.domain_http_codes(123, {
201
+ # domains: ['cdn.example.com', 'static.example.com'],
202
+ # startTime: '2024-01-01T00:00:00Z',
203
+ # endTime: '2024-01-02T00:00:00Z',
204
+ # interval: 'hour'
205
+ # })
206
+ def domain_http_codes(customer_id, payload)
207
+ response = @parent.send(:call, 'POST', "/api/report/customers/#{customer_id}/http_codes", payload)
208
+ JSON.parse(response)
209
+ rescue StandardError => e
210
+ @parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
211
+ nil
212
+ end
213
+
214
+ # Get request per second for specific domain
215
+ #
216
+ # @param params [Hash] query parameters
217
+ #
218
+ # @return [Hash] RPS data for domain, or nil on error
219
+ # @since 1.0.8
220
+ def domain_rps(params)
221
+ query_string = params.map { |k, v| "#{k}=#{v}" }.join('&')
222
+ response = @parent.send(:call, 'GET', "/api/rps_chart_data?#{query_string}")
223
+ JSON.parse(response)
224
+ rescue StandardError => e
225
+ @parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
226
+ nil
227
+ end
228
+ end
229
+ end
230
+ end
231
+ end
232
+ end
233
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Conversant
4
+ module V3
5
+ module Services
6
+ class CDN
7
+ # Partner service for CDN partner-level operations
8
+ #
9
+ # Provides access to partner-level analytics for CDN services
10
+ # that aggregate data across multiple customer accounts.
11
+ #
12
+ # @example Access partner analytics
13
+ # cdn = Conversant::V3.cdn(12345)
14
+ #
15
+ # # Partner-level CDN analytics
16
+ # bandwidth = cdn.partner.analytics.bandwidth({
17
+ # startTime: "2025-01-01T00:00:00Z",
18
+ # endTime: "2025-01-31T23:59:59Z"
19
+ # })
20
+ #
21
+ # @since 1.0.12
22
+ class Partner
23
+ # @return [CDN] the parent CDN service instance
24
+ attr_reader :parent
25
+
26
+ # Initialize partner service
27
+ #
28
+ # @param parent [CDN] the parent CDN service instance
29
+ def initialize(parent)
30
+ @parent = parent
31
+ end
32
+
33
+ # Get partner analytics service instance
34
+ #
35
+ # Provides partner-level analytics for CDN services including bandwidth,
36
+ # volume, traffic usage, and viewer metrics across multiple customers.
37
+ #
38
+ # @return [Analytics] CDN partner analytics service
39
+ # @since 1.0.12
40
+ def analytics
41
+ @analytics ||= Analytics.new(@parent)
42
+ end
43
+
44
+ # @deprecated Use {Conversant::V3.oss} instead
45
+ # Get partner OSS analytics service instance (deprecated)
46
+ #
47
+ # @return [Conversant::V3::Services::OSS::Partner::Analytics] OSS partner analytics service
48
+ # @since 1.0.12
49
+ # @deprecated Use `oss = Conversant::V3.oss(customer_id); oss.partner.analytics` instead of `cdn.partner.oss`
50
+ def oss
51
+ @oss ||= Conversant::V3::Services::OSS::Partner::Analytics.new(@parent)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ # Load nested analytics class after Partner is defined
60
+ require_relative 'partner/analytics'