gd_bam 0.1.35 → 0.1.36
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.
- data/bin/bam +79 -10
- data/lib/bam/version.rb +1 -1
- data/lib/cloud_connect/dsl/sf_helpers.rb +5 -1
- data/lib/cloud_connect/dsl/structure_helpers.rb +4 -0
- data/lib/commands/commands.rb +92 -0
- data/lib/commands/gd_commands.rb +8 -4
- data/lib/generators/downloaders.rb +195 -44
- metadata +18 -2
data/bin/bam
CHANGED
@@ -21,6 +21,17 @@ default_value false
|
|
21
21
|
arg_name 'logger'
|
22
22
|
switch [:l,:logger]
|
23
23
|
|
24
|
+
desc 'Platform server'
|
25
|
+
default_value nil
|
26
|
+
arg_name 'server'
|
27
|
+
flag [:s,:server]
|
28
|
+
|
29
|
+
desc 'Platform uploads server'
|
30
|
+
default_value nil
|
31
|
+
arg_name 'web dav upload server'
|
32
|
+
flag [:w,:webdav_server]
|
33
|
+
|
34
|
+
|
24
35
|
desc 'Generates clover project based on information in current directory. The default ouptut is the directory ./clover-project'
|
25
36
|
# arg_name 'Describe arguments to new here'
|
26
37
|
command :generate do |c|
|
@@ -99,7 +110,7 @@ command :run_validator do |c|
|
|
99
110
|
end
|
100
111
|
fail "You need to specify process" if process.blank?
|
101
112
|
|
102
|
-
GoodData::Bam::Commands::connect_to_gd()
|
113
|
+
GoodData::Bam::Commands::connect_to_gd(global_options)
|
103
114
|
GoodData::Bam::Commands::run_validator(process, files, PARAMS)
|
104
115
|
end
|
105
116
|
end
|
@@ -240,6 +251,62 @@ command :procs do |c|
|
|
240
251
|
end
|
241
252
|
|
242
253
|
|
254
|
+
desc 'Replicate and join S3 backup locally. Use ONLY if you knwo what it does.'
|
255
|
+
command :clone_backup_locally do |c|
|
256
|
+
|
257
|
+
c.desc 'taps'
|
258
|
+
c.arg_name 'taps'
|
259
|
+
c.flag :taps
|
260
|
+
|
261
|
+
|
262
|
+
c.action do |global_options,options,args|
|
263
|
+
only = options[:only]
|
264
|
+
params = PARAMS.merge({
|
265
|
+
:project_name => "backup-restore-#{PARAMS[:project_name]}",
|
266
|
+
:graph_repos => [
|
267
|
+
GoodData::Bam::Repository.create(:type => :file, :base => './local_graphs'),
|
268
|
+
GoodData::Bam::Repository.create(:type => :file, :base => GoodData::CloverGenerator::BAM_DEFINED_GRAPHS_ROOT)],
|
269
|
+
:only => only
|
270
|
+
})
|
271
|
+
GoodData::Bam::Commands::clone_backup(".", params)
|
272
|
+
end
|
273
|
+
|
274
|
+
end
|
275
|
+
desc 'Restore data from S3 backup'
|
276
|
+
command :restore_backup do |c|
|
277
|
+
|
278
|
+
c.desc 'ES name'
|
279
|
+
c.arg_name 'es'
|
280
|
+
c.flag :es
|
281
|
+
|
282
|
+
c.desc 'specify tap to process only that one'
|
283
|
+
c.arg_name 'only'
|
284
|
+
c.flag :only
|
285
|
+
|
286
|
+
|
287
|
+
c.action do |global_options,options,args|
|
288
|
+
new_es = options[:es]
|
289
|
+
only = options[:only]
|
290
|
+
params = PARAMS.merge({
|
291
|
+
:project_name => "backup-restore-#{PARAMS[:project_name]}",
|
292
|
+
:graph_repos => [
|
293
|
+
GoodData::Bam::Repository.create(:type => :file, :base => './local_graphs'),
|
294
|
+
GoodData::Bam::Repository.create(:type => :file, :base => GoodData::CloverGenerator::BAM_DEFINED_GRAPHS_ROOT)],
|
295
|
+
:new_es => new_es,
|
296
|
+
:only => only
|
297
|
+
})
|
298
|
+
|
299
|
+
fail "You do not have backup information specified. I do not know where to look for the backup." unless PARAMS[:s3_backup]
|
300
|
+
fail "You did not specify an ES." if new_es.blank?
|
301
|
+
fail "ES cannot be the same as you currently have in params.json. The point is to use a new one. If anything goes wrong you can always go back." if new_es == (params[:additional_params] && params[:additional_params][:GDC_EVENTSTORE])
|
302
|
+
|
303
|
+
# puts "Let's reload backup"
|
304
|
+
GoodData::Bam::Commands::generate_backup_restoration(".", params)
|
305
|
+
end
|
306
|
+
|
307
|
+
end
|
308
|
+
|
309
|
+
|
243
310
|
desc 'Creates project'
|
244
311
|
command :project do |c|
|
245
312
|
|
@@ -253,20 +320,22 @@ command :project do |c|
|
|
253
320
|
|
254
321
|
c.action do |global_options,options,args|
|
255
322
|
fail "You need to specify token to create a project" if options[:token].nil?
|
256
|
-
GoodData::Bam::Commands::connect_to_gd()
|
257
|
-
|
323
|
+
GoodData::Bam::Commands::connect_to_gd(global_options)
|
324
|
+
creation_info = case options[:blueprint]
|
258
325
|
when "goodsales"
|
259
|
-
"
|
326
|
+
{ :template => "/projectTemplates/GoodSalesAnalytics/2" }
|
260
327
|
when "box"
|
261
|
-
"n1zoyqvahupyxfxv35nzo0ernax69odm"
|
328
|
+
{ :pid => "n1zoyqvahupyxfxv35nzo0ernax69odm" }
|
262
329
|
end
|
263
330
|
|
264
331
|
params = PARAMS.merge({:token => options[:token]})
|
265
332
|
|
266
|
-
new_project = if
|
267
|
-
|
268
|
-
|
333
|
+
new_project = if creation_info && creation_info.has_key?(:template)
|
334
|
+
params = PARAMS.merge({:token => options[:token], :template => creation_info[:template]})
|
335
|
+
|
269
336
|
GoodData::Bam::Commands.create_project(params)
|
337
|
+
else
|
338
|
+
GoodData::Bam::Commands.clone_project(pid, params)
|
270
339
|
end
|
271
340
|
|
272
341
|
puts "Your project pid is #{new_project}"
|
@@ -360,7 +429,7 @@ command :deploy do |c|
|
|
360
429
|
fail "You have to specify directory to deploy as an argument" if dir.nil?
|
361
430
|
fail "Specified directory does not exist" unless File.exist?(dir)
|
362
431
|
|
363
|
-
GoodData::Bam::Commands::connect_to_gd()
|
432
|
+
GoodData::Bam::Commands::connect_to_gd(global_options)
|
364
433
|
params = PARAMS.merge(global_options.merge(options))
|
365
434
|
response = GoodData::Bam::Commands::deploy(dir, params)
|
366
435
|
end
|
@@ -380,7 +449,7 @@ command :run do |c|
|
|
380
449
|
fail "Specified directory does not exist" unless File.exist?(dir)
|
381
450
|
|
382
451
|
params = PARAMS.merge(global_options.merge(options))
|
383
|
-
GoodData::Bam::Commands::connect_to_gd()
|
452
|
+
GoodData::Bam::Commands::connect_to_gd(global_options)
|
384
453
|
GoodData::Bam::Commands::run(dir, params)
|
385
454
|
end
|
386
455
|
end
|
data/lib/bam/version.rb
CHANGED
@@ -45,7 +45,11 @@ module GoodData
|
|
45
45
|
:token => "${SFDC_TOKEN}",
|
46
46
|
:type => "SFDC",
|
47
47
|
:username => "${SFDC_USERNAME}",
|
48
|
-
:passwordEncrypted => "false"
|
48
|
+
:passwordEncrypted => "false",
|
49
|
+
:consumerKey => "${SFDC_CONSUMER_KEY}",
|
50
|
+
:consumerSecret => "${SFDC_CONSUMER_SECRET}",
|
51
|
+
:credentialsType => "${SFDC_CREDENTIALS_TYPE}",
|
52
|
+
:refreshToken => "${SFDC_REFRESH_TOKEN}"
|
49
53
|
})
|
50
54
|
end
|
51
55
|
end
|
@@ -4,6 +4,10 @@ module GoodData
|
|
4
4
|
|
5
5
|
include GoodData::CloudConnect
|
6
6
|
|
7
|
+
# Structural pattern
|
8
|
+
# loop_over_file will loop over every line provided in the file given as parameter
|
9
|
+
# it will run the graph given as options[:graph_to_run]
|
10
|
+
# it will make all arrangments that the underlying graph will have access to only one line thus making a loop
|
7
11
|
def self.loop_over_file(file, options={})
|
8
12
|
file_to_loop = options[:file_to_loop]
|
9
13
|
token = options[:token]
|
data/lib/commands/commands.rb
CHANGED
@@ -103,6 +103,98 @@ module GoodData
|
|
103
103
|
GoodData::Bam::Generators::Downloaders.generate_history_downloaders(home + DOWNLOADERS_HOME + "graphs", project, params)
|
104
104
|
end
|
105
105
|
|
106
|
+
def self.generate_backup_restoration(home, params)
|
107
|
+
home = Pathname(home)
|
108
|
+
new_params = params.clone
|
109
|
+
only = params[:only]
|
110
|
+
new_params[:additional_params][:GDC_EVENTSTORE] = params[:new_es]
|
111
|
+
clobber_downloaders_project(home)
|
112
|
+
project = GoodData::Bam::Project.build_project(home, new_params)
|
113
|
+
|
114
|
+
require 'aws-sdk'
|
115
|
+
AWS.config(
|
116
|
+
:access_key_id => params[:additional_params][:S3_ACCESS_KEY_ID],
|
117
|
+
:secret_access_key => params[:additional_params][:S3_SECRET_ACCESS_KEY]
|
118
|
+
)
|
119
|
+
|
120
|
+
s3_interface_from = AWS::S3.new()
|
121
|
+
bucket_from = s3_interface_from.buckets[params[:additional_params][:S3_BUCKETNAME]]
|
122
|
+
|
123
|
+
files_in_from_bucket = bucket_from.objects.map {|o| o.key}
|
124
|
+
|
125
|
+
incremental_taps = Taps.get_incremental(project[:taps])
|
126
|
+
|
127
|
+
setup_downloaders_project(home, new_params)
|
128
|
+
GoodData::Bam::Generators::Downloaders.generate_backup_restoration_graph(home + DOWNLOADERS_HOME + "graphs", project, new_params)
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.clone_backup(home, params)
|
133
|
+
home = Pathname(home)
|
134
|
+
new_params = params.clone
|
135
|
+
only = params[:only]
|
136
|
+
new_params[:additional_params][:GDC_EVENTSTORE] = params[:new_es]
|
137
|
+
clobber_downloaders_project(home)
|
138
|
+
project = GoodData::Bam::Project.build_project(home, new_params)
|
139
|
+
|
140
|
+
require 'aws-sdk'
|
141
|
+
AWS.config(
|
142
|
+
:access_key_id => params[:additional_params][:S3_ACCESS_KEY_ID],
|
143
|
+
:secret_access_key => params[:additional_params][:S3_SECRET_ACCESS_KEY]
|
144
|
+
)
|
145
|
+
|
146
|
+
s3_interface_from = AWS::S3.new()
|
147
|
+
bucket_from = s3_interface_from.buckets[params[:additional_params][:S3_BUCKETNAME]]
|
148
|
+
|
149
|
+
files_in_from_bucket = bucket_from.objects.map {|o| o.key}
|
150
|
+
|
151
|
+
binding.pry
|
152
|
+
|
153
|
+
incremental_taps = Taps.get_incremental(project[:taps])
|
154
|
+
|
155
|
+
taps_to_process = if only.blank?
|
156
|
+
incremental_taps
|
157
|
+
else
|
158
|
+
# binding.pry
|
159
|
+
temp = Taps.get_incremental([Project::find_tap_by_id(project, only)].reject {|x| x.nil?})
|
160
|
+
fail "There is no such tap \"#{only}\"" if temp.empty?
|
161
|
+
temp
|
162
|
+
end
|
163
|
+
|
164
|
+
taps_to_process.each do |tap|
|
165
|
+
what = tap[:id]
|
166
|
+
Dir.mktmpdir do |dir|
|
167
|
+
dir = Pathname(dir)
|
168
|
+
files_in_from_bucket.grep(/#{params[:project_pid]}\/#{what}\/#{what}/).each do |file_name|
|
169
|
+
puts "Downloading #{file_name}"
|
170
|
+
o = bucket_from.objects[file_name]
|
171
|
+
local_File_name = file_name.split("\/").last
|
172
|
+
# puts local_File_name
|
173
|
+
File.open(dir + local_File_name,"w") do |local_file|
|
174
|
+
local_file.write(o.read)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# FileUtils::cd(dir) do
|
179
|
+
full_file_name = "full_" + what + ".csv"
|
180
|
+
# TODO
|
181
|
+
system "\"line to be skipped\n\">> #{dir + full_file_name}"
|
182
|
+
|
183
|
+
system "for i in #{dir + what}*
|
184
|
+
do
|
185
|
+
if test -f \"$i\"
|
186
|
+
then
|
187
|
+
echo \"Doing somthing to $i\"
|
188
|
+
tail +2 \"$i\" >> #{dir + full_file_name}
|
189
|
+
fi
|
190
|
+
done"
|
191
|
+
FileUtils::cp(dir + full_file_name, full_file_name)
|
192
|
+
# binding.pry
|
193
|
+
# end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
106
198
|
def self.generate(home, params)
|
107
199
|
# fail "The flow you specified was not found" if flows.empty? && !only_flow.nil?
|
108
200
|
clobber_etl_project(home)
|
data/lib/commands/gd_commands.rb
CHANGED
@@ -3,8 +3,9 @@ module GoodData
|
|
3
3
|
module Commands
|
4
4
|
|
5
5
|
def self.connect_to_gd(options={})
|
6
|
-
|
7
|
-
|
6
|
+
server = options[:server]
|
7
|
+
GoodData.connect(PARAMS[:gd_login], PARAMS[:gd_pass], server, options)
|
8
|
+
GoodData.project = PARAMS[:project_pid] if !PARAMS[:project_pid].nil? && !PARAMS[:project_pid].empty?
|
8
9
|
end
|
9
10
|
|
10
11
|
def self.set_up_debug(project, flow, graph)
|
@@ -73,15 +74,18 @@ module GoodData
|
|
73
74
|
:project => {
|
74
75
|
:content => {
|
75
76
|
:guidedNavigation => 1,
|
76
|
-
:driver => "Pg",
|
77
|
+
:driver => "Pg",
|
77
78
|
:authorizationToken => options[:token]
|
78
79
|
},
|
79
80
|
:meta => {
|
80
81
|
:title => project_name,
|
81
|
-
:summary => "Testing Project"
|
82
|
+
:summary => "Testing Project",
|
83
|
+
:projectTemplate => options[:template]
|
82
84
|
}
|
83
85
|
}
|
84
86
|
}
|
87
|
+
|
88
|
+
binding.pry
|
85
89
|
result = GoodData.post("/gdc/projects/", pr)
|
86
90
|
uri = result["uri"]
|
87
91
|
while(GoodData.get(uri)["project"]["content"]["state"] == "LOADING")
|
@@ -139,68 +139,150 @@ HEREDOC
|
|
139
139
|
end
|
140
140
|
|
141
141
|
file_taps = Taps.get_file(taps)
|
142
|
+
generate_file_lists(file_taps, {
|
143
|
+
phase => phase,
|
144
|
+
:builder => builder,
|
145
|
+
:reformat_func => :webdav
|
146
|
+
})
|
147
|
+
# file_taps.each do |tap|
|
148
|
+
# source = tap[:source]
|
149
|
+
# id = tap[:id]
|
150
|
+
#
|
151
|
+
#
|
152
|
+
# reformat_func = <<HEREDOC
|
153
|
+
#
|
154
|
+
# function integer transform() {
|
155
|
+
# $out.0.filePath = replace($in.0.filePath, "${GDC_WEBDAV_HOST}", replace(replace(\"${GD_LOGIN}\",\"@\",\"%40\"),\"\\\\+\",\"%2B\") + ":${GD_PASSWORD}@${GDC_WEBDAV_HOST}");
|
156
|
+
# $out.0.fileName = $in.0.fileName;
|
157
|
+
# return ALL;
|
158
|
+
# }
|
159
|
+
# HEREDOC
|
160
|
+
#
|
161
|
+
# builder.Phase(:number => phase += 1) do
|
162
|
+
# Core::build_node2(builder, Nodes.file_list2({:id => "#{id}_file_list", :name => "#{id}_file_list", :dataPolicy => "Strict", :baseURL => "#{tap[:source]}", :output_mapping => Nodes::MAP_ALL}))
|
163
|
+
# Core::build_node2(builder, Nodes.reformat2({:name => "#{id} Reformat", :id => "#{id}_reformat", :transformation => reformat_func}))
|
164
|
+
# Core::build_node2(builder, Nodes.edge2({:toNode => "#{id}_reformat:0", :fromNode => "#{id}_file_list:0", :metadata => "file_list"}))
|
165
|
+
# Core::build_node2(builder, Nodes.writer2({:name => "PARAMS CSV Writer", :id => "#{id}_writer", :fileURL => "data/#{id}_files_to_read.csv"}))
|
166
|
+
# Core::build_node2(builder, Nodes.edge2({:toNode => "#{id}_writer:0", :fromNode => "#{id}_reformat:0", :metadata => "file_list"}))
|
167
|
+
# end
|
168
|
+
#
|
169
|
+
# builder.Phase(:number => phase += 1) do
|
170
|
+
# ctl = "function integer generate() {$out.0.all = \"#{id}_SKIP_LINES=0\";return OK;}"
|
171
|
+
# Core::build_node2(builder, Nodes.data_generator2({:name => "#{id}_generator", :id => "#{id}_generator", :generate => ctl}))
|
172
|
+
# Core::build_node2(builder, Nodes.writer2({:name => "PARAMS CSV Writer", :id => "#{id}_csv_writer", :fileURL => "#{id}_counter.prm", :outputFieldNames => "false", :quotedStrings => "false"}))
|
173
|
+
# Core::build_node2(builder, Nodes.edge2({:toNode => "#{id}_csv_writer:0", :fromNode => "#{id}_generator:0", :metadata => "trash_metadata"}))
|
174
|
+
# end
|
175
|
+
#
|
176
|
+
# subgraph_reformat_func = <<HEREDOC
|
177
|
+
#
|
178
|
+
# function integer transform() {
|
179
|
+
# $out.0.all = "graphs/#{id}_loop.grf";
|
180
|
+
# return ALL;
|
181
|
+
# }
|
182
|
+
# HEREDOC
|
183
|
+
#
|
184
|
+
# fail_reformat = <<HEREDOC
|
185
|
+
# function integer transform() {
|
186
|
+
# raiseError("Loop failed");
|
187
|
+
# }
|
188
|
+
# HEREDOC
|
189
|
+
#
|
190
|
+
#
|
191
|
+
# builder.Phase(:number => phase += 1) do
|
192
|
+
# Core::build_node2(builder, Nodes.reformat2({:name => "#{id} Reformat graph", :id => "#{id}_reformat_graph", :transformation => subgraph_reformat_func}))
|
193
|
+
# Core::build_node2(builder, Nodes.edge2({:toNode => "#{id}_reformat_graph:0", :fromNode => "#{id}_reformat:1", :metadata => "file_list"}))
|
194
|
+
# Core::build_node2(builder, Nodes.run_graph2({
|
195
|
+
# :guiName => id,
|
196
|
+
# :name => id,
|
197
|
+
# :id => "#{id}_run_graph"
|
198
|
+
# }))
|
199
|
+
# Core::build_node2(builder, Nodes.edge2({:toNode => "#{id}_run_graph:0", :fromNode => "#{id}_reformat_graph:0", :metadata => "trash_metadata"}))
|
200
|
+
# Core::build_node2(builder, Nodes.reformat2({:name => "#{id} Reformat fail", :id => "#{id}_reformat_fail", :transformation => fail_reformat}))
|
201
|
+
# Core::build_node2(builder, Nodes.edge2({:toNode => "#{id}_reformat_fail:0", :fromNode => "#{id}_run_graph:1", :metadata => "run_graph_failure_metadata"}))
|
202
|
+
# Core::build_node2(builder, Nodes.trash2({:name => "#{id}_trash", :id => "#{id}_trash", :debugPrint => true}))
|
203
|
+
# Core::build_node2(builder, Nodes.edge2({:toNode => "#{id}_trash:0", :fromNode => "#{id}_reformat_fail:0", :metadata => "run_graph_failure_metadata"}))
|
204
|
+
# end
|
205
|
+
# end
|
142
206
|
|
143
|
-
file_taps.each do |tap|
|
144
|
-
source = tap[:source]
|
145
|
-
id = tap[:id]
|
146
207
|
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
147
211
|
|
212
|
+
def self.generate_file_lists(taps, options={})
|
213
|
+
phase = options[:phase] || 0
|
214
|
+
builder = options[:builder] || fail("I need a builder")
|
215
|
+
reformat_func = nil
|
216
|
+
case options[:reformat_func]
|
217
|
+
when :webdav
|
148
218
|
reformat_func = <<HEREDOC
|
149
219
|
|
150
220
|
function integer transform() {
|
151
|
-
|
152
|
-
|
153
|
-
|
221
|
+
$out.0.filePath = replace($in.0.filePath, "${GDC_WEBDAV_HOST}", replace(replace(\"${GD_LOGIN}\",\"@\",\"%40\"),\"\\\\+\",\"%2B\") + ":${GD_PASSWORD}@${GDC_WEBDAV_HOST}");
|
222
|
+
$out.0.fileName = $in.0.fileName;
|
223
|
+
return ALL;
|
154
224
|
}
|
155
225
|
HEREDOC
|
226
|
+
when :s3
|
227
|
+
reformat_func = <<HEREDOC
|
156
228
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
229
|
+
function integer transform() {
|
230
|
+
|
231
|
+
$out.0.filePath = replace($in.0.filePath, "https://", "https://${S3_ACCESS_KEY_ID}:${S3_SECRET_ACCESS_KEY}@");
|
232
|
+
$out.0.fileName = $in.0.fileName;
|
233
|
+
return ALL;
|
234
|
+
}
|
235
|
+
HEREDOC
|
236
|
+
else
|
237
|
+
reformat_func = Nodes::MAP_ALL
|
238
|
+
end
|
239
|
+
taps.each do |tap|
|
240
|
+
source = tap[:source]
|
241
|
+
id = tap[:id]
|
242
|
+
|
243
|
+
builder.Phase(:number => phase += 1) do
|
244
|
+
Core::build_node2(builder, Nodes.file_list2({:id => "#{id}_file_list", :name => "#{id}_file_list", :dataPolicy => "Strict", :baseURL => "#{tap[:source]}", :output_mapping => Nodes::MAP_ALL}))
|
245
|
+
Core::build_node2(builder, Nodes.reformat2({:name => "#{id} Reformat", :id => "#{id}_reformat", :transformation => reformat_func}))
|
246
|
+
Core::build_node2(builder, Nodes.edge2({:toNode => "#{id}_reformat:0", :fromNode => "#{id}_file_list:0", :metadata => "file_list"}))
|
247
|
+
Core::build_node2(builder, Nodes.writer2({:name => "PARAMS CSV Writer", :id => "#{id}_writer", :fileURL => "data/#{id}_files_to_read.csv"}))
|
248
|
+
Core::build_node2(builder, Nodes.edge2({:toNode => "#{id}_writer:0", :fromNode => "#{id}_reformat:0", :metadata => "file_list"}))
|
249
|
+
end
|
164
250
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
251
|
+
builder.Phase(:number => phase += 1) do
|
252
|
+
ctl = "function integer generate() {$out.0.all = \"#{id}_SKIP_LINES=0\";return OK;}"
|
253
|
+
Core::build_node2(builder, Nodes.data_generator2({:name => "#{id}_generator", :id => "#{id}_generator", :generate => ctl}))
|
254
|
+
Core::build_node2(builder, Nodes.writer2({:name => "PARAMS CSV Writer", :id => "#{id}_csv_writer", :fileURL => "#{id}_counter.prm", :outputFieldNames => "false", :quotedStrings => "false"}))
|
255
|
+
Core::build_node2(builder, Nodes.edge2({:toNode => "#{id}_csv_writer:0", :fromNode => "#{id}_generator:0", :metadata => "trash_metadata"}))
|
256
|
+
end
|
171
257
|
|
172
|
-
|
258
|
+
subgraph_reformat_func = <<HEREDOC
|
173
259
|
|
174
260
|
function integer transform() {
|
175
|
-
|
176
|
-
|
261
|
+
$out.0.all = "graphs/#{id}_loop.grf";
|
262
|
+
return ALL;
|
177
263
|
}
|
178
264
|
HEREDOC
|
179
265
|
|
180
|
-
|
266
|
+
fail_reformat = <<HEREDOC
|
181
267
|
function integer transform() {
|
182
|
-
|
268
|
+
raiseError("Loop failed");
|
183
269
|
}
|
184
270
|
HEREDOC
|
185
271
|
|
186
272
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
|
273
|
+
builder.Phase(:number => phase += 1) do
|
274
|
+
Core::build_node2(builder, Nodes.reformat2({:name => "#{id} Reformat graph", :id => "#{id}_reformat_graph", :transformation => subgraph_reformat_func}))
|
275
|
+
Core::build_node2(builder, Nodes.edge2({:toNode => "#{id}_reformat_graph:0", :fromNode => "#{id}_reformat:1", :metadata => "file_list"}))
|
276
|
+
Core::build_node2(builder, Nodes.run_graph2({
|
277
|
+
:guiName => id,
|
278
|
+
:name => id,
|
279
|
+
:id => "#{id}_run_graph"
|
280
|
+
}))
|
281
|
+
Core::build_node2(builder, Nodes.edge2({:toNode => "#{id}_run_graph:0", :fromNode => "#{id}_reformat_graph:0", :metadata => "trash_metadata"}))
|
282
|
+
Core::build_node2(builder, Nodes.reformat2({:name => "#{id} Reformat fail", :id => "#{id}_reformat_fail", :transformation => fail_reformat}))
|
283
|
+
Core::build_node2(builder, Nodes.edge2({:toNode => "#{id}_reformat_fail:0", :fromNode => "#{id}_run_graph:1", :metadata => "run_graph_failure_metadata"}))
|
284
|
+
Core::build_node2(builder, Nodes.trash2({:name => "#{id}_trash", :id => "#{id}_trash", :debugPrint => true}))
|
285
|
+
Core::build_node2(builder, Nodes.edge2({:toNode => "#{id}_trash:0", :fromNode => "#{id}_reformat_fail:0", :metadata => "run_graph_failure_metadata"}))
|
204
286
|
end
|
205
287
|
end
|
206
288
|
end
|
@@ -689,11 +771,78 @@ HEREDOC
|
|
689
771
|
:file_to_loop => "data/#{id}_files_to_read.csv",
|
690
772
|
:graph_to_run => "graphs/#{id}_download.grf"
|
691
773
|
})
|
692
|
-
create_incremental_file_downloading_graph(home + "#{tap[:id]}_download.grf", [tap], params)
|
774
|
+
create_incremental_file_downloading_graph(home + "#{tap[:id]}_download.grf", [tap], params.merge(:delete_after_processing => true))
|
693
775
|
|
694
776
|
end
|
695
777
|
end
|
696
778
|
|
779
|
+
def self.create_backup_restoration_run_graph(file, taps, options={})
|
780
|
+
|
781
|
+
File.open(file, "w") do |file|
|
782
|
+
builder = Builder::XmlMarkup.new(:target=>file, :indent=>2)
|
783
|
+
builder.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
|
784
|
+
builder.Graph({
|
785
|
+
:name => "Run graph"
|
786
|
+
}) do
|
787
|
+
builder.Global do
|
788
|
+
Helpers::property_file(builder, {:id => "workspace_params", :fileURL => "workspace.prm"})
|
789
|
+
Helpers::property_file(builder, {:id => "params_params", :fileURL => "params.prm"})
|
790
|
+
Helpers::create_trash_meta(builder)
|
791
|
+
Helpers::create_lookup_meta(builder)
|
792
|
+
Helpers::create_file_list_meta(builder)
|
793
|
+
Helpers::create_run_graph_failure_metadata(builder)
|
794
|
+
|
795
|
+
Core::build_node2(builder, Nodes.lookup2({:name => "gdLookup0", :id => "gdLookup0", :type => Nodes::GD_LOOKUP, :metadata => "lookup_metadata"}))
|
796
|
+
|
797
|
+
end
|
798
|
+
|
799
|
+
s3_taps = taps.map do |tap|
|
800
|
+
file = tap[:id]
|
801
|
+
# binding.pry
|
802
|
+
Tap.create(tap.merge({:source => "../full_#{file}.csv"}))
|
803
|
+
end
|
804
|
+
generate_file_lists(s3_taps, {
|
805
|
+
:builder => builder,
|
806
|
+
:reformat_func => :local
|
807
|
+
})
|
808
|
+
end
|
809
|
+
end
|
810
|
+
end
|
811
|
+
|
812
|
+
# Since everything that BAM touches is stored to S3 (if credentials are provided).
|
813
|
+
# it should be easy to restore it to any state
|
814
|
+
# if the timestamp is not provided in TAP it is nevertheless created so we are ensured predictable state
|
815
|
+
def self.generate_backup_restoration_graph(home, project, params)
|
816
|
+
home = Pathname(home)
|
817
|
+
only = params[:only]
|
818
|
+
|
819
|
+
incremental_taps = Taps.get_incremental(project[:taps])
|
820
|
+
|
821
|
+
taps_to_process = if only.blank?
|
822
|
+
incremental_taps
|
823
|
+
else
|
824
|
+
temp = Taps.get_incremental([Project::find_tap_by_id(project, only)].reject {|x| x.nil?})
|
825
|
+
fail "There is no such tap \"#{only}\"" if temp.empty?
|
826
|
+
temp
|
827
|
+
end
|
828
|
+
|
829
|
+
# sf_taps = Taps.get_salesforce(incremental_taps)
|
830
|
+
# file_taps = Taps.get_file(incremental_taps)
|
831
|
+
|
832
|
+
create_backup_restoration_run_graph(home + "main.grf", taps_to_process)
|
833
|
+
|
834
|
+
taps_to_process.each do |tap|
|
835
|
+
id = tap[:id]
|
836
|
+
Helpers::loop_over_file(home + "#{tap[:id]}_loop.grf", {
|
837
|
+
:token => id,
|
838
|
+
:file_to_loop => "data/#{id}_files_to_read.csv",
|
839
|
+
:graph_to_run => "graphs/#{id}_download.grf"
|
840
|
+
})
|
841
|
+
# Do not backup since we are just using backup files. Also explicitely forbid deleting the files from S3 to prevent default behavior
|
842
|
+
restoration_params = params.merge(:s3_backup => false, :delete_after_processing => false)
|
843
|
+
create_incremental_file_downloading_graph(home + "#{tap[:id]}_download.grf", [tap], restoration_params)
|
844
|
+
end
|
845
|
+
end
|
697
846
|
|
698
847
|
def self.generate_history_downloaders(home, project, params)
|
699
848
|
home = Pathname(home)
|
@@ -799,8 +948,10 @@ HEREDOC
|
|
799
948
|
Core::build_node2(builder, Nodes.edge2({:toNode => "#{file}_es:0", :fromNode => "#{file}_es_sort:0", :metadata => "#{file}_es_metadata"}))
|
800
949
|
end
|
801
950
|
|
802
|
-
|
803
|
-
|
951
|
+
if options[:delete_after_processing] == true
|
952
|
+
builder.Phase(:number => phase += 1) do
|
953
|
+
Core::build_node2(builder, Nodes.file_delete2({:guiName => "#{file}_file_delete", :name => "#{file}_file_delete", :id => "#{file}_file_delete", :baseURL => "${FILE}"}))
|
954
|
+
end
|
804
955
|
end
|
805
956
|
|
806
957
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gd_bam
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.36
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-11-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -283,6 +283,22 @@ dependencies:
|
|
283
283
|
- - ! '>='
|
284
284
|
- !ruby/object:Gem::Version
|
285
285
|
version: '0'
|
286
|
+
- !ruby/object:Gem::Dependency
|
287
|
+
name: aws-sdk
|
288
|
+
requirement: !ruby/object:Gem::Requirement
|
289
|
+
none: false
|
290
|
+
requirements:
|
291
|
+
- - ! '>='
|
292
|
+
- !ruby/object:Gem::Version
|
293
|
+
version: '0'
|
294
|
+
type: :runtime
|
295
|
+
prerelease: false
|
296
|
+
version_requirements: !ruby/object:Gem::Requirement
|
297
|
+
none: false
|
298
|
+
requirements:
|
299
|
+
- - ! '>='
|
300
|
+
- !ruby/object:Gem::Version
|
301
|
+
version: '0'
|
286
302
|
- !ruby/object:Gem::Dependency
|
287
303
|
name: rubyzip
|
288
304
|
requirement: !ruby/object:Gem::Requirement
|