infopark_cloud_connector 6.8.3.115.227021242 → 6.8.3.174.51542603
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/rails_connector/basic_obj.rb +1 -2
- data/lib/rails_connector/blob.rb +19 -52
- data/lib/rails_connector/cache_middleware.rb +0 -1
- data/lib/rails_connector/cms_backend.rb +179 -17
- data/lib/rails_connector/model_identity.rb +13 -0
- data/lib/rails_connector/workspace.rb +2 -11
- metadata +4 -49
- data/lib/rails_connector/chain.rb +0 -175
- data/lib/rails_connector/cms_base_model.rb +0 -55
- data/lib/rails_connector/content_cache.rb +0 -23
- data/lib/rails_connector/dict_storage.rb +0 -66
- data/lib/rails_connector/dynamo_cms_backend.rb +0 -136
- data/lib/rails_connector/obj_data_from_database.rb +0 -109
- data/lib/rails_connector/path_conversion.rb +0 -21
- data/lib/rails_connector/permission.rb +0 -39
- data/lib/rails_connector/revision.rb +0 -75
- data/lib/rails_connector/s3_blob.rb +0 -89
- data/lib/rails_connector/service_blob.rb +0 -48
- data/lib/rails_connector/service_cms_backend.rb +0 -194
- data/lib/rails_connector/version.rb +0 -38
- data/lib/rails_connector/workspace_data_from_database.rb +0 -19
@@ -1,175 +0,0 @@
|
|
1
|
-
module RailsConnector
|
2
|
-
|
3
|
-
class Chain
|
4
|
-
# the id of the content cache to use, or nil
|
5
|
-
attr_reader :content_cache
|
6
|
-
|
7
|
-
# a chain of patch operations that can be used to construct the target revision
|
8
|
-
# each chain member is an array with two elements.
|
9
|
-
# the first element denotes the patch type (-1, 1), where
|
10
|
-
# 1 => apply the revision
|
11
|
-
# -1 => revert the revision
|
12
|
-
# and the second element is the revision.
|
13
|
-
attr_reader :patches
|
14
|
-
|
15
|
-
def self.build_for(revision, content_cache = nil)
|
16
|
-
if content_cache && content_cache.revision
|
17
|
-
patches = patches_to(revision, content_cache.revision)
|
18
|
-
|
19
|
-
if content_cache.transfer_target
|
20
|
-
if patches.present? && patches.first.second == content_cache.transfer_target
|
21
|
-
# the transfer target is already included in the chain - no extra patch needed!
|
22
|
-
else
|
23
|
-
patches.unshift([-1, content_cache.transfer_target])
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
new(content_cache, patches)
|
28
|
-
else
|
29
|
-
new(nil, patches_to(revision))
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.query_counter
|
34
|
-
@query_counter || 0
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.count_query
|
38
|
-
@query_counter = query_counter + 1
|
39
|
-
end
|
40
|
-
|
41
|
-
def initialize(content_cache, patches)
|
42
|
-
@content_cache = content_cache
|
43
|
-
@patches = patches
|
44
|
-
end
|
45
|
-
|
46
|
-
# performs a revision aware query on the cms database.
|
47
|
-
#
|
48
|
-
# returns a hash of results from the query.
|
49
|
-
# the keys are the criterion by which the query results are grouped (typically the OBJ ID).
|
50
|
-
# the values are tuples where
|
51
|
-
# - the first element denotes the diff type and
|
52
|
-
# - the second the document rows
|
53
|
-
def query(index, key)
|
54
|
-
self.class.count_query
|
55
|
-
result_map = perform_queries(index, key)
|
56
|
-
version_map = result_map.merge(result_map) do |ignore, results|
|
57
|
-
results.map {|row| Version.new(row) }
|
58
|
-
end
|
59
|
-
revision_aware_results(version_map)
|
60
|
-
end
|
61
|
-
|
62
|
-
private
|
63
|
-
|
64
|
-
# calculate a list of patches to get to the destionation revision.
|
65
|
-
# if origin is given, the list will start at origin.
|
66
|
-
# otherwise the list will start at the initial revision.
|
67
|
-
def self.patches_to(destination, origin = nil)
|
68
|
-
if destination.nil? && origin.nil?
|
69
|
-
[]
|
70
|
-
elsif origin.nil? || origin.generation < destination.generation
|
71
|
-
patches_to(destination.base_revision, origin) + [[1, destination]]
|
72
|
-
elsif destination.nil? || origin.generation > destination.generation
|
73
|
-
[[-1, origin]] + patches_to(destination, origin.base_revision)
|
74
|
-
elsif origin != destination
|
75
|
-
[[-1, origin]] + patches_to(destination.base_revision, origin.base_revision) + [[1, destination]]
|
76
|
-
else # origin == destination
|
77
|
-
[]
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def perform_queries(index, key)
|
82
|
-
result_map = {}
|
83
|
-
|
84
|
-
query_options = {
|
85
|
-
:hash_value => key,
|
86
|
-
}
|
87
|
-
|
88
|
-
if content_cache.present?
|
89
|
-
result_map[:content_cache] = CmsBaseModel.query_index(:obj, index, query_options.merge({
|
90
|
-
:range_value => "cc/#{content_cache.id}",
|
91
|
-
}))
|
92
|
-
end
|
93
|
-
if patches.present?
|
94
|
-
result_map[:patches] = CmsBaseModel.query_index(:obj, index, query_options.merge({
|
95
|
-
:range_value => revision_range,
|
96
|
-
}))
|
97
|
-
end
|
98
|
-
|
99
|
-
result_map
|
100
|
-
end
|
101
|
-
|
102
|
-
# filter out those results that aren't on the chain.
|
103
|
-
# order the remaining results according to their chain position
|
104
|
-
def order_results_by_chain(result_map)
|
105
|
-
results = []
|
106
|
-
|
107
|
-
if result_map[:content_cache].present?
|
108
|
-
results << [1, result_map[:content_cache]]
|
109
|
-
end
|
110
|
-
if result_map[:patches].present?
|
111
|
-
results_by_revision = result_map[:patches].group_by do |version|
|
112
|
-
version.revision_id
|
113
|
-
end
|
114
|
-
patches.each do |(patch_diff_type, revision)|
|
115
|
-
results_for_revision = results_by_revision[revision.id]
|
116
|
-
results << [patch_diff_type, results_for_revision] if results_for_revision
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
results
|
121
|
-
end
|
122
|
-
|
123
|
-
# group the results by obj id
|
124
|
-
# i.e. calculate a separate chain for each obj
|
125
|
-
def group_results(result_map)
|
126
|
-
results_by_chain = order_results_by_chain(result_map)
|
127
|
-
|
128
|
-
result_index = {}
|
129
|
-
results_by_chain.each do |(patch_diff_type, versions)|
|
130
|
-
versions.each do |version|
|
131
|
-
id = version.obj_id
|
132
|
-
result_index[id] ||= []
|
133
|
-
result_index[id] << [patch_diff_type, version]
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
result_index
|
138
|
-
end
|
139
|
-
|
140
|
-
# apply the diff chain for each of obj
|
141
|
-
# to determine which of them are included in the final revision
|
142
|
-
def revision_aware_results(result_map)
|
143
|
-
result_index = {}
|
144
|
-
|
145
|
-
# note: using merge as a map function for hashes
|
146
|
-
group_results(result_map).each do |id, apply_chain|
|
147
|
-
final_existance = apply_chain.inject(0) do |temp_existance, (patch_diff_type, version)|
|
148
|
-
# remember: -1 (revert) multiplied with -1 (revert) equals 1 (apply)
|
149
|
-
# and: +1 (create) added to -1 (delete) equals 0 (not existant)
|
150
|
-
temp_existance + patch_diff_type * version.diff
|
151
|
-
end
|
152
|
-
if final_existance > 0
|
153
|
-
patch_diff, version = apply_chain.last
|
154
|
-
result_index[id] = version.obj_data(patch_diff)
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
result_index
|
159
|
-
end
|
160
|
-
|
161
|
-
private
|
162
|
-
|
163
|
-
def revision_range
|
164
|
-
@revision_range ||=
|
165
|
-
begin
|
166
|
-
sorted_keys = patches.map do |(type, revision)|
|
167
|
-
"#{"%010d" % revision.generation}/#{revision.id}"
|
168
|
-
end.sort
|
169
|
-
Range.new(sorted_keys.first, sorted_keys.last)
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
end
|
174
|
-
|
175
|
-
end # module RailsConnector
|
@@ -1,55 +0,0 @@
|
|
1
|
-
require "kvom"
|
2
|
-
|
3
|
-
module RailsConnector
|
4
|
-
|
5
|
-
# This is the abstract class from which all CMS models derive.
|
6
|
-
class CmsBaseModel < Kvom::Model::Base
|
7
|
-
class << self
|
8
|
-
def instance_name=(ignore)
|
9
|
-
# this method is here only for compatibility with the fiona connector.
|
10
|
-
end
|
11
|
-
|
12
|
-
def adapter
|
13
|
-
@@cms_database_adapter
|
14
|
-
end
|
15
|
-
|
16
|
-
def configure_database(connection_spec)
|
17
|
-
@@cms_database_adapter =
|
18
|
-
case connection_spec["type"]
|
19
|
-
when "dynamo"
|
20
|
-
Kvom::Adapter::DynamodbAdapter.new(connection_spec)
|
21
|
-
when "file"
|
22
|
-
Kvom::Adapter::FilesystemAdapter.new(connection_spec)
|
23
|
-
else
|
24
|
-
raise "Unexpected database type #{connection_spec["type"]}"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def query_index(model, index, params = {}, query_options={})
|
29
|
-
hash_value = "#{model}/#{index}/#{params[:hash_value]}"
|
30
|
-
range_value = params[:range_value] || ""
|
31
|
-
|
32
|
-
# up to this point: backend independent
|
33
|
-
|
34
|
-
# this may be backend dependent (suffix character)
|
35
|
-
start_key, end_key =
|
36
|
-
case range_value
|
37
|
-
when Range
|
38
|
-
[range_value.begin, range_value.end]
|
39
|
-
else
|
40
|
-
[range_value, range_value]
|
41
|
-
end
|
42
|
-
range_value = Range.new(start_key, end_key + "~")
|
43
|
-
|
44
|
-
adapter.query(hash_value, range_value, query_options)
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
def save
|
50
|
-
raise "CmsBaseModel is read-only"
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module RailsConnector
|
2
|
-
|
3
|
-
class ContentCache < CmsBaseModel
|
4
|
-
self.key_prefix = "cc"
|
5
|
-
|
6
|
-
property :revision_id
|
7
|
-
property :transferring_to
|
8
|
-
|
9
|
-
# returns the revision that is represented by this content cache.
|
10
|
-
# returns nil if the revision cannot be found.
|
11
|
-
def revision
|
12
|
-
@revision ||= Revision.find_by_id(revision_id)
|
13
|
-
end
|
14
|
-
|
15
|
-
# returns the revision that this content cache is currently transferring to.
|
16
|
-
# returns nil if no transfer is taking place or if the revision cannot be found.
|
17
|
-
def transfer_target
|
18
|
-
@transfer_target ||= transferring_to ? Revision.find_by_id(transferring_to) : nil
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
end # module RailsConnector
|
23
|
-
|
@@ -1,66 +0,0 @@
|
|
1
|
-
module RailsConnector
|
2
|
-
|
3
|
-
class DictStorage
|
4
|
-
|
5
|
-
class << self
|
6
|
-
|
7
|
-
def configure(config)
|
8
|
-
@config = config.present? ? config.symbolize_keys : {}
|
9
|
-
@storage = nil
|
10
|
-
end
|
11
|
-
|
12
|
-
def get(key)
|
13
|
-
cache.fetch(key) { storage.get(key) }
|
14
|
-
end
|
15
|
-
|
16
|
-
# clears the in-memory cache.
|
17
|
-
# does not affect a potential second level cache present in the underlying storage.
|
18
|
-
def clear_first_level_cache
|
19
|
-
@cache = nil
|
20
|
-
end
|
21
|
-
|
22
|
-
attr_reader :config
|
23
|
-
|
24
|
-
def storage
|
25
|
-
@storage ||=
|
26
|
-
case config[:type]
|
27
|
-
when "s3"
|
28
|
-
s3_storage(config)
|
29
|
-
when "file"
|
30
|
-
file_storage(config)
|
31
|
-
else
|
32
|
-
raise "Unsupported dict storage type #{config[:type]}"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def cache
|
39
|
-
@cache ||= Cache.new
|
40
|
-
end
|
41
|
-
|
42
|
-
def s3_storage(config)
|
43
|
-
if config && !config.key?("s3_endpoint") && !config.key?(:s3_endpoint)
|
44
|
-
config = config.merge(:s3_endpoint => "s3-eu-west-1.amazonaws.com")
|
45
|
-
end
|
46
|
-
|
47
|
-
bucket = AWS::S3.new(config).buckets[config[:bucket_name]]
|
48
|
-
Kvom::Storage::S3Storage.new({
|
49
|
-
:bucket => bucket,
|
50
|
-
:bucket_prefix => "dict",
|
51
|
-
:cache => s3_storage_cache,
|
52
|
-
:cache_prefix => "dict.",
|
53
|
-
})
|
54
|
-
end
|
55
|
-
|
56
|
-
def s3_storage_cache
|
57
|
-
Rails.cache
|
58
|
-
end
|
59
|
-
|
60
|
-
def file_storage(config)
|
61
|
-
Kvom::Storage::FileSystemStorage.new(config)
|
62
|
-
end
|
63
|
-
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,136 +0,0 @@
|
|
1
|
-
module RailsConnector
|
2
|
-
|
3
|
-
class DynamoCmsBackend
|
4
|
-
CACHE_PREFIX = 'revision'
|
5
|
-
|
6
|
-
def initialize
|
7
|
-
@query_counter = 0
|
8
|
-
end
|
9
|
-
|
10
|
-
def begin_caching
|
11
|
-
@editable_cache = Configuration.cache_editable_workspaces ? persistent_cache : Cache.new
|
12
|
-
@read_only_cache = persistent_cache
|
13
|
-
end
|
14
|
-
|
15
|
-
def end_caching
|
16
|
-
@editable_cache = @read_only_cache = nil
|
17
|
-
end
|
18
|
-
|
19
|
-
def find_workspace_data_by_id(id)
|
20
|
-
WorkspaceDataFromDatabase.find(id)
|
21
|
-
rescue Kvom::NotFound
|
22
|
-
end
|
23
|
-
|
24
|
-
def find_obj_data_by(workspace_data, index, keys)
|
25
|
-
revision = workspace_data.revision
|
26
|
-
raw_data =
|
27
|
-
if caching?
|
28
|
-
find_obj_data_from_cache_or_database_by(revision, index, keys)
|
29
|
-
else
|
30
|
-
find_obj_data_from_database_by(revision, index, keys)
|
31
|
-
end
|
32
|
-
|
33
|
-
raw_data.map do |raw_list|
|
34
|
-
raw_list.map do |raw_obj_data|
|
35
|
-
ObjDataFromDatabase.new(raw_obj_data, revision)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def caching?
|
41
|
-
@read_only_cache && @editable_cache
|
42
|
-
end
|
43
|
-
|
44
|
-
def query_counter
|
45
|
-
@query_counter
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def persistent_cache
|
51
|
-
Cache.new(:fallback_backend => Rails.cache, :cache_prefix => CACHE_PREFIX)
|
52
|
-
end
|
53
|
-
|
54
|
-
def find_obj_data_from_database_by(revision, index, keys)
|
55
|
-
return [] if keys.blank?
|
56
|
-
@query_counter += 1
|
57
|
-
instrumenter = ActiveSupport::Notifications.instrumenter
|
58
|
-
instrumenter.instrument(
|
59
|
-
"cms_load.rails_connector", :name => "Obj Load", :index => index.to_s, :keys => keys
|
60
|
-
) do
|
61
|
-
keys.map do |key|
|
62
|
-
results = revision.chain.query(index, key)
|
63
|
-
results.values.map { |row| extract_obj_data(row) }
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def find_obj_data_from_cache_or_database_by(revision, index, keys)
|
69
|
-
keys_from_database = []
|
70
|
-
# load results from cache
|
71
|
-
results_from_cache = keys.map do |key|
|
72
|
-
cache_for(revision).read(cache_key_for(revision, index, key)).tap do |objs|
|
73
|
-
keys_from_database << key unless objs
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# load cache misses from database and store them in cache
|
78
|
-
results_from_database = find_obj_data_from_database_by(revision, index, keys_from_database)
|
79
|
-
keys_from_database.each_with_index do |key, key_number|
|
80
|
-
store_obj_data_list_in_cache(revision, index, key, results_from_database[key_number])
|
81
|
-
end
|
82
|
-
|
83
|
-
# combine the results
|
84
|
-
results_from_cache.map do |objs_from_cache|
|
85
|
-
objs_from_cache || results_from_database.shift
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
UNIQUE_INDICES = [:id, :path, :permalink].freeze
|
90
|
-
OBJ_PROPERTY_VALUE_TO_RANGE_VALUE_CONVERSIONS = {
|
91
|
-
:path => PathConversion.method(:path_from_list)
|
92
|
-
}.freeze
|
93
|
-
|
94
|
-
def store_obj_data_list_in_cache(revision, index, key, obj_data_list)
|
95
|
-
obj_data_list.each do |obj_data|
|
96
|
-
values = obj_data["values"]
|
97
|
-
UNIQUE_INDICES.each do |unique_index|
|
98
|
-
index_value = values["_#{unique_index}"]
|
99
|
-
if (converter = OBJ_PROPERTY_VALUE_TO_RANGE_VALUE_CONVERSIONS[unique_index])
|
100
|
-
index_value = converter.call(index_value)
|
101
|
-
end
|
102
|
-
store_item_in_cache(revision, unique_index, index_value, [obj_data])
|
103
|
-
end
|
104
|
-
end
|
105
|
-
unless UNIQUE_INDICES.include?(index)
|
106
|
-
store_item_in_cache(revision, index, key, obj_data_list)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def store_item_in_cache(revision, index, key, item)
|
111
|
-
cache_for(revision).write(cache_key_for(revision, index, key), item) if caching?
|
112
|
-
end
|
113
|
-
|
114
|
-
def cache_key_for(revision, index, key)
|
115
|
-
"#{revision.id}/obj/#{index}/#{key}"
|
116
|
-
end
|
117
|
-
|
118
|
-
def extract_obj_data(data)
|
119
|
-
{
|
120
|
-
"values" => data["values"].merge(
|
121
|
-
"_id" => data["obj_id"],
|
122
|
-
"_obj_type" => data["obj_type"],
|
123
|
-
"_obj_class" => data["obj_class_name"]
|
124
|
-
),
|
125
|
-
"rtc_ref" => data["rtc_ref"],
|
126
|
-
"ext_ref" => data["ext_ref"],
|
127
|
-
}
|
128
|
-
end
|
129
|
-
|
130
|
-
def cache_for(revision)
|
131
|
-
revision.editable ? @editable_cache : @read_only_cache
|
132
|
-
end
|
133
|
-
|
134
|
-
end
|
135
|
-
|
136
|
-
end
|