infopark_cloud_connector 7.0.2 → 7.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|