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.
- checksums.yaml +7 -0
- data/.env.example +39 -0
- data/.gitignore +52 -0
- data/.gitlab-ci.yml +108 -0
- data/.rspec +3 -0
- data/.rubocop.yml +16 -0
- data/.yardopts +7 -0
- data/CHANGELOG.md +487 -0
- data/Gemfile +12 -0
- data/LICENSE.txt +21 -0
- data/README.md +860 -0
- data/RELEASE.md +726 -0
- data/Rakefile +21 -0
- data/conversant.gemspec +49 -0
- data/examples/inheritance_integration.rb +348 -0
- data/examples/rails_initializer.rb +69 -0
- data/lib/conversant/configuration.rb +132 -0
- data/lib/conversant/v3/base.rb +47 -0
- data/lib/conversant/v3/http_client.rb +456 -0
- data/lib/conversant/v3/mixins/authentication.rb +221 -0
- data/lib/conversant/v3/services/authorization.rb +194 -0
- data/lib/conversant/v3/services/cdn/analytics.rb +483 -0
- data/lib/conversant/v3/services/cdn/audit.rb +71 -0
- data/lib/conversant/v3/services/cdn/business.rb +122 -0
- data/lib/conversant/v3/services/cdn/certificate.rb +180 -0
- data/lib/conversant/v3/services/cdn/dashboard.rb +109 -0
- data/lib/conversant/v3/services/cdn/domain.rb +223 -0
- data/lib/conversant/v3/services/cdn/monitoring.rb +65 -0
- data/lib/conversant/v3/services/cdn/partner/analytics.rb +233 -0
- data/lib/conversant/v3/services/cdn/partner.rb +60 -0
- data/lib/conversant/v3/services/cdn.rb +221 -0
- data/lib/conversant/v3/services/lms/dashboard.rb +99 -0
- data/lib/conversant/v3/services/lms/domain.rb +108 -0
- data/lib/conversant/v3/services/lms/job.rb +211 -0
- data/lib/conversant/v3/services/lms/partner/analytics.rb +266 -0
- data/lib/conversant/v3/services/lms/partner/business.rb +151 -0
- data/lib/conversant/v3/services/lms/partner/report.rb +170 -0
- data/lib/conversant/v3/services/lms/partner.rb +58 -0
- data/lib/conversant/v3/services/lms/preset.rb +57 -0
- data/lib/conversant/v3/services/lms.rb +173 -0
- data/lib/conversant/v3/services/oss/partner/analytics.rb +105 -0
- data/lib/conversant/v3/services/oss/partner.rb +48 -0
- data/lib/conversant/v3/services/oss.rb +128 -0
- data/lib/conversant/v3/services/portal/dashboard.rb +114 -0
- data/lib/conversant/v3/services/portal.rb +219 -0
- data/lib/conversant/v3/services/vms/analytics.rb +114 -0
- data/lib/conversant/v3/services/vms/business.rb +190 -0
- data/lib/conversant/v3/services/vms/partner/analytics.rb +133 -0
- data/lib/conversant/v3/services/vms/partner/business.rb +90 -0
- data/lib/conversant/v3/services/vms/partner.rb +57 -0
- data/lib/conversant/v3/services/vms/transcoding.rb +184 -0
- data/lib/conversant/v3/services/vms.rb +166 -0
- data/lib/conversant/v3.rb +36 -0
- data/lib/conversant/version.rb +5 -0
- data/lib/conversant.rb +108 -0
- data/publish.sh +107 -0
- data/sig/conversant/v3/services/authorization.rbs +34 -0
- data/sig/conversant/v3/services/cdn.rbs +123 -0
- data/sig/conversant/v3/services/lms.rbs +80 -0
- data/sig/conversant/v3/services/portal.rbs +22 -0
- data/sig/conversant/v3/services/vms.rbs +64 -0
- data/sig/conversant/v3.rbs +85 -0
- data/sig/conversant.rbs +37 -0
- metadata +267 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Conversant
|
|
4
|
+
module V3
|
|
5
|
+
module Services
|
|
6
|
+
# Shared authorization methods for service classes
|
|
7
|
+
#
|
|
8
|
+
# This module provides common authentication and authorization functionality
|
|
9
|
+
# for Conversant V3 service classes. It handles session management, cookie
|
|
10
|
+
# generation, and HTTP header construction with automatic caching via Redis.
|
|
11
|
+
#
|
|
12
|
+
# @example Including in a service class
|
|
13
|
+
# class MyService < Conversant::V3::BaseService
|
|
14
|
+
# include Conversant::V3::Services::Authorization
|
|
15
|
+
#
|
|
16
|
+
# def fetch_new_session
|
|
17
|
+
# # Custom session fetching logic
|
|
18
|
+
# end
|
|
19
|
+
#
|
|
20
|
+
# def service_endpoint
|
|
21
|
+
# 'https://api.example.com'
|
|
22
|
+
# end
|
|
23
|
+
# end
|
|
24
|
+
module Authorization
|
|
25
|
+
protected
|
|
26
|
+
|
|
27
|
+
# Builds authorized HTTP headers with session cookies
|
|
28
|
+
#
|
|
29
|
+
# Retrieves session cookies from cache or authenticates if needed,
|
|
30
|
+
# then constructs headers with appropriate cookie values.
|
|
31
|
+
#
|
|
32
|
+
# @return [Hash] HTTP headers including Cookie header if sessions exist
|
|
33
|
+
def authorized_headers
|
|
34
|
+
session_cookie = fetch_session_cookie
|
|
35
|
+
sso_gw_session2 = fetch_sso_session
|
|
36
|
+
|
|
37
|
+
log_missing_session if session_cookie.nil? && respond_to?(:requires_session?) && requires_session?
|
|
38
|
+
|
|
39
|
+
build_headers_with_cookies(session_cookie, sso_gw_session2)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Authorizes and retrieves a session cookie
|
|
43
|
+
#
|
|
44
|
+
# Checks Redis cache first, then fetches a new session if not cached.
|
|
45
|
+
#
|
|
46
|
+
# @return [String, nil] The session cookie value, or nil if authorization fails
|
|
47
|
+
def authorize
|
|
48
|
+
cached = cached_session
|
|
49
|
+
return cached if cached
|
|
50
|
+
|
|
51
|
+
fetch_new_session
|
|
52
|
+
rescue StandardError => e
|
|
53
|
+
logger.debug "#{identifier}.METHOD:authorize.EXCEPTION:#{e.message}"
|
|
54
|
+
nil
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
# Fetches session cookie from cache or authorizes to get a new one
|
|
60
|
+
#
|
|
61
|
+
# @return [String, nil] The session cookie value
|
|
62
|
+
def fetch_session_cookie
|
|
63
|
+
cached = cached_session
|
|
64
|
+
cached || authorize
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Fetches SSO session from authentication or cache
|
|
68
|
+
#
|
|
69
|
+
# @return [String, nil] The SSO_GW_SESSION2 cookie value
|
|
70
|
+
def fetch_sso_session
|
|
71
|
+
sessions = authenticate
|
|
72
|
+
sessions&.[](:sso_gw_session2)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Retrieves cached session from Redis
|
|
76
|
+
#
|
|
77
|
+
# @return [String, nil] The cached session value
|
|
78
|
+
def cached_session
|
|
79
|
+
redis.get(session_cache_key)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Generates Redis cache key for session storage
|
|
83
|
+
#
|
|
84
|
+
# @return [String] Redis key in format "CONVERSANT.V3.SERVICE.SESSION_TYPE.CUSTOMER_ID"
|
|
85
|
+
def session_cache_key
|
|
86
|
+
service_name = self.class.name.split('::').last.upcase
|
|
87
|
+
session_type = respond_to?(:session_cookie_name, true) ? session_cookie_name : 'SESSION'
|
|
88
|
+
"CONVERSANT.V3.#{service_name}.#{session_type}.#{customer_id}"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Generates Redis cache key for SSO session storage
|
|
92
|
+
#
|
|
93
|
+
# @return [String] Redis key in format "CONVERSANT.V3.PORTAL.SSO_GW_SESSION2.CUSTOMER_ID"
|
|
94
|
+
def sso_cache_key
|
|
95
|
+
"CONVERSANT.V3.PORTAL.SSO_GW_SESSION2.#{customer_id}"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Builds HTTP headers hash with cookie values
|
|
99
|
+
#
|
|
100
|
+
# @param session_cookie [String, nil] The session cookie value
|
|
101
|
+
# @param sso_gw_session2 [String, nil] The SSO session cookie value
|
|
102
|
+
# @return [Hash] Complete HTTP headers including Cookie header if applicable
|
|
103
|
+
def build_headers_with_cookies(session_cookie, sso_gw_session2)
|
|
104
|
+
headers = base_headers
|
|
105
|
+
cookie_header = format_cookies(session_cookie, sso_gw_session2)
|
|
106
|
+
headers['Cookie'] = cookie_header if cookie_header
|
|
107
|
+
headers
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Builds base HTTP headers for API requests
|
|
111
|
+
#
|
|
112
|
+
# @return [Hash] Base headers with Authority, Content-Type, Referer, and User-Agent
|
|
113
|
+
def base_headers
|
|
114
|
+
{
|
|
115
|
+
'Authority' => URI.parse(service_endpoint).hostname,
|
|
116
|
+
'Content-Type' => configuration.default_content_type,
|
|
117
|
+
'Referer' => portal_endpoint,
|
|
118
|
+
'User-Agent' => configuration.default_ua
|
|
119
|
+
}
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Formats cookie hash into HTTP Cookie header string
|
|
123
|
+
#
|
|
124
|
+
# @param session_cookie [String, nil] The session cookie value
|
|
125
|
+
# @param sso_gw_session2 [String, nil] The SSO session cookie value
|
|
126
|
+
# @return [String, nil] Formatted cookie string "key1=value1; key2=value2" or nil if no cookies
|
|
127
|
+
def format_cookies(session_cookie, sso_gw_session2)
|
|
128
|
+
cookies = build_cookie_hash(session_cookie, sso_gw_session2)
|
|
129
|
+
return nil if cookies.empty?
|
|
130
|
+
|
|
131
|
+
cookies.map { |k, v| "#{k}=#{v}" }.join('; ')
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Builds hash of cookie key-value pairs
|
|
135
|
+
#
|
|
136
|
+
# @param session_cookie [String, nil] The session cookie value
|
|
137
|
+
# @param sso_gw_session2 [String, nil] The SSO session cookie value
|
|
138
|
+
# @return [Hash] Cookie hash with appropriate keys based on service configuration
|
|
139
|
+
def build_cookie_hash(session_cookie, sso_gw_session2)
|
|
140
|
+
cookies = {}
|
|
141
|
+
|
|
142
|
+
if respond_to?(:session_cookie_name, true)
|
|
143
|
+
cookies[session_cookie_name] = session_cookie if session_cookie
|
|
144
|
+
elsif session_cookie
|
|
145
|
+
cookies['SESSION'] = session_cookie
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
cookies['SSO_GW_SESSION2'] = sso_gw_session2 if sso_gw_session2
|
|
149
|
+
cookies
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Logs warning when required session is missing
|
|
153
|
+
#
|
|
154
|
+
# @return [void]
|
|
155
|
+
def log_missing_session
|
|
156
|
+
session_type = respond_to?(:session_cookie_name, true) ? session_cookie_name : 'SESSION'
|
|
157
|
+
logger.warn "#{identifier}.METHOD:authorized_headers.NO_#{session_type}"
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Returns the service-specific API endpoint
|
|
161
|
+
#
|
|
162
|
+
# @abstract Subclasses must implement this method
|
|
163
|
+
# @return [String] The service endpoint URL
|
|
164
|
+
# @raise [NotImplementedError] if not implemented by subclass
|
|
165
|
+
def service_endpoint
|
|
166
|
+
raise NotImplementedError, "#{self.class} must implement #service_endpoint"
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Fetches a new session from the service
|
|
170
|
+
#
|
|
171
|
+
# @abstract Subclasses must implement this method with service-specific logic
|
|
172
|
+
# @return [String] The new session cookie value
|
|
173
|
+
# @raise [NotImplementedError] if not implemented by subclass
|
|
174
|
+
def fetch_new_session
|
|
175
|
+
raise NotImplementedError, "#{self.class} must implement #fetch_new_session"
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Returns the session cookie name for this service
|
|
179
|
+
#
|
|
180
|
+
# @return [String] The cookie name (defaults to 'SESSION')
|
|
181
|
+
def session_cookie_name
|
|
182
|
+
'SESSION'
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Indicates whether this service requires a session cookie
|
|
186
|
+
#
|
|
187
|
+
# @return [Boolean] true if session is required, false otherwise
|
|
188
|
+
def requires_session?
|
|
189
|
+
false
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Conversant
|
|
4
|
+
module V3
|
|
5
|
+
module Services
|
|
6
|
+
class CDN
|
|
7
|
+
# Analytics service for CDN metrics and reporting
|
|
8
|
+
#
|
|
9
|
+
# Provides comprehensive analytics data for CDN performance including:
|
|
10
|
+
# - Bandwidth and volume metrics
|
|
11
|
+
# - Viewer statistics
|
|
12
|
+
# - Request rates and hit rates
|
|
13
|
+
# - HTTP status code distribution
|
|
14
|
+
# - Referrer and popular content analytics
|
|
15
|
+
# - Origin request metrics
|
|
16
|
+
# - ISP and user agent analytics
|
|
17
|
+
#
|
|
18
|
+
# @example Basic usage
|
|
19
|
+
# cdn = Conversant::V3.cdn(12345)
|
|
20
|
+
#
|
|
21
|
+
# # Get bandwidth data
|
|
22
|
+
# bandwidth = cdn.analytics.bandwidths({
|
|
23
|
+
# domain: "All",
|
|
24
|
+
# startTime: "2025-01-01T00:00:00Z",
|
|
25
|
+
# endTime: "2025-01-01T23:59:59Z",
|
|
26
|
+
# interval: "hour"
|
|
27
|
+
# })
|
|
28
|
+
#
|
|
29
|
+
# # Get viewer statistics
|
|
30
|
+
# viewers = cdn.analytics.viewers({
|
|
31
|
+
# domain: "streaming.example.com",
|
|
32
|
+
# startTime: "2025-01-01T00:00:00Z",
|
|
33
|
+
# endTime: "2025-01-01T23:59:59Z",
|
|
34
|
+
# interval: "minute"
|
|
35
|
+
# })
|
|
36
|
+
#
|
|
37
|
+
# @since 1.0.0
|
|
38
|
+
class Analytics
|
|
39
|
+
# @return [CDN] the parent CDN service instance
|
|
40
|
+
attr_reader :parent
|
|
41
|
+
|
|
42
|
+
# Initialize analytics service
|
|
43
|
+
#
|
|
44
|
+
# @param parent [CDN] the parent CDN service instance
|
|
45
|
+
def initialize(parent)
|
|
46
|
+
@parent = parent
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Get bandwidth analytics data
|
|
50
|
+
#
|
|
51
|
+
# @param payload [Hash] analytics parameters
|
|
52
|
+
# @option payload [String] :domain domain name or "All" for all domains
|
|
53
|
+
# @option payload [String] :startTime start time in ISO 8601 format ("2025-01-01T00:00:00Z")
|
|
54
|
+
# @option payload [String] :endTime end time in ISO 8601 format
|
|
55
|
+
# @option payload [String] :interval time interval ("minute", "hour", "day")
|
|
56
|
+
# @option payload [Boolean] :fillFixedTime whether to fill missing time slots
|
|
57
|
+
# @option payload [String] :daHostName specific hostname filter
|
|
58
|
+
#
|
|
59
|
+
# @return [Hash, nil] bandwidth data with averageThroughput and data array, or nil on error
|
|
60
|
+
#
|
|
61
|
+
# @example Get hourly bandwidth for all domains
|
|
62
|
+
# bandwidth = cdn.analytics.bandwidths({
|
|
63
|
+
# domain: "All",
|
|
64
|
+
# startTime: "2025-01-01T00:00:00Z",
|
|
65
|
+
# endTime: "2025-01-01T23:59:59Z",
|
|
66
|
+
# interval: "hour",
|
|
67
|
+
# fillFixedTime: true
|
|
68
|
+
# })
|
|
69
|
+
# puts bandwidth[:averageThroughput]
|
|
70
|
+
# bandwidth[:data].each { |point| puts "#{point['time']}: #{point['value']}" }
|
|
71
|
+
#
|
|
72
|
+
# @since 1.0.0
|
|
73
|
+
def bandwidths(payload)
|
|
74
|
+
response = JSON.parse(@parent.send(:call, 'POST', '/api/report/bandwidth', payload))
|
|
75
|
+
if response&.[]('bandwidth')
|
|
76
|
+
{
|
|
77
|
+
averageThroughput: response&.[]('averageThroughput'),
|
|
78
|
+
data: response&.[]('bandwidth'),
|
|
79
|
+
}
|
|
80
|
+
end
|
|
81
|
+
rescue StandardError => e
|
|
82
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
83
|
+
nil
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Get volume analytics data
|
|
87
|
+
#
|
|
88
|
+
# @param payload [Hash] analytics parameters
|
|
89
|
+
# @option payload [String] :domain domain name or "All" for all domains
|
|
90
|
+
# @option payload [String] :startTime start time in ISO 8601 format
|
|
91
|
+
# @option payload [String] :endTime end time in ISO 8601 format
|
|
92
|
+
# @option payload [String] :interval time interval ("minute", "hour", "day")
|
|
93
|
+
# @option payload [Boolean] :fillFixedTime whether to fill missing time slots
|
|
94
|
+
#
|
|
95
|
+
# @return [Hash, nil] volume data with domain and volumes array, or nil on error
|
|
96
|
+
#
|
|
97
|
+
# @example Get daily volume data
|
|
98
|
+
# volume = cdn.analytics.volumes({
|
|
99
|
+
# domain: "example.com",
|
|
100
|
+
# startTime: "2025-01-01T00:00:00Z",
|
|
101
|
+
# endTime: "2025-01-31T00:00:00Z",
|
|
102
|
+
# interval: "day"
|
|
103
|
+
# })
|
|
104
|
+
# puts "Domain: #{volume[:domain]}"
|
|
105
|
+
# volume[:data].each { |point| puts "#{point['time']}: #{point['bytes']} bytes" }
|
|
106
|
+
#
|
|
107
|
+
# @since 1.0.0
|
|
108
|
+
def volumes(payload)
|
|
109
|
+
response = JSON.parse(@parent.send(:call, 'POST', '/api/report/volume', payload))
|
|
110
|
+
{ data: response&.[]('volumes') } if response&.[]('volumes')
|
|
111
|
+
rescue StandardError => e
|
|
112
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
113
|
+
nil
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Get viewer analytics data
|
|
117
|
+
#
|
|
118
|
+
# @param payload [Hash] analytics parameters
|
|
119
|
+
# @option payload [String] :domain domain name or "All" for all domains
|
|
120
|
+
# @option payload [String] :startTime start time in ISO 8601 format
|
|
121
|
+
# @option payload [String] :endTime end time in ISO 8601 format
|
|
122
|
+
# @option payload [String] :interval time interval ("minute", "hour", "day")
|
|
123
|
+
#
|
|
124
|
+
# @return [Array, nil] array of viewer data points, or nil on error
|
|
125
|
+
#
|
|
126
|
+
# @example Get viewer statistics
|
|
127
|
+
# viewers = cdn.analytics.viewers({
|
|
128
|
+
# domain: "streaming.example.com",
|
|
129
|
+
# startTime: "2025-01-01T00:00:00Z",
|
|
130
|
+
# endTime: "2025-01-01T23:59:59Z",
|
|
131
|
+
# interval: "minute"
|
|
132
|
+
# })
|
|
133
|
+
# viewers.each { |point| puts "#{point['time']}: #{point['viewers']} viewers" }
|
|
134
|
+
#
|
|
135
|
+
# @since 1.0.0
|
|
136
|
+
def viewers(payload)
|
|
137
|
+
JSON.parse(@parent.send(:call, 'POST', '/api/report/viewers', payload))
|
|
138
|
+
rescue StandardError => e
|
|
139
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
140
|
+
nil
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Get requests per second (RPS) analytics
|
|
144
|
+
#
|
|
145
|
+
# @param payload [Hash] analytics parameters (passed as query string)
|
|
146
|
+
# @option payload [String] :domain domain name or "All" for all domains
|
|
147
|
+
# @option payload [String] :startTime start time in ISO 8601 format
|
|
148
|
+
# @option payload [String] :endTime end time in ISO 8601 format
|
|
149
|
+
# @option payload [String] :interval time interval
|
|
150
|
+
#
|
|
151
|
+
# @return [Hash, nil] RPS data with statistics and time series, or nil on error
|
|
152
|
+
#
|
|
153
|
+
# @example Get RPS data
|
|
154
|
+
# rps = cdn.analytics.request_per_second({
|
|
155
|
+
# domain: "api.example.com",
|
|
156
|
+
# startTime: "2025-01-01T12:00:00Z",
|
|
157
|
+
# endTime: "2025-01-01T13:00:00Z"
|
|
158
|
+
# })
|
|
159
|
+
# puts "Max RPS: #{rps[:maxQuantity]}"
|
|
160
|
+
# puts "Avg RPS: #{rps[:avgQuantity]}"
|
|
161
|
+
# puts "HTTP Total: #{rps[:httpTotalQuantity]}"
|
|
162
|
+
# puts "HTTPS Total: #{rps[:httpsTotalQuantity]}"
|
|
163
|
+
#
|
|
164
|
+
# @since 1.0.0
|
|
165
|
+
def request_per_second(payload)
|
|
166
|
+
response = JSON.parse(@parent.send(:call, 'GET', "/api/rps_chart_data?#{payload.to_query}"))
|
|
167
|
+
if response&.[]('datas')
|
|
168
|
+
{
|
|
169
|
+
maxQuantity: response['maxQuantity'],
|
|
170
|
+
avgQuantity: response['avgQuantity'],
|
|
171
|
+
httpTotalQuantity: response['httpTotalQuantity'],
|
|
172
|
+
httpsTotalQuantity: response['httpsTotalQuantity'],
|
|
173
|
+
data: response['datas'],
|
|
174
|
+
}
|
|
175
|
+
end
|
|
176
|
+
rescue StandardError => e
|
|
177
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
178
|
+
nil
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Get HTTP status code analytics
|
|
182
|
+
#
|
|
183
|
+
# @param payload [Hash] analytics parameters
|
|
184
|
+
# @option payload [Array<String>] :domains array of domain names
|
|
185
|
+
# @option payload [String] :startTime start time in ISO 8601 format
|
|
186
|
+
# @option payload [String] :endTime end time in ISO 8601 format
|
|
187
|
+
# @option payload [String] :interval time interval
|
|
188
|
+
#
|
|
189
|
+
# @return [Hash, nil] HTTP status code distribution data, or nil on error
|
|
190
|
+
#
|
|
191
|
+
# @example Get HTTP status codes
|
|
192
|
+
# codes = cdn.analytics.http_codes({
|
|
193
|
+
# domains: ["example.com"],
|
|
194
|
+
# startTime: "2025-01-01T00:00:00Z",
|
|
195
|
+
# endTime: "2025-01-01T23:59:59Z",
|
|
196
|
+
# interval: "hour"
|
|
197
|
+
# })
|
|
198
|
+
# puts "2xx responses: #{codes['2xx']}"
|
|
199
|
+
# puts "4xx responses: #{codes['4xx']}"
|
|
200
|
+
#
|
|
201
|
+
# @since 1.0.1
|
|
202
|
+
def http_codes(payload)
|
|
203
|
+
JSON.parse(@parent.send(:call, 'POST', "/api/report/customers/#{@parent.customer_id}/http_codes", payload))
|
|
204
|
+
rescue StandardError => e
|
|
205
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
206
|
+
nil
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Get referrer analytics by domain
|
|
210
|
+
#
|
|
211
|
+
# @param payload [Hash] analytics parameters
|
|
212
|
+
# @option payload [String] :customerId customer ID
|
|
213
|
+
# @option payload [String] :serviceName domain/service name
|
|
214
|
+
# @option payload [String] :startTime start time in ISO 8601 format
|
|
215
|
+
# @option payload [String] :endTime end time in ISO 8601 format
|
|
216
|
+
# @option payload [Integer] :pageNumber page number (0-based)
|
|
217
|
+
# @option payload [Integer] :pageSize number of results per page
|
|
218
|
+
#
|
|
219
|
+
# @return [Array] array of referrer data, or empty array on error
|
|
220
|
+
#
|
|
221
|
+
# @example Get top referrers
|
|
222
|
+
# referrers = cdn.analytics.referrer_by_domain({
|
|
223
|
+
# customerId: "12345",
|
|
224
|
+
# serviceName: "example.com",
|
|
225
|
+
# startTime: "2025-01-01T00:00:00Z",
|
|
226
|
+
# endTime: "2025-01-07T00:00:00Z",
|
|
227
|
+
# pageNumber: 0,
|
|
228
|
+
# pageSize: 20
|
|
229
|
+
# })
|
|
230
|
+
# referrers.each { |ref| puts "#{ref['referrer']}: #{ref['requests']} requests" }
|
|
231
|
+
#
|
|
232
|
+
# @since 1.0.1
|
|
233
|
+
def referrer_by_domain(payload)
|
|
234
|
+
response = JSON.parse(@parent.send(:call, 'POST', '/api/report/getReferrerByDomain', payload))
|
|
235
|
+
response&.[]('list') || []
|
|
236
|
+
rescue StandardError => e
|
|
237
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
238
|
+
[]
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# Get popular content URLs by domain
|
|
242
|
+
#
|
|
243
|
+
# @param payload [Hash] analytics parameters
|
|
244
|
+
# @option payload [String] :customerId customer ID
|
|
245
|
+
# @option payload [String] :serviceName domain/service name
|
|
246
|
+
# @option payload [String] :startTime start time in ISO 8601 format
|
|
247
|
+
# @option payload [String] :endTime end time in ISO 8601 format
|
|
248
|
+
# @option payload [Integer] :pageNumber page number (0-based)
|
|
249
|
+
# @option payload [Integer] :pageSize number of results per page
|
|
250
|
+
#
|
|
251
|
+
# @return [Array] array of popular URL data, or empty array on error
|
|
252
|
+
#
|
|
253
|
+
# @example Get most requested URLs
|
|
254
|
+
# urls = cdn.analytics.popular_content_url_by_domain({
|
|
255
|
+
# customerId: "12345",
|
|
256
|
+
# serviceName: "cdn.example.com",
|
|
257
|
+
# startTime: "2025-01-01T00:00:00Z",
|
|
258
|
+
# endTime: "2025-01-07T00:00:00Z",
|
|
259
|
+
# pageNumber: 0,
|
|
260
|
+
# pageSize: 50
|
|
261
|
+
# })
|
|
262
|
+
# urls.each { |url| puts "#{url['url']}: #{url['requests']} requests" }
|
|
263
|
+
#
|
|
264
|
+
# @since 1.0.1
|
|
265
|
+
def popular_content_url_by_domain(payload)
|
|
266
|
+
response = JSON.parse(@parent.send(:call, 'POST', '/api/report/getUrlByDomain', payload))
|
|
267
|
+
response&.[]('list') || []
|
|
268
|
+
rescue StandardError => e
|
|
269
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
270
|
+
[]
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
# Get origin request analytics
|
|
274
|
+
#
|
|
275
|
+
# @param payload [Hash] analytics parameters (passed as query string)
|
|
276
|
+
# @option payload [String] :domain domain name
|
|
277
|
+
# @option payload [String] :startTime start time in ISO 8601 format
|
|
278
|
+
# @option payload [String] :endTime end time in ISO 8601 format
|
|
279
|
+
# @option payload [String] :interval time interval
|
|
280
|
+
#
|
|
281
|
+
# @return [Hash, nil] origin request data with time series, or nil on error
|
|
282
|
+
#
|
|
283
|
+
# @example Get origin request data
|
|
284
|
+
# origin = cdn.analytics.origin_request({
|
|
285
|
+
# domain: "example.com",
|
|
286
|
+
# startTime: "2025-01-01T00:00:00Z",
|
|
287
|
+
# endTime: "2025-01-01T23:59:59Z",
|
|
288
|
+
# interval: "hour"
|
|
289
|
+
# })
|
|
290
|
+
# origin[:data].each { |point| puts "#{point['time']}: #{point['requests']} origin requests" }
|
|
291
|
+
#
|
|
292
|
+
# @since 1.0.0
|
|
293
|
+
def origin_request(payload)
|
|
294
|
+
response = JSON.parse(@parent.send(:call, 'GET', "/api/origin_request_chart_data?#{payload.to_query}"))
|
|
295
|
+
{ data: response['requestSpots'] } if response&.[]('requestSpots')
|
|
296
|
+
rescue StandardError => e
|
|
297
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
298
|
+
nil
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
# Get request hit rate analytics
|
|
302
|
+
#
|
|
303
|
+
# @param params [Hash] analytics parameters (passed as query string)
|
|
304
|
+
# @option params [String] :domain domain name or "All"
|
|
305
|
+
# @option params [String] :startTime start time in ISO 8601 format
|
|
306
|
+
# @option params [String] :endTime end time in ISO 8601 format
|
|
307
|
+
# @option params [String] :interval time interval
|
|
308
|
+
# @option params [Boolean] :fillFixedTime fill missing time slots
|
|
309
|
+
#
|
|
310
|
+
# @return [Hash, nil] hit rate data, or nil on error
|
|
311
|
+
#
|
|
312
|
+
# @since 1.0.8
|
|
313
|
+
def request_hit_rate(params)
|
|
314
|
+
query_string = URI.encode_www_form(params)
|
|
315
|
+
response = JSON.parse(@parent.send(:call, 'GET', "/api/hit_rate_chart_data?#{query_string}", nil))
|
|
316
|
+
response
|
|
317
|
+
rescue StandardError => e
|
|
318
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
319
|
+
nil
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
# Get byte hit rate analytics
|
|
323
|
+
#
|
|
324
|
+
# @param params [Hash] analytics parameters (passed as query string)
|
|
325
|
+
# @return [Hash, nil] byte hit rate data, or nil on error
|
|
326
|
+
# @since 1.0.8
|
|
327
|
+
def byte_hit_rate(params)
|
|
328
|
+
query_string = URI.encode_www_form(params)
|
|
329
|
+
response = JSON.parse(@parent.send(:call, 'GET', "/api/byte_rate_chart_data?#{query_string}", nil))
|
|
330
|
+
response
|
|
331
|
+
rescue StandardError => e
|
|
332
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
333
|
+
nil
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
# Get origin bandwidth analytics
|
|
337
|
+
#
|
|
338
|
+
# @param payload [Hash] analytics parameters
|
|
339
|
+
# @return [Array] origin bandwidth data, or empty array on error
|
|
340
|
+
# @since 1.0.8
|
|
341
|
+
def origin_bandwidth(payload)
|
|
342
|
+
response = JSON.parse(@parent.send(:call, 'POST', '/api/report/origin_bandwidth', payload))
|
|
343
|
+
response || []
|
|
344
|
+
rescue StandardError => e
|
|
345
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
346
|
+
[]
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
# Get number of concurrent viewers by domain
|
|
350
|
+
#
|
|
351
|
+
# @param payload [Hash] analytics parameters
|
|
352
|
+
# @return [Array] concurrent viewer data, or empty array on error
|
|
353
|
+
# @since 1.0.8
|
|
354
|
+
def number_of_concurrent_viewers(payload)
|
|
355
|
+
response = JSON.parse(@parent.send(:call, 'POST', '/api/report/domain/viewers', payload))
|
|
356
|
+
response || []
|
|
357
|
+
rescue StandardError => e
|
|
358
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
359
|
+
[]
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
# Get origin HTTP status codes
|
|
363
|
+
#
|
|
364
|
+
# @param payload [Hash] analytics parameters
|
|
365
|
+
# @return [Array] origin HTTP code data, or empty array on error
|
|
366
|
+
# @since 1.0.8
|
|
367
|
+
def origin_http_codes(payload)
|
|
368
|
+
customer_id = @parent.send(:customer_id)
|
|
369
|
+
response = JSON.parse(@parent.send(:call, 'POST', "/api/report/customers/#{customer_id}/origin_http_codes", payload))
|
|
370
|
+
response || []
|
|
371
|
+
rescue StandardError => e
|
|
372
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
373
|
+
[]
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
# Get total referrer count by domain
|
|
377
|
+
#
|
|
378
|
+
# @param payload [Hash] analytics parameters
|
|
379
|
+
# @return [Hash, nil] total referrer data, or nil on error
|
|
380
|
+
# @since 1.0.8
|
|
381
|
+
def referrer_total_by_domain(payload)
|
|
382
|
+
response = JSON.parse(@parent.send(:call, 'POST', '/api/report/getReferrerTotalByDomain', payload))
|
|
383
|
+
response
|
|
384
|
+
rescue StandardError => e
|
|
385
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
386
|
+
nil
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
# Get referrer CSV export by domain
|
|
390
|
+
#
|
|
391
|
+
# @param payload [Hash] analytics parameters with csvRequest: 1
|
|
392
|
+
# @return [String, nil] CSV data, or nil on error
|
|
393
|
+
# @since 1.0.8
|
|
394
|
+
def referrer_csv_by_domain(payload)
|
|
395
|
+
response = @parent.send(:call, 'POST', '/api/report/getReferrerCsvByDomain', payload)
|
|
396
|
+
response
|
|
397
|
+
rescue StandardError => e
|
|
398
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
399
|
+
nil
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
# Get total popular content URL count by domain
|
|
403
|
+
#
|
|
404
|
+
# @param payload [Hash] analytics parameters
|
|
405
|
+
# @return [Hash, nil] total URL data, or nil on error
|
|
406
|
+
# @since 1.0.8
|
|
407
|
+
def popular_content_url_total_by_domain(payload)
|
|
408
|
+
response = JSON.parse(@parent.send(:call, 'POST', '/api/report/getUrlTotalByDomain', payload))
|
|
409
|
+
response
|
|
410
|
+
rescue StandardError => e
|
|
411
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
412
|
+
nil
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
# Get popular content URL CSV export by domain
|
|
416
|
+
#
|
|
417
|
+
# @param payload [Hash] analytics parameters with csvRequest: 1
|
|
418
|
+
# @return [String, nil] CSV data, or nil on error
|
|
419
|
+
# @since 1.0.8
|
|
420
|
+
def popular_content_url_csv_by_domain(payload)
|
|
421
|
+
response = @parent.send(:call, 'POST', '/api/report/getUrlCsvByDomain', payload)
|
|
422
|
+
response
|
|
423
|
+
rescue StandardError => e
|
|
424
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
425
|
+
nil
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
# Get request and visit number statistics
|
|
429
|
+
#
|
|
430
|
+
# @param payload [Hash] analytics parameters
|
|
431
|
+
# @return [Hash, nil] request/visit statistics, or nil on error
|
|
432
|
+
# @since 1.0.8
|
|
433
|
+
def request_visit_number(payload)
|
|
434
|
+
response = JSON.parse(@parent.send(:call, 'POST', '/api/report/request_visit_number', payload))
|
|
435
|
+
response
|
|
436
|
+
rescue StandardError => e
|
|
437
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
438
|
+
nil
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
# Get ISP analytics
|
|
442
|
+
#
|
|
443
|
+
# @param payload [Hash] analytics parameters
|
|
444
|
+
# @return [Array] ISP data, or empty array on error
|
|
445
|
+
# @since 1.0.8
|
|
446
|
+
def isp(payload)
|
|
447
|
+
response = JSON.parse(@parent.send(:call, 'POST', '/api/report/isp', payload))
|
|
448
|
+
response || []
|
|
449
|
+
rescue StandardError => e
|
|
450
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
451
|
+
[]
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
# Get user agent analytics by domain
|
|
455
|
+
#
|
|
456
|
+
# @param payload [Hash] analytics parameters
|
|
457
|
+
# @return [Array] user agent data, or empty array on error
|
|
458
|
+
# @since 1.0.8
|
|
459
|
+
def user_agent(payload)
|
|
460
|
+
response = JSON.parse(@parent.send(:call, 'POST', '/api/report/domain/userAgent', payload))
|
|
461
|
+
response&.[]('list') || []
|
|
462
|
+
rescue StandardError => e
|
|
463
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
464
|
+
[]
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
# Get user agent CSV export by domain
|
|
468
|
+
#
|
|
469
|
+
# @param payload [Hash] analytics parameters
|
|
470
|
+
# @return [String, nil] CSV data, or nil on error
|
|
471
|
+
# @since 1.0.8
|
|
472
|
+
def user_agent_csv(payload)
|
|
473
|
+
response = @parent.send(:call, 'POST', '/api/report/domain/userAgentCsv', payload)
|
|
474
|
+
response
|
|
475
|
+
rescue StandardError => e
|
|
476
|
+
@parent.send(:logger).error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
477
|
+
nil
|
|
478
|
+
end
|
|
479
|
+
end
|
|
480
|
+
end
|
|
481
|
+
end
|
|
482
|
+
end
|
|
483
|
+
end
|