lib/scrivito/cms_backend.rb in scrivito_sdk-0.18.1 vs lib/scrivito/cms_backend.rb in scrivito_sdk-0.30.0.rc1

- old
+ new

@@ -1,6 +1,6 @@ -require 'rest_client' +require 'addressable/uri' module Scrivito class ContentServiceObjQueries def initialize(queries) @@ -45,11 +45,10 @@ open_queries.empty? end end class CmsBackend - BLOB_DATA_CACHE_PREFIX = 'blob_data'.freeze VALID_INDEX_NAMES = %w[id path ppath permalink].freeze class << self def instance @instance ||= new @@ -75,10 +74,15 @@ def query_counter @query_counter end + # For test purpose only. + def reset_query_counter! + @query_counter = 0 + end + def find_workspace_data_by_id(id) workspace_data_from_cache = WorkspaceDataFromService.find_from_cache(id) from_content_state_id = workspace_data_from_cache.try(:content_state_id) request_params = {:workspace_id => id} @@ -108,23 +112,31 @@ def find_obj_data_including_deleted_by(revision, index, keys) find_obj_data_filtering_deleted_by(revision, index, keys, true) end - def find_blob_data_by_id(id) - cache_key = "#{BLOB_DATA_CACHE_PREFIX}/#{id}" - if data_from_cache = CmsCacheStorage.cache.read(cache_key) - data_from_cache + def find_blob_data(id, access, verb) + id = Addressable::URI.normalize_component(id, Addressable::URI::CharacterClasses::UNRESERVED) + if blob_data = fetch_blob_data_from_cache(id, access, verb) + blob_data else - data_from_database = find_blob_data_from_database_by(id) - if maxage = data_from_database['maxage'] - CmsCacheStorage.cache.write(cache_key, data_from_database, :expires_in => maxage) - end - data_from_database + blob_datas = request_blob_datas_from_backend(id) + store_blob_datas_in_cache(id, blob_datas) + blob_datas[access][verb] end end + def find_blob_metadata(id, url) + if blob_metadata = fetch_blob_metadata_from_cache(id) + blob_metadata + else + blob_metadata = request_blob_metadata_from_s3(url) + store_blob_metadata_in_cache(id, blob_metadata) + blob_metadata + end + end + def search_objs(workspace, params) content_state = workspace.revision.content_state cache_index = 'search' cache_key = params.to_param @@ -177,10 +189,68 @@ def store_search_result_in_cache(content_state, cache_index, cache_key, result) content_state.save_obj_data(cache_index, cache_key, result) if caching? end + def fetch_blob_data_from_cache(id, access, verb) + CmsCacheStorage.cache.read(blob_data_cache_key(id, access, verb)) + end + + def request_blob_datas_from_backend(id) + @query_counter += 1 + CmsRestApi.get("blobs/#{id}") + end + + def store_blob_datas_in_cache(id, blob_datas) + %w[public_access private_access].each do |access| + %w[get head].each do |verb| + blob_data = blob_datas[access][verb] + CmsCacheStorage.cache.write(blob_data_cache_key(id, access, verb), + blob_data, expires_in: blob_data['maxage']) + end + end + end + + def blob_data_cache_key(id, access, verb) + "blob_data/#{id}/#{access}/#{verb}" + end + + def fetch_blob_metadata_from_cache(id) + CmsCacheStorage.cache.read(blob_metadata_cache_key(id)) + end + + def request_blob_metadata_from_s3(url) + uri = URI.parse(url) + retried = false + begin + response = ConnectionManager.request(uri, Net::HTTP::Head.new(uri.path)) + @query_counter += 1 + rescue NetworkError + raise if retried + retried = true + retry + end + + raise ScrivitoError, "S3 responded with #{reponse.code}" unless response.code == '200' + + { + content_length: response['content-length'], + content_type: response['content-type'], + cache_control: response['cache-control'], + } + end + + def store_blob_metadata_in_cache(id, blob_metadata) + max_age = blob_metadata.delete(:cache_control) =~ /max-age=(.*),/ && $1 + max_age = max_age.to_i if max_age + CmsCacheStorage.cache.write(blob_metadata_cache_key(id), blob_metadata, expires_in: max_age) + end + + def blob_metadata_cache_key(id) + "blob_metadata/#{Digest::SHA1.hexdigest(id)}" # id of a blob is a URI. + end + def find_obj_data_filtering_deleted_by(revision, index, keys, include_deleted) index = index.to_s assert_valid_index_name(index) raw_data = find_raw_data_from_cache_or_database_by(revision, index, keys) @@ -265,14 +335,9 @@ end end def store_item_in_cache(revision, index, key, item) ContentStateCaching.store_obj_data(revision.content_state, index, key, item) - end - - def find_blob_data_from_database_by(id) - @query_counter += 1 - ContentService.query('blobs/query', :blob_ids => [id])['blobs'][id] end def assert_valid_index_name(index) raise ArgumentError, "invalid index name '#{index}'" unless VALID_INDEX_NAMES.include?(index) end