Skip to content

Commit 9347663

Browse files
authored
Added delete recording functionality to s3 (#1258)
1 parent e763c5b commit 9347663

2 files changed

Lines changed: 52 additions & 3 deletions

File tree

app/controllers/bigbluebutton_api_controller.rb

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -498,15 +498,30 @@ def delete_recordings
498498
query_params = { record_id: params[:recordID].split(',') }
499499
query_params[:metadata] = { key: 'tenant-id', value: @tenant.id } if @tenant.present? # filter based on tenant
500500

501-
query = Recording.includes(:metadata).where(query_params).load
501+
query = Recording.includes(:metadata, :playback_formats).where(query_params).load
502502
raise BBBError.new('notFound', 'We could not find recordings') if query.none?
503503

504+
s3_client = Aws::S3::Client.new if ENV['S3_RECORDING']
505+
504506
query.each do |rec|
505507
# Start transaction + lock record
506508
rec.with_lock do
507509
logger.debug("Deleting recording: #{rec.record_id}")
508-
# TODO: check the unpublished dir when it is implemented
509-
FileUtils.rm_r(Dir.glob(File.join(Rails.configuration.x.recording_publish_dir, '/*/', rec.record_id)))
510+
if ENV['S3_RECORDING']
511+
bucket = ENV.fetch('S3_BUCKET_NAME')
512+
state = rec.published ? 'published' : 'unpublished'
513+
514+
rec.playback_formats.each do |playback_format|
515+
prefix = "#{state}/#{playback_format.format}/#{rec.record_id}/"
516+
objects = s3_client.list_objects_v2(bucket: bucket, prefix: prefix).contents
517+
next if objects.empty?
518+
519+
s3_client.delete_objects(bucket: bucket, delete: { objects: objects.map { |o| { key: o.key } } })
520+
end
521+
else
522+
# TODO: check the unpublished dir when it is implemented
523+
FileUtils.rm_r(Dir.glob(File.join(Rails.configuration.x.recording_publish_dir, '/*/', rec.record_id)))
524+
end
510525
rec.mark_delete!
511526
rescue StandardError => e
512527
logger.warn("Error #{e} deleting recording #{rec.record_id}")

spec/requests/bigbluebutton_api_controller_spec.rb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2536,6 +2536,40 @@
25362536
end
25372537
end
25382538

2539+
context 'with S3 recording storage enabled' do
2540+
let(:s3_client) { Aws::S3::Client.new(stub_responses: true, region: 'us-east-1') }
2541+
2542+
before do
2543+
ENV['S3_RECORDING'] = 'true'
2544+
ENV['S3_BUCKET_NAME'] = 'test-bucket'
2545+
s3_client.stub_responses(:list_objects_v2, { contents: [{ key: 'published/presentation/test123/metadata.xml' }] })
2546+
allow(Aws::S3::Client).to receive(:new).and_return(s3_client)
2547+
end
2548+
2549+
after do
2550+
ENV.delete('S3_RECORDING')
2551+
ENV.delete('S3_BUCKET_NAME')
2552+
end
2553+
2554+
it 'deletes the recording objects from S3 and marks the recording deleted' do
2555+
r = create(:recording, record_id: 'test123')
2556+
create(:playback_format, recording: r, format: 'presentation')
2557+
params = encode_bbb_params('deleteRecordings', "recordID=#{r.record_id}")
2558+
2559+
expect(FileUtils).not_to receive(:rm_r)
2560+
2561+
get bigbluebutton_api_delete_recordings_url, params: params
2562+
2563+
expect(response).to be_successful
2564+
response_xml = Nokogiri::XML(response.body)
2565+
expect(response_xml.at_xpath('/response/returncode').text).to eq('SUCCESS')
2566+
2567+
delete_requests = s3_client.api_requests.select { |req| req[:operation_name] == :delete_objects }
2568+
expect(delete_requests).not_to be_empty
2569+
expect(r.reload.state).to eq('deleted')
2570+
end
2571+
end
2572+
25392573
context 'POST request' do
25402574
it 'is not supported' do
25412575
r = create(:recording)

0 commit comments

Comments
 (0)