cts-mpx-aci 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +64 -0
- data/Gemfile +30 -0
- data/Gemfile.lock +178 -0
- data/Guardfile +40 -0
- data/LICENSE +201 -0
- data/README.md +203 -0
- data/Rakefile +6 -0
- data/Rules +53 -0
- data/bin/console +7 -0
- data/bin/setup +8 -0
- data/content/CHANGELOG.md +1 -0
- data/content/EXAMPLES.md +1 -0
- data/content/README.md +1 -0
- data/content/assets/bootstrap.min.css +12 -0
- data/content/assets/images/cts-logo-wide.svg +121 -0
- data/content/assets/images/cts-logo.svg +119 -0
- data/content/assets/syntax.css +210 -0
- data/content/coverage +1 -0
- data/content/doc +1 -0
- data/content/specifications.html +1 -0
- data/content/stylesheet.css +101 -0
- data/cts-mpx-aci.gemspec +23 -0
- data/data/stencils/account_record.json +431 -0
- data/data/stencils/media_custom_fields.json +37 -0
- data/data/stencils/servers.json +31 -0
- data/data/stencils/task_templates.json +17 -0
- data/data/stencils/test.json +13 -0
- data/examples/collect.md +21 -0
- data/examples/complete_basic.md +95 -0
- data/examples/deploy.md +25 -0
- data/examples/image.md +41 -0
- data/examples/pre_post_block.md +101 -0
- data/layouts/default.html +52 -0
- data/lib/cts/mpx/aci/extensions/cts/mpx/entries.rb +29 -0
- data/lib/cts/mpx/aci/extensions/cts/mpx/entry.rb +130 -0
- data/lib/cts/mpx/aci/extensions/services/data/entry.rb +136 -0
- data/lib/cts/mpx/aci/stencil.rb +148 -0
- data/lib/cts/mpx/aci/tasks/collect.rb +91 -0
- data/lib/cts/mpx/aci/tasks/deploy.rb +117 -0
- data/lib/cts/mpx/aci/tasks/image.rb +161 -0
- data/lib/cts/mpx/aci/transformations.rb +144 -0
- data/lib/cts/mpx/aci/validators.rb +114 -0
- data/lib/cts/mpx/aci/version.rb +7 -0
- data/lib/cts/mpx/aci.rb +76 -0
- data/nanoc.yaml +22 -0
- metadata +158 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
module Cts
|
2
|
+
module Mpx
|
3
|
+
module Aci
|
4
|
+
module Tasks
|
5
|
+
# Responsible for deploying an image to an account.
|
6
|
+
# @!attribute [rw] user
|
7
|
+
# @return [User] user to make data service calls with
|
8
|
+
# @!attribute [rw] account
|
9
|
+
# @return [String] relative account or nil when untransformed
|
10
|
+
# @!attribute [rw] image
|
11
|
+
# @return [Cts::Mpx::Aci::Tasks::Image]Image containing entries to deploy
|
12
|
+
class Deploy
|
13
|
+
include Creatable
|
14
|
+
|
15
|
+
attribute name: 'account', kind_of: String
|
16
|
+
attribute name: 'image', kind_of: Tasks::Image
|
17
|
+
attribute name: 'user', kind_of: User
|
18
|
+
attribute name: 'pre_block', kind_of: Proc
|
19
|
+
attribute name: 'post_block', kind_of: Proc
|
20
|
+
|
21
|
+
# Any dependencies the image may contain
|
22
|
+
# @return [Hash] dependency hash keyed by entry
|
23
|
+
def dependencies
|
24
|
+
hash = {}
|
25
|
+
image.entries.each do |e|
|
26
|
+
deps = e.dependencies
|
27
|
+
hash.store e.id, deps if deps.any?
|
28
|
+
end
|
29
|
+
hash
|
30
|
+
end
|
31
|
+
|
32
|
+
# rubocop:disable Metrics/AbcSize
|
33
|
+
# reason: these classes is as thin as it can get. not splitting it up to satisify rubocop.
|
34
|
+
# deploy a transformed image to an account
|
35
|
+
# @param [String] target_account to deploy to
|
36
|
+
# @raise [RuntimeError] when image is not deployable
|
37
|
+
def deploy(target_account, *args)
|
38
|
+
raise "not a deployable image" unless Validators.image_deployable? image
|
39
|
+
raise "not a deployable image" unless deploy_order
|
40
|
+
|
41
|
+
deploy_order.each do |ref|
|
42
|
+
entry = image.entries.find { |e| e.id == ref }
|
43
|
+
entry = block_update_entry entry, *args, &pre_block if pre_block
|
44
|
+
|
45
|
+
query = Query.create service: entry.service, endpoint: entry.endpoint, fields: 'id,guid'
|
46
|
+
query.query['byOwnerId'] = target_account
|
47
|
+
|
48
|
+
if entry.id.include? 'Field/'
|
49
|
+
query.query['byQualifiedFieldName'] = "#{entry.fields['namespace']}$#{entry.fields['fieldName']}"
|
50
|
+
else
|
51
|
+
query.query['byGuid'] = entry.fields['guid']
|
52
|
+
end
|
53
|
+
|
54
|
+
if entry.exists_by? user, query
|
55
|
+
method = 'PUT'
|
56
|
+
response = query.run(user: user)
|
57
|
+
entry.id = response.page.entries.first["id"]
|
58
|
+
else
|
59
|
+
entry.id = nil
|
60
|
+
entry.service = query.service
|
61
|
+
entry.endpoint = query.endpoint
|
62
|
+
method = 'POST'
|
63
|
+
end
|
64
|
+
|
65
|
+
entry.fields['ownerId'] = target_account
|
66
|
+
entry.save user: user
|
67
|
+
block_update_entry entry, *args, &post_block if post_block
|
68
|
+
|
69
|
+
logger.info "deployed #{entry.fields['guid']} to #{target_account} as #{entry.id || 'new_id'} with #{user.username} via a #{method} call"
|
70
|
+
end
|
71
|
+
|
72
|
+
true
|
73
|
+
end
|
74
|
+
|
75
|
+
# @return [Array] order to deploy objects in
|
76
|
+
# @return [nil] if image state is transformed.
|
77
|
+
# @return [nil] if a deploy order could not be generated.
|
78
|
+
def deploy_order
|
79
|
+
return nil unless image.state == :untransformed
|
80
|
+
|
81
|
+
hash = dependencies
|
82
|
+
list = image.entries.map(&:id) - dependencies.keys
|
83
|
+
|
84
|
+
100.times do |_i|
|
85
|
+
break unless hash.any?
|
86
|
+
|
87
|
+
hash.delete_if { |k, _v| list.include? k }
|
88
|
+
|
89
|
+
new_hash = hash.select { |_k, v| (v - list).empty? }
|
90
|
+
list += new_hash.keys if new_hash.any?
|
91
|
+
end
|
92
|
+
|
93
|
+
return list.uniq if image.entries.map(&:id).count == list.count
|
94
|
+
|
95
|
+
nil
|
96
|
+
end
|
97
|
+
# rubocop:enable Metrics/AbcSize
|
98
|
+
|
99
|
+
def block_update_entry(entry, *args, &block)
|
100
|
+
raise ArgumentError, 'block must be provided' unless block
|
101
|
+
raise ArgumentError, 'argument must be an entry' unless entry.is_a? Entry
|
102
|
+
|
103
|
+
e = entry.dup
|
104
|
+
block.yield e, args
|
105
|
+
e
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def logger
|
111
|
+
Aci.logger
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
module Cts
|
2
|
+
module Mpx
|
3
|
+
module Aci
|
4
|
+
module Tasks
|
5
|
+
# Image class for gathering a set of service data as a single collection.
|
6
|
+
#
|
7
|
+
# @!attribute [rw] entries
|
8
|
+
# @return [Hash] set of entries to generate the image from
|
9
|
+
# @!attribute [rw] schema
|
10
|
+
# @return [String] schema of the image
|
11
|
+
# @!attribute [rw] user
|
12
|
+
# @return [User] user to make data service calls with
|
13
|
+
# @!attribute [r] account_id
|
14
|
+
# @return [String] relative account_id or nil when untransformed
|
15
|
+
# @!attribute [r] date_taken
|
16
|
+
# @return [DateTime] Date the image was instantiated
|
17
|
+
# @!attribute [r] state
|
18
|
+
# @return [String] :transformed or :untransformed
|
19
|
+
class Image
|
20
|
+
include Creatable
|
21
|
+
|
22
|
+
attribute name: 'entries', kind_of: Entries
|
23
|
+
attribute name: 'schema', kind_of: Integer
|
24
|
+
attribute name: 'user', kind_of: User
|
25
|
+
attribute name: 'account_id', kind_of: String
|
26
|
+
attribute name: 'date_taken', kind_of: Time
|
27
|
+
attribute name: 'state', kind_of: String
|
28
|
+
|
29
|
+
# load an image from directory
|
30
|
+
#
|
31
|
+
# @param user [String] user to set the image and entries to
|
32
|
+
# @return [Cts::Mpx::aciTasks::Image] image with entries loaded and info set.
|
33
|
+
def self.load_from_directory(directory, user = nil)
|
34
|
+
i = new
|
35
|
+
i.load_from_directory directory, user
|
36
|
+
i
|
37
|
+
end
|
38
|
+
|
39
|
+
# All entries in the entries, including the md5 hash of the data.
|
40
|
+
#
|
41
|
+
# @return [Hash] filepath is key, value is md5
|
42
|
+
def files
|
43
|
+
entries.map(&:filepath)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Generate information report for the image.
|
47
|
+
#
|
48
|
+
# @return [Hash] contains the information about the image.
|
49
|
+
def info
|
50
|
+
{
|
51
|
+
account_id: @account_id,
|
52
|
+
date_taken: @date_taken.iso8601,
|
53
|
+
username: @user.nil? ? "" : @user.username,
|
54
|
+
schema: @schema,
|
55
|
+
state: @state,
|
56
|
+
files: files
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def initialize
|
61
|
+
@account_id = ""
|
62
|
+
@entries = Entries.new
|
63
|
+
@date_taken = Time.now
|
64
|
+
@files = {}
|
65
|
+
@state = :untransformed
|
66
|
+
@schema = 1
|
67
|
+
@user = nil
|
68
|
+
end
|
69
|
+
|
70
|
+
# save an image to a directory
|
71
|
+
#
|
72
|
+
# @param directory [String] the name of the directory to save to
|
73
|
+
def save_to_directory(directory)
|
74
|
+
entries.each do |entry|
|
75
|
+
FileUtils.mkdir_p "#{directory}/#{entry.directory}"
|
76
|
+
File.write "#{directory}/#{entry.filepath}", entry.to_s
|
77
|
+
end
|
78
|
+
|
79
|
+
File.write "#{directory}/info.json", Oj.dump(info, indent: 2)
|
80
|
+
true
|
81
|
+
end
|
82
|
+
|
83
|
+
# load an image from directory
|
84
|
+
#
|
85
|
+
# @param user [String] user to set the image and entries to
|
86
|
+
# @return [Cts::Mpx::Aci::Tasks::Image] image with entries loaded and info set.
|
87
|
+
def load_from_directory(directory, user = nil)
|
88
|
+
raise "#{directory} does not contain a valid image." unless Validators.image_directory? directory
|
89
|
+
|
90
|
+
info = load_json_or_error "#{directory}/info.json"
|
91
|
+
|
92
|
+
["date_taken", "account_id", "schema", "username", "state"].each do |param|
|
93
|
+
instance_variable_set "@#{param}", info[param]
|
94
|
+
end
|
95
|
+
|
96
|
+
entries = Entries.new
|
97
|
+
|
98
|
+
info["files"].each do |file|
|
99
|
+
begin
|
100
|
+
h = load_json_or_error("#{directory}/#{file}")
|
101
|
+
rescue Oj::ParseError
|
102
|
+
raise "#{directory}/#{file} is readable, but not parsable. Please run the json through a linter."
|
103
|
+
end
|
104
|
+
|
105
|
+
entries.add Entry.create(fields: Fields.create_from_data(data: h[:entry], xmlns: h[:xmlns]))
|
106
|
+
end
|
107
|
+
|
108
|
+
@user = user
|
109
|
+
|
110
|
+
true
|
111
|
+
end
|
112
|
+
|
113
|
+
# merge two images together
|
114
|
+
#
|
115
|
+
# @param other_image [Image] Image to merge from
|
116
|
+
# @return [Cts::Mpx::Aci::Tasks::Image] new image containg merged results.
|
117
|
+
def merge(other_image)
|
118
|
+
raise 'an image class must be supplied' unless other_image.is_a? Image
|
119
|
+
raise 'cannot merge if the user is different' unless other_image.user == user
|
120
|
+
raise 'cannot merge if the account_id is different' unless other_image.account_id == account_id
|
121
|
+
raise 'cannot merge if the state is different' unless other_image.state == state
|
122
|
+
|
123
|
+
new_image = Image.new
|
124
|
+
new_image.user = @user
|
125
|
+
new_image.entries = entries + other_image.entries
|
126
|
+
new_image
|
127
|
+
end
|
128
|
+
|
129
|
+
# transform an image to an abstract state
|
130
|
+
def transform
|
131
|
+
entries.each { |entry| entry.transform user }
|
132
|
+
@state = :transformed
|
133
|
+
@account_id = nil
|
134
|
+
true
|
135
|
+
end
|
136
|
+
|
137
|
+
# untransform an image from an abstract state
|
138
|
+
# @param target_account [String] account_id to transform to
|
139
|
+
def untransform(target_account)
|
140
|
+
entries.each do |entry|
|
141
|
+
entry.fields['ownerId'] = target_account
|
142
|
+
entry.untransform user, target_account
|
143
|
+
end
|
144
|
+
|
145
|
+
@state = :untransformed
|
146
|
+
@account_id = target_account
|
147
|
+
true
|
148
|
+
end
|
149
|
+
|
150
|
+
private
|
151
|
+
|
152
|
+
def load_json_or_error(file)
|
153
|
+
Oj.load File.read file
|
154
|
+
rescue Oj::ParseError => exception
|
155
|
+
raise "#{exception.message.split(' [').first}: #{file}"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
module Cts
|
2
|
+
module Mpx
|
3
|
+
module Aci
|
4
|
+
# contains the logic to transform/untransform an entry.
|
5
|
+
module Transformations
|
6
|
+
module_function
|
7
|
+
|
8
|
+
# Transform a reference into a transformed_reference
|
9
|
+
# @param [User] user that will make the service calls.
|
10
|
+
# @param [String] original_account to do the transformation from
|
11
|
+
# @param [String] reference to transform to a transformed reference
|
12
|
+
# @return [String] transformed_reference
|
13
|
+
def transform_reference(reference: nil, user: nil, original_account: nil)
|
14
|
+
return "urn:cts:aci:target-account" if reference == original_account
|
15
|
+
return reference unless Validators.reference? reference
|
16
|
+
|
17
|
+
service_info = Services.from_url reference
|
18
|
+
endpoint = service_info[:endpoint]
|
19
|
+
service = service_info[:service]
|
20
|
+
return reference if service.start_with? "User Data Service"
|
21
|
+
|
22
|
+
response = Services::Data.get user: user, service: service, endpoint: endpoint, ids: reference.split('/').last
|
23
|
+
|
24
|
+
return "urn:cts:aci:no-id-found" unless (entry = response.data["entries"].first)
|
25
|
+
|
26
|
+
return "urn:cts:aci:no-guid-found" unless (guid = entry["guid"])
|
27
|
+
|
28
|
+
"urn:cts:aci:#{URI.encode_www_form_component(service)}:#{endpoint}:#{entry['ownerId'].split('/').last}:#{guid}"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Transform a field reference into a transformed_field_reference
|
32
|
+
# @param [User] user that will make the service calls.
|
33
|
+
# @param [String] field_reference to transform to a transformed field reference
|
34
|
+
# @return [String] transformed_field_reference
|
35
|
+
def transform_field_reference(field_reference: nil, user: nil)
|
36
|
+
return field_reference unless Validators.field_reference? field_reference
|
37
|
+
|
38
|
+
service_info = Services.from_url field_reference
|
39
|
+
endpoint = service_info[:endpoint]
|
40
|
+
service = service_info[:service]
|
41
|
+
response = Services::Data.get user: user, service: service, endpoint: endpoint, ids: field_reference.split('/').last, fields: 'ownerId,fieldName,namespace'
|
42
|
+
return "urn:cts:aci:no-id-found" unless (entry = response.data["entries"].first)
|
43
|
+
return "urn:cts:aci:no-qualified-field-name-found" unless entry["fieldName"]
|
44
|
+
|
45
|
+
namespace = response.data['namespace']
|
46
|
+
owner_id = entry['ownerId'].split('/').last
|
47
|
+
"urn:cts:aci:#{URI.encode_www_form_component(service)}:#{endpoint}:#{owner_id}:#{namespace}$#{entry['fieldName']}"
|
48
|
+
end
|
49
|
+
|
50
|
+
# Untransform a transformed_reference into a reference
|
51
|
+
# @param [User] user that will make the service calls.
|
52
|
+
# @param [String] target_account to do the transformation from
|
53
|
+
# @param [String] transformed_reference to transform to a reference
|
54
|
+
# @return [String] reference
|
55
|
+
def untransform_reference(transformed_reference: nil, user: nil, target_account: nil)
|
56
|
+
return target_account if transformed_reference == "urn:cts:aci:target-account"
|
57
|
+
return transformed_reference unless Validators.transformed_reference? transformed_reference
|
58
|
+
|
59
|
+
parts = transformed_reference.split ':'
|
60
|
+
endpoint = parts[4]
|
61
|
+
service = parts[3]
|
62
|
+
guid = URI.decode_www_form_component(parts[6])
|
63
|
+
owner_id = "http://access.auth.theplatform.com/data/Account/#{parts[5]}"
|
64
|
+
|
65
|
+
response = Services::Data.get user: user,
|
66
|
+
service: service,
|
67
|
+
endpoint: endpoint,
|
68
|
+
ids: transformed_reference.split('/').last,
|
69
|
+
query: { byGuid: guid, ownerId: owner_id }
|
70
|
+
|
71
|
+
raise "could not find an entry by guid" unless (entry = response.data["entries"].first)
|
72
|
+
raise "service returned too many entries on guid" if response.data["entries"].count > 1
|
73
|
+
|
74
|
+
entry['id']
|
75
|
+
end
|
76
|
+
|
77
|
+
# Untransform a transformed_field_reference into a field reference
|
78
|
+
# @param [User] user that will make the service calls.
|
79
|
+
# @param [String] transformed_field_reference to transform to a reference
|
80
|
+
# @return [String] field_reference
|
81
|
+
def untransform_field_reference(transformed_field_reference: nil, user: nil, target_account: nil)
|
82
|
+
return transformed_field_reference unless Validators.transformed_field_reference? transformed_field_reference
|
83
|
+
|
84
|
+
parts = transformed_field_reference.split ':'
|
85
|
+
endpoint = parts[4]
|
86
|
+
service = parts[3]
|
87
|
+
qualified_field_name = URI.decode_www_form_component(parts[6])
|
88
|
+
owner_id = "http://access.auth.theplatform.com/data/Account/#{parts[5]}"
|
89
|
+
|
90
|
+
response = Services::Data.get user: user,
|
91
|
+
service: service,
|
92
|
+
endpoint: endpoint,
|
93
|
+
query: { byQualifiedFieldName: qualified_field_name, ownerId: owner_id }
|
94
|
+
|
95
|
+
raise "could not find an entry by qualified field name" unless (entry = response.data["entries"].first)
|
96
|
+
raise "service returned too many entries on qualified field name" if response.data["entries"].count > 1
|
97
|
+
|
98
|
+
entry['id']
|
99
|
+
end
|
100
|
+
|
101
|
+
def traverse_for(hash, direction, &block)
|
102
|
+
id = hash['id']
|
103
|
+
output = hash.reject { |k, _v| k == 'id' }
|
104
|
+
output = Transformations.send :traverse_hash, Oj.load(Oj.dump(output)), direction, &block
|
105
|
+
{ "id" => id }.merge(output)
|
106
|
+
end
|
107
|
+
|
108
|
+
# private module method, not explicitly covered
|
109
|
+
def traverse_hash(entry, direction, &block)
|
110
|
+
entry.each do |field, value|
|
111
|
+
case value
|
112
|
+
when String
|
113
|
+
entry[field] = block.yield field, value if direction == :transform &&
|
114
|
+
Validators.reference?(value)
|
115
|
+
entry[field] = block.yield field, value if direction == :untransform &&
|
116
|
+
Validators.transformed_reference?(value)
|
117
|
+
when Array
|
118
|
+
entry[field] = traverse_array field, value, direction, &block
|
119
|
+
when Hash
|
120
|
+
entry[field] = traverse_hash value, direction, &block
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# private module method, not explicitly covered
|
126
|
+
def traverse_array(field, value, direction, &block)
|
127
|
+
if value.map(&:class).uniq.first == String
|
128
|
+
value.map do |v|
|
129
|
+
if Validators.reference?(v) || Validators.transformed_reference?(v)
|
130
|
+
block.yield field, v
|
131
|
+
else
|
132
|
+
v
|
133
|
+
end
|
134
|
+
end
|
135
|
+
elsif value.map(&:class).uniq.first == Hash
|
136
|
+
value.map { |v| traverse_hash v, direction, &block }
|
137
|
+
else
|
138
|
+
value
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module Cts
|
2
|
+
module Mpx
|
3
|
+
module Aci
|
4
|
+
# Wireline Validators
|
5
|
+
module Validators
|
6
|
+
module_function
|
7
|
+
|
8
|
+
# Test if a string is a reference or not
|
9
|
+
# @param [String] uri to test if it is a reference or not
|
10
|
+
# @return [Boolean]
|
11
|
+
def reference?(uri)
|
12
|
+
Cts::Mpx::Validators.reference?(uri)
|
13
|
+
end
|
14
|
+
|
15
|
+
def field_reference?(uri)
|
16
|
+
begin
|
17
|
+
ref = URI.parse uri
|
18
|
+
rescue URI::InvalidURIError
|
19
|
+
return false
|
20
|
+
end
|
21
|
+
|
22
|
+
return false if ref.host == 'web.theplatform.com'
|
23
|
+
return false unless ref.scheme == "http" || ref.scheme == "https"
|
24
|
+
return false unless ref.host.end_with? ".theplatform.com"
|
25
|
+
return false unless ref.path =~ /Field\/\d+/
|
26
|
+
return false if ref.path =~ /\/\D+$/
|
27
|
+
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
# Test if a string is a transformed_reference or not
|
32
|
+
# @param [String] string to check if it is a transformed_reference
|
33
|
+
# @return [Boolean]
|
34
|
+
def transformed_reference?(string)
|
35
|
+
return true if [
|
36
|
+
'urn:cts:aci:target-account',
|
37
|
+
'urn:cts:aci:no-id-found',
|
38
|
+
'urn:cts:aci:no-guid-found',
|
39
|
+
'urn:cts:aci:no-custom-field-found'
|
40
|
+
].include? string
|
41
|
+
|
42
|
+
urn_regex = /^(?i:urn:(?!urn:)([cC][tT][sS]):(?<nss>(?:[a-z0-9()\/+,-.:=@;$_!*']|%[0-9a-f]{2})+))$/
|
43
|
+
|
44
|
+
return false unless urn_regex =~ string
|
45
|
+
|
46
|
+
nss = urn_regex.match(string)["nss"]
|
47
|
+
segments = nss.split(":")
|
48
|
+
|
49
|
+
return false unless /^([aA][cC][iI])$/ =~ segments[0]
|
50
|
+
|
51
|
+
begin
|
52
|
+
service = Services[URI.decode_www_form_component(segments[1])]
|
53
|
+
rescue RuntimeError
|
54
|
+
return false
|
55
|
+
end
|
56
|
+
|
57
|
+
return false unless service.endpoints.include? segments[2].gsub('Field', '/Field')
|
58
|
+
return false unless /\A\d+\z/ =~ segments[3]
|
59
|
+
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
# Test if a string is a transformed_field_reference or not
|
64
|
+
# @param [String] string to check if it is a transformed_field_reference
|
65
|
+
# @return [Boolean]
|
66
|
+
def transformed_field_reference?(string)
|
67
|
+
return false unless transformed_reference? string
|
68
|
+
return false unless /Field:\d*:.*$/.match? string
|
69
|
+
|
70
|
+
true
|
71
|
+
end
|
72
|
+
|
73
|
+
# test if a directory is an image_directory
|
74
|
+
# @param [String] image_directory to check if it is a transformed_reference
|
75
|
+
# @return [Boolean]
|
76
|
+
def image_directory?(image_directory)
|
77
|
+
return false unless File.exist? "#{image_directory}/info.json"
|
78
|
+
|
79
|
+
true
|
80
|
+
end
|
81
|
+
|
82
|
+
# test if a image will depoly
|
83
|
+
# @param [Tasks::Image] image to check if it is a transformed_reference
|
84
|
+
# @return [Boolean]
|
85
|
+
def image_deployable?(image)
|
86
|
+
return false if image.state == :transformed || image.state == 'transformed'
|
87
|
+
return false if image.entries.collection.empty?
|
88
|
+
|
89
|
+
image.entries.each do |entry|
|
90
|
+
Transformations.traverse_for(entry.to_h, :untransform) do |_k, v|
|
91
|
+
return false if v =~ /^urn:cts:aci:no-(gu)?id-found$/
|
92
|
+
end
|
93
|
+
end
|
94
|
+
true
|
95
|
+
end
|
96
|
+
|
97
|
+
# Test if a string is a transformed_reference or not
|
98
|
+
# @param [String] filename to check if it is a valid info.json or not
|
99
|
+
# @return [Boolean]
|
100
|
+
def info_file?(filename)
|
101
|
+
raise "could not find an info.json" unless File.exist? filename
|
102
|
+
|
103
|
+
begin
|
104
|
+
Oj.load(File.read(filename))
|
105
|
+
rescue Oj::ParseError
|
106
|
+
return false
|
107
|
+
end
|
108
|
+
|
109
|
+
true
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|