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.
@@ -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