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