infopark_cloud_connector 7.0.2 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/app/controllers/rails_connector/objs_controller.rb +29 -37
- data/app/helpers/rails_connector/cms_asset_helper.rb +1 -1
- data/app/helpers/rails_connector/cms_tag_helper.rb +1 -1
- data/app/helpers/rails_connector/default_cms_routing_helper.rb +1 -3
- data/app/helpers/rails_connector/display_helper.rb +5 -1
- data/app/views/rails_connector/_editing_javascript.html.erb +3 -2
- data/config/ca-bundle.crt +2 -2
- data/config/routes.rb +3 -0
- data/lib/assets/fonts/infopark_icons-webfont.eot +0 -0
- data/lib/assets/fonts/infopark_icons-webfont.ttf +0 -0
- data/lib/assets/fonts/infopark_icons-webfont.woff +0 -0
- data/lib/assets/images/apple-touch-icon.jpg +0 -0
- data/lib/assets/images/favicon.ico +0 -0
- data/lib/assets/images/ip_logo.svg +50 -0
- data/lib/assets/javascripts/infopark_editing.js +903 -164
- data/lib/assets/stylesheets/infopark_editing.css +222 -271
- data/lib/infopark_cloud_connector.rb +0 -1
- data/lib/rails_connector/attribute_content.rb +25 -74
- data/lib/rails_connector/backend_error.rb +4 -0
- data/lib/rails_connector/basic_obj.rb +173 -20
- data/lib/rails_connector/basic_widget.rb +42 -1
- data/lib/rails_connector/blob.rb +1 -1
- data/lib/rails_connector/cache_middleware.rb +2 -2
- data/lib/rails_connector/cms_backend.rb +51 -33
- data/lib/rails_connector/cms_rest_api.rb +13 -8
- data/lib/rails_connector/cms_rest_api/attribute_serializer.rb +62 -0
- data/lib/rails_connector/cms_rest_api/blob_uploader.rb +18 -0
- data/lib/rails_connector/communication_error.rb +17 -0
- data/lib/rails_connector/configuration.rb +28 -0
- data/lib/rails_connector/connection_manager.rb +2 -2
- data/lib/rails_connector/content_conversion.rb +16 -62
- data/lib/rails_connector/content_service.rb +2 -2
- data/lib/rails_connector/engine.rb +2 -1
- data/lib/rails_connector/html_string.rb +0 -1
- data/lib/rails_connector/link.rb +41 -33
- data/lib/rails_connector/link_parser.rb +72 -0
- data/lib/rails_connector/migrations/migration_dsl.rb +13 -0
- data/lib/rails_connector/{backend_not_available.rb → network_error.rb} +1 -6
- data/lib/rails_connector/obj_data.rb +4 -0
- data/lib/rails_connector/obj_data_from_hash.rb +6 -0
- data/lib/rails_connector/obj_data_from_service.rb +37 -3
- data/lib/rails_connector/obj_params_parser.rb +50 -0
- data/lib/rails_connector/obj_search_builder.rb +62 -0
- data/lib/rails_connector/obj_search_enumerator.rb +60 -5
- data/lib/rails_connector/rate_limit_exceeded.rb +5 -0
- data/lib/rails_connector/revision.rb +9 -0
- data/lib/rails_connector/string_tagging.rb +1 -12
- data/lib/rails_connector/text_link.rb +52 -0
- data/lib/rails_connector/text_link_conversion.rb +50 -0
- data/lib/rails_connector/workspace.rb +125 -3
- data/lib/rails_connector/workspace_data_from_service.rb +30 -31
- data/lib/rails_connector/workspace_selection_middleware.rb +62 -20
- data/lib/tasks/cache.rake +2 -0
- data/lib/tasks/rails_connector/cache_garbage_collector_task.rb +98 -0
- metadata +24 -17
- data/lib/assets/images/ip_logo_app.png +0 -0
- data/lib/assets/images/ip_logo_app2x.png +0 -0
- data/lib/assets/images/irongrip.png +0 -0
- data/lib/rails_connector/link_resolvable.rb +0 -9
- data/lib/rails_connector/rack_middlewares.rb +0 -6
data/lib/rails_connector/blob.rb
CHANGED
@@ -55,9 +55,6 @@ module RailsConnector
|
|
55
55
|
def instance
|
56
56
|
@instance ||= new
|
57
57
|
end
|
58
|
-
|
59
|
-
delegate :begin_caching, :end_caching, :caching?, :query_counter, :find_workspace_data_by_id,
|
60
|
-
:find_obj_data_by, :find_blob_data_by_id, to: :instance
|
61
58
|
end
|
62
59
|
|
63
60
|
def initialize
|
@@ -91,7 +88,7 @@ module RailsConnector
|
|
91
88
|
raw_data = if id == 'published' && workspace_data_from_cache
|
92
89
|
begin
|
93
90
|
ContentService.query('workspaces/query', request_params, timeout: 1)
|
94
|
-
rescue
|
91
|
+
rescue CommunicationError => e
|
95
92
|
warn_backend_not_available(id, from_content_state_id, e.message)
|
96
93
|
return workspace_data_from_cache
|
97
94
|
end
|
@@ -106,15 +103,12 @@ module RailsConnector
|
|
106
103
|
end
|
107
104
|
end
|
108
105
|
|
109
|
-
def find_obj_data_by(
|
110
|
-
index
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
ObjDataFromService.new(raw_obj_data)
|
116
|
-
end
|
117
|
-
end
|
106
|
+
def find_obj_data_by(revision, index, keys)
|
107
|
+
find_obj_data_filtering_deleted_by(revision, index, keys, false)
|
108
|
+
end
|
109
|
+
|
110
|
+
def find_obj_data_including_deleted_by(revision, index, keys)
|
111
|
+
find_obj_data_filtering_deleted_by(revision, index, keys, true)
|
118
112
|
end
|
119
113
|
|
120
114
|
def find_blob_data_by_id(id)
|
@@ -132,20 +126,33 @@ module RailsConnector
|
|
132
126
|
|
133
127
|
private
|
134
128
|
|
135
|
-
def
|
129
|
+
def find_obj_data_filtering_deleted_by(revision, index, keys, include_deleted)
|
130
|
+
index = index.to_s
|
131
|
+
assert_valid_index_name(index)
|
132
|
+
raw_data = find_raw_data_from_cache_or_database_by(revision, index, keys)
|
133
|
+
|
134
|
+
raw_data.map do |raw_result|
|
135
|
+
raw_result.each_with_object([]) do |raw_data, result|
|
136
|
+
next if raw_data['_modification'] == ['deleted'] && !include_deleted
|
137
|
+
result << ObjDataFromService.new(raw_data)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def find_raw_data_from_cache_or_database_by(revision, index, keys)
|
136
143
|
keys_from_database = []
|
137
144
|
# load results from cache
|
138
145
|
results_from_cache = keys.map do |key|
|
139
|
-
find_raw_data_from_cache_by(
|
146
|
+
find_raw_data_from_cache_by(revision, index, key).tap do |objs|
|
140
147
|
keys_from_database << key unless objs
|
141
148
|
end
|
142
149
|
end
|
143
150
|
|
144
151
|
# load cache misses from database and store them in cache
|
145
152
|
results_from_database =
|
146
|
-
find_raw_data_from_database_by(
|
153
|
+
find_raw_data_from_database_by(revision, index, keys_from_database)
|
147
154
|
keys_from_database.each_with_index do |key, key_number|
|
148
|
-
store_raw_data_list_in_cache(
|
155
|
+
store_raw_data_list_in_cache(revision, index, key, results_from_database[key_number])
|
149
156
|
end
|
150
157
|
|
151
158
|
# combine the results
|
@@ -154,11 +161,11 @@ module RailsConnector
|
|
154
161
|
end
|
155
162
|
end
|
156
163
|
|
157
|
-
def find_raw_data_from_cache_by(
|
158
|
-
ContentStateCaching.find_obj_data(
|
164
|
+
def find_raw_data_from_cache_by(revision, index, key)
|
165
|
+
ContentStateCaching.find_obj_data(revision.content_state, index, key) if caching?
|
159
166
|
end
|
160
167
|
|
161
|
-
def find_raw_data_from_database_by(
|
168
|
+
def find_raw_data_from_database_by(revision, index, keys)
|
162
169
|
return [] if keys.blank?
|
163
170
|
instrumenter = ActiveSupport::Notifications.instrumenter
|
164
171
|
instrumenter.instrument(
|
@@ -166,36 +173,47 @@ module RailsConnector
|
|
166
173
|
) do
|
167
174
|
@query_counter += 1
|
168
175
|
queries = ContentServiceObjQueries.new(keys.map {|key| {:type => index, :param => key} })
|
169
|
-
until queries.finished?
|
170
|
-
queries.handle_response(ContentService.query(
|
171
|
-
"objs/query",
|
172
|
-
:queries => queries.open_queries,
|
173
|
-
:workspace_id => workspace_data.id,
|
174
|
-
:revision_id => workspace_data.revision_id
|
175
|
-
))
|
176
|
-
end
|
176
|
+
queries.handle_response(request_content_service(queries, revision)) until queries.finished?
|
177
177
|
queries.results
|
178
178
|
end
|
179
179
|
end
|
180
180
|
|
181
|
+
def request_content_service(queries, revision)
|
182
|
+
ContentService.query('objs/query', content_service_request_params(queries, revision))
|
183
|
+
end
|
184
|
+
|
185
|
+
def content_service_request_params(queries, revision)
|
186
|
+
params = {
|
187
|
+
queries: queries.open_queries,
|
188
|
+
revision_id: revision.id,
|
189
|
+
include_deleted: true
|
190
|
+
}
|
191
|
+
|
192
|
+
# Not every revision has a workspace,
|
193
|
+
# e.g. when requesting with the base revision of the current workspace.
|
194
|
+
params[:workspace_id] = revision.workspace.id if revision.workspace
|
195
|
+
|
196
|
+
params
|
197
|
+
end
|
198
|
+
|
181
199
|
UNIQUE_INDICES = [:id, :path, :permalink].freeze
|
182
200
|
|
183
|
-
def store_raw_data_list_in_cache(
|
201
|
+
def store_raw_data_list_in_cache(revision, index, key, raw_data_list)
|
184
202
|
raw_data_list.each do |values|
|
185
203
|
UNIQUE_INDICES.each do |unique_index|
|
186
204
|
unique_index_values = values["_#{unique_index}"]
|
187
205
|
if unique_index_values.present?
|
188
|
-
store_item_in_cache(
|
206
|
+
store_item_in_cache(revision, unique_index, unique_index_values.first, [values])
|
189
207
|
end
|
190
208
|
end
|
191
209
|
end
|
192
210
|
unless UNIQUE_INDICES.include?(index)
|
193
|
-
store_item_in_cache(
|
211
|
+
store_item_in_cache(revision, index, key, raw_data_list)
|
194
212
|
end
|
195
213
|
end
|
196
214
|
|
197
|
-
def store_item_in_cache(
|
198
|
-
ContentStateCaching.store_obj_data(
|
215
|
+
def store_item_in_cache(revision, index, key, item)
|
216
|
+
ContentStateCaching.store_obj_data(revision.content_state, index, key, item)
|
199
217
|
end
|
200
218
|
|
201
219
|
def find_blob_data_from_database_by(id)
|
@@ -90,8 +90,6 @@ module RailsConnector
|
|
90
90
|
private
|
91
91
|
|
92
92
|
def request_cms_api(action, resource_path, payload, options)
|
93
|
-
reset_connection_manager if connection_manager.uri != uri
|
94
|
-
|
95
93
|
decoded = response_for_request_cms_api(action, resource_path, payload)
|
96
94
|
return decoded unless Hash === decoded
|
97
95
|
return decoded unless decoded.keys == ["task"]
|
@@ -102,6 +100,8 @@ module RailsConnector
|
|
102
100
|
end
|
103
101
|
|
104
102
|
def response_for_request_cms_api(method, resource_path, payload = nil)
|
103
|
+
reset_connection_manager if connection_manager.uri != uri
|
104
|
+
|
105
105
|
request = method_to_net_http_class(method).new(path(resource_path))
|
106
106
|
set_headers(request)
|
107
107
|
request.body = MultiJson.encode(payload) if payload.present?
|
@@ -111,19 +111,24 @@ module RailsConnector
|
|
111
111
|
|
112
112
|
def handle_response(response)
|
113
113
|
code = response.code.to_i
|
114
|
-
if code.
|
114
|
+
if response.code.start_with?('2')
|
115
115
|
MultiJson.load(response.body)
|
116
116
|
elsif response.code == '403'
|
117
117
|
raise AccessDenied.new(response.body)
|
118
|
-
|
118
|
+
else
|
119
119
|
begin
|
120
120
|
specific_output = MultiJson.decode(response.body)['error']
|
121
|
-
|
121
|
+
|
122
|
+
if response.code.start_with?('4')
|
123
|
+
raise ClientError.new(specific_output, code)
|
124
|
+
elsif response.code == '500' && specific_output
|
125
|
+
raise BackendError.new(specific_output, code)
|
126
|
+
else # 3xx and >500 are treated as NetworkErrors
|
127
|
+
raise NetworkError.new(response.body, code)
|
128
|
+
end
|
122
129
|
rescue MultiJson::DecodeError
|
123
|
-
raise
|
130
|
+
raise NetworkError.new(response.body, code)
|
124
131
|
end
|
125
|
-
else
|
126
|
-
raise BackendNotAvailable.new(response.body, code)
|
127
132
|
end
|
128
133
|
end
|
129
134
|
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module RailsConnector
|
2
|
+
class CmsRestApi
|
3
|
+
module AttributeSerializer
|
4
|
+
class << self
|
5
|
+
def convert(attributes)
|
6
|
+
Hash[
|
7
|
+
attributes.map do |attribute_name, value|
|
8
|
+
converted_value = if link_array?(value)
|
9
|
+
convert_links(value)
|
10
|
+
elsif value.is_a?(BasicObj)
|
11
|
+
value.id
|
12
|
+
elsif obj_array?(value)
|
13
|
+
value.map(&:id)
|
14
|
+
elsif value.is_a?(Time) || value.is_a?(Date)
|
15
|
+
convert_time(value)
|
16
|
+
elsif value.is_a?(Array)
|
17
|
+
value.map(&:to_s)
|
18
|
+
elsif value.is_a?(File)
|
19
|
+
RailsConnector::CmsRestApi::BlobUploader.upload_file(value)
|
20
|
+
else
|
21
|
+
value.to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
[attribute_name.to_s, converted_value]
|
25
|
+
end
|
26
|
+
]
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def link_array?(value)
|
32
|
+
value.is_a?(Array) && value.all? do |element|
|
33
|
+
element.is_a?(Link)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def obj_array?(value)
|
38
|
+
value.is_a?(Array) && value.all? do |element|
|
39
|
+
element.is_a?(BasicObj)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def convert_links(links)
|
44
|
+
links.map do |link|
|
45
|
+
link.to_cms_api_linklist_params
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def convert_time(point_in_time)
|
50
|
+
time_object = if point_in_time.instance_of?(Date)
|
51
|
+
point_in_time.to_time
|
52
|
+
else
|
53
|
+
point_in_time.to_time.utc
|
54
|
+
end
|
55
|
+
|
56
|
+
time_object.strftime("%Y%m%d%H%M%S")
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module RailsConnector
|
2
|
+
class CmsRestApi
|
3
|
+
module BlobUploader
|
4
|
+
class << self
|
5
|
+
def upload_file(file)
|
6
|
+
upload_permission = CmsRestApi.get('blobs/upload_permission')
|
7
|
+
|
8
|
+
fields = upload_permission['fields'].to_a + [[:file, file]]
|
9
|
+
|
10
|
+
# Net/HTTP does not support multipart forms
|
11
|
+
RestClient.post(upload_permission['url'], fields)
|
12
|
+
|
13
|
+
upload_permission['blob']
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module RailsConnector
|
2
|
+
|
3
|
+
class CommunicationError < StandardError
|
4
|
+
attr_reader :http_code, :message
|
5
|
+
|
6
|
+
def initialize(message, http_code)
|
7
|
+
@http_code = http_code.to_i
|
8
|
+
@message = message
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
"HTTP-Response-Code: #{self.http_code}, Body: \"#{self.message}\""
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -170,6 +170,30 @@ module RailsConnector
|
|
170
170
|
' config.action_dispatch.x_sendfile_header = "X-Sendfile"'
|
171
171
|
end
|
172
172
|
|
173
|
+
def obj_formats
|
174
|
+
@obj_formats ||= {
|
175
|
+
'_changes_list' => proc do |obj|
|
176
|
+
{
|
177
|
+
id: obj.id,
|
178
|
+
modification: obj.modification,
|
179
|
+
deleted: obj.modification == 'deleted',
|
180
|
+
obj_class: obj.obj_class,
|
181
|
+
binary: obj.binary?,
|
182
|
+
title: obj.description_for_editor,
|
183
|
+
last_changed: obj.last_changed.strftime('%d.%m.%Y - %H:%M')
|
184
|
+
}
|
185
|
+
end
|
186
|
+
}
|
187
|
+
end
|
188
|
+
|
189
|
+
def register_obj_format(name, &block)
|
190
|
+
if name.start_with? '_'
|
191
|
+
raise InvalidFormatNameError.new('Format names starting with underscore are not allowed.')
|
192
|
+
else
|
193
|
+
obj_formats[name] = block
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
173
197
|
private
|
174
198
|
|
175
199
|
def content_service
|
@@ -188,4 +212,8 @@ module RailsConnector
|
|
188
212
|
|
189
213
|
class ConfigurationError < StandardError
|
190
214
|
end
|
215
|
+
|
216
|
+
class InvalidFormatNameError < StandardError; end
|
217
|
+
|
191
218
|
end
|
219
|
+
|
@@ -62,7 +62,7 @@ module RailsConnector
|
|
62
62
|
begin
|
63
63
|
yield
|
64
64
|
rescue *SOCKET_ERRORS => e
|
65
|
-
raise
|
65
|
+
raise NetworkError.from_socket_error(e) if retried
|
66
66
|
ensure_finished
|
67
67
|
retried = true
|
68
68
|
retry
|
@@ -74,7 +74,7 @@ module RailsConnector
|
|
74
74
|
begin
|
75
75
|
yield
|
76
76
|
rescue *SOCKET_ERRORS => e
|
77
|
-
raise
|
77
|
+
raise NetworkError.from_socket_error(e) if attempt == 2
|
78
78
|
attempt += 1
|
79
79
|
retry
|
80
80
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'nokogiri'
|
2
|
-
require 'addressable/uri'
|
3
2
|
|
4
3
|
module RailsConnector
|
5
4
|
|
@@ -8,13 +7,17 @@ module RailsConnector
|
|
8
7
|
doc = Nokogiri::HTML.parse("<div class='internal_jump_point'>#{input}</div>")
|
9
8
|
|
10
9
|
doc.css('body a').each do |a_tag|
|
11
|
-
|
12
|
-
|
10
|
+
if href = a_tag.attributes['href']
|
11
|
+
link = Link.parse(href.value, request_host, request_port)
|
12
|
+
href.value = link.to_cms_api_html_url
|
13
|
+
end
|
13
14
|
end
|
14
15
|
|
15
16
|
doc.css('body img').each do |img_tag|
|
16
|
-
|
17
|
-
|
17
|
+
if src = img_tag.attributes['src']
|
18
|
+
link = Link.parse(src.value, request_host, request_port)
|
19
|
+
src.value = link.to_cms_api_html_url
|
20
|
+
end
|
18
21
|
end
|
19
22
|
|
20
23
|
new_html = doc.css('body div.internal_jump_point').inner_html
|
@@ -23,65 +26,16 @@ module RailsConnector
|
|
23
26
|
new_html.gsub(nbsp, " ")
|
24
27
|
end
|
25
28
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
if internal_url?(uri, request_host, request_port)
|
34
|
-
target = convert_single_link(uri)
|
35
|
-
end
|
36
|
-
else
|
37
|
-
if uri.path.present?
|
38
|
-
target = convert_single_link(uri)
|
39
|
-
end
|
29
|
+
def self.convert_linklist_urls(linklist, request_host, request_port)
|
30
|
+
linklist.map do |link_data|
|
31
|
+
if link_data.has_key?(:url)
|
32
|
+
link_data.delete(:obj_id)
|
33
|
+
url = link_data.delete(:url)
|
34
|
+
link = Link.parse(url, request_host, request_port)
|
35
|
+
link_data.merge!(link.to_cms_api_linklist_params)
|
40
36
|
end
|
41
|
-
end
|
42
37
|
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.internal_url?(uri, request_host, request_port)
|
47
|
-
if request_host == uri.host
|
48
|
-
if uri.port.present?
|
49
|
-
uri.port == Integer(request_port)
|
50
|
-
else
|
51
|
-
true
|
52
|
-
end
|
53
|
-
else
|
54
|
-
false
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def self.convert_single_link(uri)
|
59
|
-
uri.path = '/' unless uri.path.present?
|
60
|
-
uri.port = nil
|
61
|
-
uri.host = nil
|
62
|
-
uri.scheme = nil
|
63
|
-
|
64
|
-
if obj_id = determine_obj_id(uri.to_s)
|
65
|
-
uri.scheme = 'objid'
|
66
|
-
uri.path = obj_id
|
67
|
-
else
|
68
|
-
uri.scheme = 'external'
|
69
|
-
end
|
70
|
-
|
71
|
-
uri.to_s
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.determine_obj_id(target)
|
75
|
-
route = Rails.application.routes.recognize_path(target, :method => :get)
|
76
|
-
if route[:controller] == 'rails_connector/cms_dispatch'
|
77
|
-
begin
|
78
|
-
if id = route[:id]
|
79
|
-
Obj.find(id).id
|
80
|
-
elsif permalink = route[:permalink]
|
81
|
-
CmsEnv.find_permalink_by_param(permalink).id
|
82
|
-
end
|
83
|
-
rescue RailsConnector::ResourceNotFound
|
84
|
-
end
|
38
|
+
link_data
|
85
39
|
end
|
86
40
|
end
|
87
41
|
end
|