diff --git a/app/controllers/concerns/bbb_helper.rb b/app/controllers/concerns/bbb_helper.rb index e13d640f..36839a05 100644 --- a/app/controllers/concerns/bbb_helper.rb +++ b/app/controllers/concerns/bbb_helper.rb @@ -124,8 +124,7 @@ def meeting_running? # Fetches all recordings for a room. def recordings - res = Rails.cache.fetch("rooms/#{@chosen_room.handler}/#{RECORDINGS_KEY}", expires_in: Rails.configuration.cache_expires_in_minutes.minutes) if Rails.configuration.cache_enabled - res ||= bbb.get_recordings(meetingID: @chosen_room.handler) + res = CacheService.fetch_or_compute("rooms/#{@chosen_room.handler}/#{RECORDINGS_KEY}") { bbb.get_recordings(meetingID: @chosen_room.handler) } recordings_formatted(res) end @@ -161,29 +160,33 @@ def server_running? # Deletes a recording. def delete_recording(record_id) - Rails.cache.delete("rooms/#{@chosen_room.handler}/#{RECORDINGS_KEY}") if Rails.configuration.cache_enabled + delete_recording_cache bbb.delete_recordings(record_id) end # Publishes a recording. def publish_recording(record_id) - Rails.cache.delete("rooms/#{@chosen_room.handler}/#{RECORDINGS_KEY}") if Rails.configuration.cache_enabled + delete_recording_cache bbb.publish_recordings(record_id, true) end # Unpublishes a recording. def unpublish_recording(record_id) - Rails.cache.delete("rooms/#{@chosen_room.handler}/#{RECORDINGS_KEY}") if Rails.configuration.cache_enabled + delete_recording_cache bbb.publish_recordings(record_id, false) end # Updates a recording. def update_recording(record_id, meta) - Rails.cache.delete("rooms/#{@chosen_room.handler}/#{RECORDINGS_KEY}") if Rails.configuration.cache_enabled + delete_recording_cache meta[:recordID] = record_id bbb.send_api_request('updateRecordings', meta) end + def delete_recording_cache + CacheService.delete("rooms/#{@chosen_room.handler}/#{RECORDINGS_KEY}") + end + # Return the number of participants in a meeting for the current room. def participant_count info = meeting_info @@ -246,8 +249,6 @@ def initialize_bbb_credentials bbb_credentials = Bbb::Credentials.new(Rails.configuration.bigbluebutton_endpoint, Rails.configuration.bigbluebutton_secret) bbb_credentials.multitenant_api_endpoint = Rails.configuration.external_multitenant_endpoint bbb_credentials.multitenant_api_secret = Rails.configuration.external_multitenant_secret - bbb_credentials.cache = Rails.cache - bbb_credentials.cache_enabled = Rails.configuration.cache_enabled bbb_credentials end diff --git a/app/controllers/concerns/broker_helper.rb b/app/controllers/concerns/broker_helper.rb index 82e7fcac..4a7f4b95 100644 --- a/app/controllers/concerns/broker_helper.rb +++ b/app/controllers/concerns/broker_helper.rb @@ -20,8 +20,7 @@ module BrokerHelper # Fetch tenant object from the broker def broker_tenant_info(tenant) - # tenant ||= @room&.tenant || '' - Rails.cache.fetch("rooms/tenant/#{tenant}", expires_in: Rails.configuration.cache_expires_in_minutes.minutes) do + CacheService.fetch_or_compute("rooms/tenant/#{tenant}") do bbbltibroker_url = omniauth_bbbltibroker_url("/api/v1/tenants/#{tenant}") get_response = RestClient.get(bbbltibroker_url, 'Authorization' => "Bearer #{omniauth_client_token(omniauth_bbbltibroker_url)}") diff --git a/app/controllers/concerns/extra_params_helper.rb b/app/controllers/concerns/extra_params_helper.rb new file mode 100644 index 00000000..4451ee54 --- /dev/null +++ b/app/controllers/concerns/extra_params_helper.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +# +## BigBlueButton open source conferencing system - http://www.bigbluebutton.org/. +# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below). +# This program is free software; you can redistribute it and/or modify it under the +# terms of the GNU Lesser General Public License as published by the Free Software +# Foundation; either version 3.0 of the License, or (at your option) any later +# version. +# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public License along +# with BigBlueButton; if not, see . +# + +module ExtraParamsHelper + extend ActiveSupport::Concern + + # return a hash of key:value pairs from the launch_params, + # for keys that exist in the extra params hash retrieved from the broker settings + def launch_and_extra_params_intersection_hash(launch_params, action, actions_hash) + CacheService.fetch_or_compute("rooms/#{@chosen_room.handler}/tenant/#{@chosen_room.tenant}/user/#{@user.uid}/ext_#{action}_params") { calculate_intersection_hash(launch_params, actions_hash) } + end + + def calculate_intersection_hash(launch_params, actions_hash) + result = {} + actions_hash&.each_key do |key| + value = find_launch_param(launch_params, key) + result[key] = value if value + end + result + end + + # Check if the launch params contain a certain param + # If they do, return the value of that param + def find_launch_param(launch_params, key) + return launch_params[key] if launch_params.key?(key) + + launch_params.each_value do |value| + if value.is_a?(Hash) + result = find_launch_param(value, key) + return result if result + end + end + + nil + end +end diff --git a/app/controllers/rooms_controller.rb b/app/controllers/rooms_controller.rb index b7fc87c6..b60c07bc 100644 --- a/app/controllers/rooms_controller.rb +++ b/app/controllers/rooms_controller.rb @@ -30,6 +30,7 @@ class RoomsController < ApplicationController include BbbHelper include OmniauthHelper include BrokerHelper + include ExtraParamsHelper before_action :print_parameters if Rails.configuration.developer_mode_enabled before_action :authenticate_user!, except: %i[meeting_close], raise: false @@ -510,15 +511,9 @@ def set_ext_params tenant = @chosen_room.tenant @broker_ext_params ||= tenant_setting(tenant, 'ext_params') - launch_params = if Rails.configuration.cache_enabled - Rails.cache.fetch("rooms/#{@chosen_room.handler}/tenant/#{tenant}/user/#{@user.uid}/launch_params", - expires_in: Rails.configuration.cache_expires_in_minutes.minutes) do - logger.debug('fetching launch params for extra params from cache') - launch_request_params['message'] - end - else - launch_request_params['message'] - end + launch_params = CacheService.fetch_or_compute("rooms/#{@chosen_room.handler}/tenant/#{tenant}/user/#{@user.uid}/launch_params") do + launch_request_params['message'] + end logger.debug("[Rooms Controller] extra params from broker for room #{@chosen_room.name}: #{@broker_ext_params}") @@ -531,41 +526,4 @@ def set_ext_params rescue StandardError => e logger.error("[Rooms Controller] Error setting extra parameters: #{e}") end - - # return a hash of key:value pairs from the launch_params, - # for keys that exist in the extra params hash retrieved from the broker settings - def launch_and_extra_params_intersection_hash(launch_params, action, actions_hash) - if Rails.configuration.cache_enabled - Rails.cache.fetch("rooms/#{@chosen_room.handler}/tenant/#{@chosen_room.tenant}/user/#{@user.uid}/ext_#{action}_params", - expires_in: Rails.configuration.cache_expires_in_minutes.minutes) do - calculate_intersection_hash(launch_params, actions_hash) - end - else - calculate_intersection_hash(launch_params, actions_hash) - end - end - - def calculate_intersection_hash(launch_params, actions_hash) - result = {} - actions_hash&.each_key do |key| - value = find_launch_param(launch_params, key) - result[key] = value if value - end - result - end - - # Check if the launch params contain a certain param - # If they do, return the value of that param - def find_launch_param(launch_params, key) - return launch_params[key] if launch_params.key?(key) - - launch_params.each_value do |value| - if value.is_a?(Hash) - result = find_launch_param(value, key) - return result unless result.nil? - end - end - - nil - end end diff --git a/app/services/cache_service.rb b/app/services/cache_service.rb new file mode 100644 index 00000000..a2976027 --- /dev/null +++ b/app/services/cache_service.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/. +# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below). +# This program is free software; you can redistribute it and/or modify it under the +# terms of the GNU Lesser General Public License as published by the Free Software +# Foundation; either version 3.0 of the License, or (at your option) any later +# version. +# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public License along +# with BigBlueButton; if not, see . + +class CacheService + def self.fetch_or_compute(cache_key, expiration = Rails.configuration.cache_expires_in_minutes.minutes, &block) + if Rails.configuration.cache_enabled + Rails.logger.debug("[CacheService] Cache enabled, attempt to fetch cache for the following key: #{cache_key}") + Rails.cache.fetch(cache_key, expires_in: expiration, &block) + else + yield + end + end + + def self.delete(cache_key) + Rails.cache.delete(cache_key) if Rails.configuration.cache_enabled + end +end diff --git a/lib/bbb/credentials.rb b/lib/bbb/credentials.rb index 09222cd1..14be9a57 100644 --- a/lib/bbb/credentials.rb +++ b/lib/bbb/credentials.rb @@ -25,7 +25,7 @@ class Credentials include OmniauthHelper include BrokerHelper - attr_writer :cache, :cache_enabled, :multitenant_api_endpoint, :multitenant_api_secret # Rails.cache store is assumed. # Enabled by default. + attr_writer :multitenant_api_endpoint, :multitenant_api_secret def initialize(endpoint, secret) # Set default credentials. @@ -33,7 +33,6 @@ def initialize(endpoint, secret) @secret = secret @multitenant_api_endpoint = nil @multitenant_api_secret = nil - @cache_enabled = true end def endpoint(tenant) @@ -62,54 +61,48 @@ def tenant_info(tenant, key) end def formatted_tenant_info(tenant) - if @cache_enabled - Rails.logger.debug('Cache enabled, attempt to fetch credentials from cache...') - cached_tenant = @cache.fetch("rooms/#{tenant}/tenantInfo", expires_in: Rails.configuration.cache_expires_in_minutes.minutes) - return cached_tenant unless cached_tenant.nil? - end - - # Get tenant info from broker - Rails.logger.debug('No cache. Attempt to fetch credentials from broker...') - tenant_info = broker_tenant_info(tenant) + CacheService.fetch_or_compute("rooms/#{tenant}/tenantInfo") do + # Get tenant info from broker + Rails.logger.debug('No cache. Attempt to fetch credentials from broker...') + tenant_info = broker_tenant_info(tenant) - # Get tenant credentials from TENANT_CREDENTIALS environment variable - tenant_credentials = JSON.parse(Rails.configuration.tenant_credentials)[tenant] + # Get tenant credentials from TENANT_CREDENTIALS environment variable + tenant_credentials = JSON.parse(Rails.configuration.tenant_credentials)[tenant] - raise 'Tenant does not exist' if tenant_info.nil? && tenant_credentials.nil? && tenant.present? + raise 'Tenant does not exist' if tenant_info.nil? && tenant_credentials.nil? && tenant.present? - # use credentials from broker first, if not found then use env variable, and then use bbb_endpoint & bbb_secret if single tenant - tenant_settings = tenant_info&.[]('settings') + # use credentials from broker first, if not found then use env variable, and then use bbb_endpoint & bbb_secret if single tenant + tenant_settings = tenant_info&.[]('settings') - api_url = tenant_settings&.[]('bigbluebutton_url') || - tenant_credentials&.[]('bigbluebutton_url') || - (@endpoint if tenant.blank?) + api_url = tenant_settings&.[]('bigbluebutton_url') || + tenant_credentials&.[]('bigbluebutton_url') || + (@endpoint if tenant.blank?) - secret = tenant_settings&.[]('bigbluebutton_secret') || - tenant_credentials&.[]('bigbluebutton_secret') || - (@secret if tenant.blank?) + secret = tenant_settings&.[]('bigbluebutton_secret') || + tenant_credentials&.[]('bigbluebutton_secret') || + (@secret if tenant.blank?) - missing_creds = !(api_url && secret) + missing_creds = !(api_url && secret) - raise 'Bigbluebutton credentials not found' if tenant.blank? && missing_creds + raise 'Bigbluebutton credentials not found' if tenant.blank? && missing_creds - raise 'Multitenant API not defined' if tenant.present? && missing_creds && (@multitenant_api_endpoint.nil? || @multitenant_api_secret.nil?) + raise 'Multitenant API not defined' if tenant.present? && missing_creds && (@multitenant_api_endpoint.nil? || @multitenant_api_secret.nil?) - # get the api URL and secret from the LB if not defined in tenant settings - if missing_creds - Rails.logger.debug('Missing credentials, attempt to fetch from multitenant_api_endpoint...') - # Build the URI. - uri = encoded_url( - "#{@multitenant_api_endpoint}api/getUser", - @multitenant_api_secret, - { name: tenant } - ) + # get the api URL and secret from the LB if not defined in tenant settings + if missing_creds + Rails.logger.debug('Missing credentials, attempt to fetch from multitenant_api_endpoint...') + # Build the URI. + uri = encoded_url( + "#{@multitenant_api_endpoint}api/getUser", + @multitenant_api_secret, + { name: tenant } + ) - http_response = http_request(uri) - response = parse_response(http_response) - response['settings'] = tenant_settings - end + http_response = http_request(uri) + response = parse_response(http_response) + response['settings'] = tenant_settings + end - @cache.fetch("rooms/#{tenant}/tenantInfo", expires_in: Rails.configuration.cache_expires_in_minutes.minutes) do response || { 'apiURL' => api_url, 'secret' => secret, 'settings' => tenant_settings } end end