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,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Conversant
|
|
4
|
+
module V3
|
|
5
|
+
module Services
|
|
6
|
+
class VMS
|
|
7
|
+
class Partner
|
|
8
|
+
# VMS Business analytics for partner-level business reporting
|
|
9
|
+
#
|
|
10
|
+
# Provides business-focused analytics methods that aggregate transcoding
|
|
11
|
+
# data for VOD (Video on Demand) billing and capacity planning.
|
|
12
|
+
#
|
|
13
|
+
# @since 1.0.16
|
|
14
|
+
class Business
|
|
15
|
+
# @return [Conversant::V3::Services::VMS::Partner::Analytics] the parent analytics instance
|
|
16
|
+
attr_reader :parent
|
|
17
|
+
|
|
18
|
+
# Initialize partner VMS business service
|
|
19
|
+
#
|
|
20
|
+
# @param parent [Conversant::V3::Services::VMS::Partner::Analytics] the parent analytics instance
|
|
21
|
+
def initialize(parent)
|
|
22
|
+
@parent = parent
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Fetches transcoding business analytics with codec breakdown
|
|
26
|
+
#
|
|
27
|
+
# Aggregates VOD transcoding data including transmuxing and transcoding
|
|
28
|
+
# across different resolutions (SD, HD, UHD) and codecs (H264, H265).
|
|
29
|
+
#
|
|
30
|
+
# @param args [Hash] Parameters for the query
|
|
31
|
+
# @option args [Time, String] :startTime start time for the report (defaults to beginning of current month)
|
|
32
|
+
# @option args [String, Integer] :type customer type filter (defaults to 2)
|
|
33
|
+
#
|
|
34
|
+
# @return [Hash] Transcoding business data with breakdown by codec and resolution. Hash contains:
|
|
35
|
+
# - :vms_transcoding [Float] total transcoding duration
|
|
36
|
+
# - :vms_transmuxing [Float] transmuxing duration
|
|
37
|
+
# - :vms_transcoding_sd [Float] SD transcoding duration
|
|
38
|
+
# - :vms_transcoding_hd [Float] HD transcoding duration
|
|
39
|
+
# - :vms_transcoding_uhd [Float] UHD transcoding duration
|
|
40
|
+
#
|
|
41
|
+
# @example Get VOD transcoding business metrics
|
|
42
|
+
# vms = Conversant::V3.vms(12345)
|
|
43
|
+
# business = vms.partner.analytics.business
|
|
44
|
+
# metrics = business.transcoding(startTime: Time.now.beginning_of_month)
|
|
45
|
+
# puts "Total transcoding: #{metrics[:vms_transcoding]} minutes"
|
|
46
|
+
# puts "SD: #{metrics[:vms_transcoding_sd]}, HD: #{metrics[:vms_transcoding_hd]}, UHD: #{metrics[:vms_transcoding_uhd]}"
|
|
47
|
+
#
|
|
48
|
+
# @since 1.0.16
|
|
49
|
+
def transcoding(**args)
|
|
50
|
+
transcoding = {
|
|
51
|
+
vms_transcoding: 0,
|
|
52
|
+
vms_transmuxing: 0,
|
|
53
|
+
vms_transcoding_sd: 0,
|
|
54
|
+
vms_transcoding_hd: 0,
|
|
55
|
+
vms_transcoding_uhd: 0
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
data = @parent.duration_of_vod(**args).first
|
|
59
|
+
return transcoding if data.nil?
|
|
60
|
+
|
|
61
|
+
name = data.keys.first
|
|
62
|
+
|
|
63
|
+
if data[name].present?
|
|
64
|
+
data[name].each do |item|
|
|
65
|
+
transcoding[:vms_transmuxing] += item['transmux'].to_f
|
|
66
|
+
transcoding[:vms_transcoding_sd] += item['h264SdTranscoding'].to_f + item['h265SdTranscoding'].to_f
|
|
67
|
+
transcoding[:vms_transcoding_hd] += item['h264HdTranscoding'].to_f + item['h265HdTranscoding'].to_f
|
|
68
|
+
transcoding[:vms_transcoding_uhd] += item['h264UhdTranscoding'].to_f + item['h265UhdTranscoding'].to_f
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
transcoding[:vms_transcoding] =
|
|
73
|
+
transcoding[:vms_transcoding_sd] + transcoding[:vms_transcoding_hd] + transcoding[:vms_transcoding_uhd]
|
|
74
|
+
transcoding
|
|
75
|
+
rescue StandardError => e
|
|
76
|
+
logger.error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
77
|
+
transcoding
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
def logger
|
|
83
|
+
@parent.send(:logger)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Conversant
|
|
4
|
+
module V3
|
|
5
|
+
module Services
|
|
6
|
+
class VMS
|
|
7
|
+
# Partner service for VMS partner-level operations
|
|
8
|
+
#
|
|
9
|
+
# Provides access to partner-level analytics for Video Management System
|
|
10
|
+
# that aggregate data across multiple customer accounts.
|
|
11
|
+
#
|
|
12
|
+
# @example Access partner analytics
|
|
13
|
+
# vms = Conversant::V3.vms(12345)
|
|
14
|
+
#
|
|
15
|
+
# # Partner-level VMS analytics
|
|
16
|
+
# transcoding = vms.partner.analytics.transcoding({
|
|
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 [VMS] the parent VMS service instance
|
|
24
|
+
attr_reader :parent
|
|
25
|
+
|
|
26
|
+
# Initialize partner service
|
|
27
|
+
#
|
|
28
|
+
# @param parent [VMS] the parent VMS 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 VMS services including transcoding
|
|
36
|
+
# duration, volume, and processing metrics across multiple customers.
|
|
37
|
+
#
|
|
38
|
+
# @return [Analytics] VMS partner analytics service
|
|
39
|
+
# @since 1.0.12
|
|
40
|
+
def analytics
|
|
41
|
+
@analytics ||= Analytics.new(@parent)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def logger
|
|
47
|
+
@parent.send(:logger)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Load nested analytics class after Partner is defined
|
|
56
|
+
require_relative 'partner/analytics'
|
|
57
|
+
require_relative 'partner/business'
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Conversant
|
|
4
|
+
module V3
|
|
5
|
+
module Services
|
|
6
|
+
class VMS
|
|
7
|
+
# Video transcoding service for job and preset management
|
|
8
|
+
#
|
|
9
|
+
# Provides comprehensive job and preset management functionality for
|
|
10
|
+
# video transcoding operations including:
|
|
11
|
+
# - Transcoding job listing and filtering
|
|
12
|
+
# - Preset configuration management
|
|
13
|
+
# - Job status tracking
|
|
14
|
+
#
|
|
15
|
+
# @example Manage transcoding jobs
|
|
16
|
+
# vms = Conversant::V3.vms(12345)
|
|
17
|
+
#
|
|
18
|
+
# # Get recent transcoding jobs
|
|
19
|
+
# jobs = vms.transcoding.jobs(page_size: 50, job_status: 2)
|
|
20
|
+
#
|
|
21
|
+
# jobs.each do |job|
|
|
22
|
+
# puts "Job #{job['id']}: #{job['file_name']} - #{job['status']}"
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
# # Get available presets
|
|
26
|
+
# presets = vms.transcoding.presets
|
|
27
|
+
#
|
|
28
|
+
# @since 1.0.0
|
|
29
|
+
class Transcoding
|
|
30
|
+
# @return [VMS] the parent VMS service instance
|
|
31
|
+
attr_reader :parent
|
|
32
|
+
|
|
33
|
+
# Initialize VOD transcoding service
|
|
34
|
+
#
|
|
35
|
+
# @param parent [VMS] the parent VMS service instance
|
|
36
|
+
def initialize(parent)
|
|
37
|
+
@parent = parent
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Get list of transcoding jobs
|
|
41
|
+
#
|
|
42
|
+
# Retrieves a paginated list of video transcoding jobs with filtering options.
|
|
43
|
+
# Returns detailed information about each job including status, file name,
|
|
44
|
+
# transcoding configurations, and timestamps.
|
|
45
|
+
#
|
|
46
|
+
# @param payload [Hash] query parameters for filtering and pagination
|
|
47
|
+
# @option payload [Integer] :page_number page number (default: 1)
|
|
48
|
+
# @option payload [Integer] :page_size number of results per page (default: 20)
|
|
49
|
+
# @option payload [Integer] :job_status filter by job status (-1 for all)
|
|
50
|
+
# @option payload [Integer] :source_type filter by source type (-1 for all)
|
|
51
|
+
# @option payload [Integer] :output_format filter by output format (-1 for all)
|
|
52
|
+
# @option payload [Integer] :protection_type filter by protection type (-1 for all)
|
|
53
|
+
# @option payload [String] :file_name filter by file name
|
|
54
|
+
# @option payload [String] :period time period filter (e.g., '0_30' for last 30 days)
|
|
55
|
+
# @option payload [Integer] :job_type job type filter (default: 1)
|
|
56
|
+
#
|
|
57
|
+
# @return [Array<Hash>] array of transcoding job records, or empty array on error
|
|
58
|
+
#
|
|
59
|
+
# @example Get recent transcoding jobs
|
|
60
|
+
# jobs = vms.vod_transcoding.jobs(page_size: 50)
|
|
61
|
+
# jobs.each { |job| puts "#{job['file_name']}: #{job['status']}" }
|
|
62
|
+
#
|
|
63
|
+
# @example Filter by status
|
|
64
|
+
# active_jobs = vms.vod_transcoding.jobs(job_status: 2, page_size: 100)
|
|
65
|
+
#
|
|
66
|
+
# @since 1.0.0
|
|
67
|
+
def jobs(payload = {})
|
|
68
|
+
default_payload = {
|
|
69
|
+
sEcho: 1,
|
|
70
|
+
iColumns: 9,
|
|
71
|
+
sColumns: nil,
|
|
72
|
+
iDisplayStart: 0,
|
|
73
|
+
iDisplayLength: 20,
|
|
74
|
+
mDataProp_0: 'id',
|
|
75
|
+
mDataProp_1: 'file_name',
|
|
76
|
+
mDataProp_2: 'transcoding_configs',
|
|
77
|
+
mDataProp_3: 'created',
|
|
78
|
+
mDataProp_4: 'source_type',
|
|
79
|
+
mDataProp_5: 'ended',
|
|
80
|
+
mDataProp_6: 'transcoding_configs',
|
|
81
|
+
mDataProp_7: 'status',
|
|
82
|
+
mDataProp_8: 'id',
|
|
83
|
+
iSortingCols: '0',
|
|
84
|
+
bSortable_0: 'false',
|
|
85
|
+
bSortable_1: 'true',
|
|
86
|
+
bSortable_2: 'false',
|
|
87
|
+
bSortable_3: 'true',
|
|
88
|
+
bSortable_4: 'false',
|
|
89
|
+
bSortable_5: 'true',
|
|
90
|
+
bSortable_6: 'false',
|
|
91
|
+
bSortable_7: 'false',
|
|
92
|
+
bSortable_8: 'false',
|
|
93
|
+
page_number: 1,
|
|
94
|
+
page_size: 20,
|
|
95
|
+
sort_field: nil,
|
|
96
|
+
sort_type: nil,
|
|
97
|
+
job_status: -1,
|
|
98
|
+
source_type: -1,
|
|
99
|
+
output_format: -1,
|
|
100
|
+
protection_type: -1,
|
|
101
|
+
file_name: nil,
|
|
102
|
+
period: '0_30',
|
|
103
|
+
job_type: 1,
|
|
104
|
+
_: (Time.now.to_f * 1000).to_i
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
merged_payload = default_payload.merge(payload)
|
|
108
|
+
response = @parent.send(:call, 'GET', "/v2/jobs?#{merged_payload.to_query}")
|
|
109
|
+
return [] if response.nil?
|
|
110
|
+
|
|
111
|
+
JSON.parse(response)&.[]("list") || []
|
|
112
|
+
rescue StandardError => e
|
|
113
|
+
logger.error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
114
|
+
[]
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Get list of transcoding presets
|
|
118
|
+
#
|
|
119
|
+
# Retrieves a paginated list of transcoding preset configurations.
|
|
120
|
+
# Presets define encoding parameters such as resolution, bitrate,
|
|
121
|
+
# codec settings, and output formats.
|
|
122
|
+
#
|
|
123
|
+
# @param payload [Hash] query parameters for pagination
|
|
124
|
+
# @option payload [Integer] :page_number page number (default: 1)
|
|
125
|
+
# @option payload [Integer] :page_size number of results per page (default: 20)
|
|
126
|
+
#
|
|
127
|
+
# @return [Array<Hash>] array of transcoding preset configurations, or empty array on error
|
|
128
|
+
#
|
|
129
|
+
# @example Get available presets
|
|
130
|
+
# presets = vms.vod_transcoding.presets
|
|
131
|
+
# presets.each do |preset|
|
|
132
|
+
# puts "#{preset['name']}: #{preset['description']}"
|
|
133
|
+
# end
|
|
134
|
+
#
|
|
135
|
+
# @example Get first page with custom size
|
|
136
|
+
# presets = vms.vod_transcoding.presets(page_number: 1, page_size: 50)
|
|
137
|
+
#
|
|
138
|
+
# @since 1.0.0
|
|
139
|
+
def presets(payload = {})
|
|
140
|
+
default_payload = {
|
|
141
|
+
sEcho: 1,
|
|
142
|
+
iColumns: 5,
|
|
143
|
+
sColumns: nil,
|
|
144
|
+
iDisplayStart: 0,
|
|
145
|
+
iDisplayLength: 20,
|
|
146
|
+
mDataProp_0: 'id',
|
|
147
|
+
mDataProp_1: 'name',
|
|
148
|
+
mDataProp_2: 'id',
|
|
149
|
+
mDataProp_3: 'description',
|
|
150
|
+
mDataProp_4: 'id',
|
|
151
|
+
iSortingCols: '0',
|
|
152
|
+
bSortable_0: 'false',
|
|
153
|
+
bSortable_1: 'false',
|
|
154
|
+
bSortable_2: 'false',
|
|
155
|
+
bSortable_3: 'false',
|
|
156
|
+
bSortable_4: 'false',
|
|
157
|
+
page_number: 1,
|
|
158
|
+
page_size: 20,
|
|
159
|
+
_: (Time.now.to_f * 1000).to_i
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
merged_payload = default_payload.merge(payload)
|
|
163
|
+
response = @parent.send(:call, 'GET', "/v2/osp/presets?#{merged_payload.to_query}")
|
|
164
|
+
return [] if response.nil?
|
|
165
|
+
|
|
166
|
+
JSON.parse(response)&.[]("list") || []
|
|
167
|
+
rescue StandardError => e
|
|
168
|
+
logger.error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
|
|
169
|
+
[]
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
private
|
|
173
|
+
|
|
174
|
+
# Get logger instance from parent
|
|
175
|
+
#
|
|
176
|
+
# @return [Logger] logger instance
|
|
177
|
+
def logger
|
|
178
|
+
@parent.send(:logger)
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'authorization'
|
|
4
|
+
|
|
5
|
+
module Conversant
|
|
6
|
+
module V3
|
|
7
|
+
module Services
|
|
8
|
+
# Video Management System (VMS) service for video processing and management
|
|
9
|
+
#
|
|
10
|
+
# Provides comprehensive functionality for video operations including:
|
|
11
|
+
# - VOD (Video on Demand) transcoding management
|
|
12
|
+
# - Analytics for video metrics and usage
|
|
13
|
+
# - Business metrics for billing and reporting
|
|
14
|
+
#
|
|
15
|
+
# @example Basic usage
|
|
16
|
+
# vms = Conversant::V3.vms(12345)
|
|
17
|
+
#
|
|
18
|
+
# # Get transcoding jobs
|
|
19
|
+
# jobs = vms.transcoding.jobs(page_number: 1)
|
|
20
|
+
#
|
|
21
|
+
# # Get analytics
|
|
22
|
+
# volume = vms.analytics.volume(startTime: '2025-01-01')
|
|
23
|
+
#
|
|
24
|
+
# @since 1.0.0
|
|
25
|
+
class VMS < ::Conversant::V3::Base
|
|
26
|
+
include Authorization
|
|
27
|
+
|
|
28
|
+
# Get transcoding service instance
|
|
29
|
+
#
|
|
30
|
+
# @return [Transcoding] transcoding service for job management
|
|
31
|
+
# @since 1.0.0
|
|
32
|
+
def transcoding
|
|
33
|
+
@transcoding ||= Transcoding.new(self)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Get analytics service instance
|
|
37
|
+
#
|
|
38
|
+
# @return [Analytics] analytics service for video metrics
|
|
39
|
+
# @since 1.0.0
|
|
40
|
+
def analytics
|
|
41
|
+
@analytics ||= Analytics.new(self)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Get business metrics service instance
|
|
45
|
+
#
|
|
46
|
+
# @return [Business] business service for billing metrics
|
|
47
|
+
# @since 1.0.0
|
|
48
|
+
def business
|
|
49
|
+
@business ||= Business.new(self)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Get partner service instance
|
|
53
|
+
#
|
|
54
|
+
# Provides access to partner-level analytics for Video Management System
|
|
55
|
+
# that aggregate data across multiple customer accounts.
|
|
56
|
+
#
|
|
57
|
+
# @return [Partner] partner service for VMS analytics
|
|
58
|
+
# @since 1.0.12
|
|
59
|
+
#
|
|
60
|
+
# @example Access partner analytics
|
|
61
|
+
# vms = Conversant::V3.vms(12345)
|
|
62
|
+
# transcoding = vms.partner.analytics.transcoding(payload)
|
|
63
|
+
def partner
|
|
64
|
+
@partner ||= Partner.new(self)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# @deprecated Use {#partner} instead
|
|
68
|
+
# Get partner analytics service instance (deprecated)
|
|
69
|
+
#
|
|
70
|
+
# @return [VMS::Partner::Analytics] partner analytics for VMS reporting
|
|
71
|
+
# @since 1.0.8
|
|
72
|
+
# @deprecated Use `vms.partner.analytics` instead of `vms.partner_analytics`
|
|
73
|
+
def partner_analytics
|
|
74
|
+
@partner_analytics ||= Partner::Analytics.new(self)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
protected
|
|
78
|
+
|
|
79
|
+
def call(method, uri, payload = nil)
|
|
80
|
+
url = "#{configuration.private_vms_endpoint}#{uri}"
|
|
81
|
+
|
|
82
|
+
headers = authorized_headers
|
|
83
|
+
|
|
84
|
+
# Check for JSESSIONID in Cookie header
|
|
85
|
+
if headers['Cookie'].nil? || !headers['Cookie'].include?('JSESSIONID=')
|
|
86
|
+
logger.error "#{identifier}.METHOD:call.NO_JSESSIONID"
|
|
87
|
+
raise AuthenticationError, 'Missing JSESSIONID for VMS'
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
code, response = request(method, url, payload, headers)
|
|
91
|
+
|
|
92
|
+
if code >= 400
|
|
93
|
+
logger.error "#{identifier}.METHOD:call.HTTP_ERROR:#{code}"
|
|
94
|
+
raise ApiError, "VMS API error: #{code}"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
response.body
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
private
|
|
101
|
+
|
|
102
|
+
def fetch_new_session
|
|
103
|
+
sessions = authenticate
|
|
104
|
+
return nil unless sessions && sessions[:session] && sessions[:sso_gw_session2]
|
|
105
|
+
|
|
106
|
+
timestamp = (Time.now.to_f * 1000).to_i
|
|
107
|
+
reporting_url = "#{configuration.private_vms_endpoint}/reporting/vms/federation/business/usage"
|
|
108
|
+
reporting_url += "?customerId=#{customer_id}&type=#{type || 2}&t=#{timestamp}"
|
|
109
|
+
|
|
110
|
+
logger.debug "#{identifier}.METHOD:authorize.REQUESTING_JSESSIONID"
|
|
111
|
+
|
|
112
|
+
response = RestClient.get(
|
|
113
|
+
reporting_url,
|
|
114
|
+
{
|
|
115
|
+
authority: URI.parse(configuration.private_vms_endpoint).hostname,
|
|
116
|
+
referer: portal_endpoint,
|
|
117
|
+
user_agent: configuration.default_ua,
|
|
118
|
+
cookies: {
|
|
119
|
+
'SESSION': sessions[:session],
|
|
120
|
+
'SSO_GW_SESSION2': sessions[:sso_gw_session2]
|
|
121
|
+
},
|
|
122
|
+
timeout: 30,
|
|
123
|
+
open_timeout: 30
|
|
124
|
+
}
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
if response.cookies['JSESSIONID']
|
|
128
|
+
jsessionid = response.cookies['JSESSIONID']
|
|
129
|
+
redis.set(session_cache_key, jsessionid, ex: configuration.cache_ttl)
|
|
130
|
+
logger.debug "#{identifier}.METHOD:authorize.JSESSIONID_OBTAINED"
|
|
131
|
+
jsessionid
|
|
132
|
+
else
|
|
133
|
+
logger.error "#{identifier}.METHOD:authorize.NO_JSESSIONID_IN_RESPONSE"
|
|
134
|
+
nil
|
|
135
|
+
end
|
|
136
|
+
rescue RestClient::Unauthorized, RestClient::Forbidden => e
|
|
137
|
+
logger.error "#{identifier}.METHOD:authorize.AUTH_ERROR:#{e.message}"
|
|
138
|
+
nil
|
|
139
|
+
rescue StandardError => e
|
|
140
|
+
logger.error "#{identifier}.METHOD:authorize.ERROR:#{e.message}"
|
|
141
|
+
nil
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
protected
|
|
145
|
+
|
|
146
|
+
def service_endpoint
|
|
147
|
+
configuration.private_vms_endpoint
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def session_cookie_name
|
|
151
|
+
'JSESSIONID'
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def requires_session?
|
|
155
|
+
true
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Load nested service classes after VMS is defined
|
|
163
|
+
require_relative 'vms/transcoding'
|
|
164
|
+
require_relative 'vms/analytics'
|
|
165
|
+
require_relative 'vms/business'
|
|
166
|
+
require_relative 'vms/partner'
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'v3/http_client'
|
|
4
|
+
require_relative 'v3/base'
|
|
5
|
+
require_relative 'v3/mixins/authentication'
|
|
6
|
+
require_relative 'v3/services/portal'
|
|
7
|
+
require_relative 'v3/services/cdn'
|
|
8
|
+
require_relative 'v3/services/lms'
|
|
9
|
+
require_relative 'v3/services/vms'
|
|
10
|
+
require_relative 'v3/services/oss'
|
|
11
|
+
|
|
12
|
+
module Conversant
|
|
13
|
+
module V3
|
|
14
|
+
class << self
|
|
15
|
+
def portal(customer_id, type = 2)
|
|
16
|
+
Services::Portal.new(customer_id, type)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def cdn(customer_id, type = 2)
|
|
20
|
+
Services::CDN.new(customer_id, type)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def lms(customer_id, type = 2)
|
|
24
|
+
Services::LMS.new(customer_id, type)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def vms(customer_id, type = 2)
|
|
28
|
+
Services::VMS.new(customer_id, type)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def oss(customer_id, type = 2)
|
|
32
|
+
Services::OSS.new(customer_id, type)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/conversant.rb
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rest-client'
|
|
4
|
+
require 'json'
|
|
5
|
+
require 'redis'
|
|
6
|
+
require 'cgi'
|
|
7
|
+
require 'logger'
|
|
8
|
+
require 'uri'
|
|
9
|
+
require 'ostruct'
|
|
10
|
+
require 'date'
|
|
11
|
+
require 'time'
|
|
12
|
+
|
|
13
|
+
require_relative 'conversant/version'
|
|
14
|
+
require_relative 'conversant/configuration'
|
|
15
|
+
require_relative 'conversant/v3'
|
|
16
|
+
|
|
17
|
+
# Conversant Ruby Gem
|
|
18
|
+
#
|
|
19
|
+
# A Ruby client library for interacting with Conversant/SwiftFederation CDN services.
|
|
20
|
+
# Provides clean interfaces for Portal, CDN, and LMS APIs with V3 authentication support.
|
|
21
|
+
#
|
|
22
|
+
# @example Basic usage with zero configuration
|
|
23
|
+
# # If ENV variables are already set, just use it:
|
|
24
|
+
# portal = Conversant::V3.portal(customer_id)
|
|
25
|
+
# cdn = Conversant::V3.cdn(customer_id)
|
|
26
|
+
# lms = Conversant::V3.lms(customer_id)
|
|
27
|
+
#
|
|
28
|
+
# @example Manual configuration
|
|
29
|
+
# Conversant.configure do |config|
|
|
30
|
+
# config.private_cdn_endpoint = 'https://cdn.example.com'
|
|
31
|
+
# config.private_lms_endpoint = 'https://lms.example.com'
|
|
32
|
+
# config.redis = Redis.new(url: ENV['REDIS_URL'])
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
# @see https://gitlab.vnetwork.dev/gems/conversant
|
|
36
|
+
# @author Tho Nguyen
|
|
37
|
+
module Conversant
|
|
38
|
+
# Base error class for all Conversant errors
|
|
39
|
+
class Error < StandardError; end
|
|
40
|
+
|
|
41
|
+
# Raised when authentication fails
|
|
42
|
+
class AuthenticationError < Error; end
|
|
43
|
+
|
|
44
|
+
# Raised when API calls fail
|
|
45
|
+
class ApiError < Error; end
|
|
46
|
+
|
|
47
|
+
class << self
|
|
48
|
+
# @return [Configuration] the global configuration object
|
|
49
|
+
attr_accessor :configuration
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Configure the Conversant gem
|
|
53
|
+
#
|
|
54
|
+
# @yield [config] Configuration object
|
|
55
|
+
# @yieldparam config [Configuration] the configuration object
|
|
56
|
+
# @return [Configuration] the configuration object
|
|
57
|
+
#
|
|
58
|
+
# @example
|
|
59
|
+
# Conversant.configure do |config|
|
|
60
|
+
# config.cache_ttl = 3600
|
|
61
|
+
# config.debug_mode = true
|
|
62
|
+
# end
|
|
63
|
+
def self.configure
|
|
64
|
+
self.configuration ||= Configuration.new
|
|
65
|
+
yield(configuration) if block_given?
|
|
66
|
+
configuration
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Auto-configure from environment variables
|
|
70
|
+
#
|
|
71
|
+
# Automatically loads configuration from ENV variables and validates.
|
|
72
|
+
# Uses existing CONVERSANT environment variables as defaults.
|
|
73
|
+
#
|
|
74
|
+
# @return [Configuration] the configured object
|
|
75
|
+
# @raise [Error] if required configuration is missing
|
|
76
|
+
#
|
|
77
|
+
# @example
|
|
78
|
+
# Conversant.auto_configure!
|
|
79
|
+
def self.auto_configure!
|
|
80
|
+
self.configuration = Configuration.new
|
|
81
|
+
|
|
82
|
+
# Auto-detect and set Redis if available
|
|
83
|
+
if defined?($redis) && $redis
|
|
84
|
+
configuration.redis = $redis
|
|
85
|
+
elsif defined?(Redis) && ENV['REDIS_URL']
|
|
86
|
+
configuration.redis = Redis.new(url: ENV['REDIS_URL'])
|
|
87
|
+
elsif defined?(Redis)
|
|
88
|
+
configuration.redis = Redis.new
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
configuration.validate!
|
|
92
|
+
configuration
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Reset configuration to defaults
|
|
96
|
+
#
|
|
97
|
+
# @return [Configuration] new configuration object
|
|
98
|
+
def self.reset_configuration!
|
|
99
|
+
self.configuration = Configuration.new
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Check if gem is configured
|
|
103
|
+
#
|
|
104
|
+
# @return [Boolean] true if configured, false otherwise
|
|
105
|
+
def self.configured?
|
|
106
|
+
!configuration.nil?
|
|
107
|
+
end
|
|
108
|
+
end
|