echi-converter 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,27 @@
1
+ class CreateEchiVdns < ActiveRecord::Migration
2
+ def self.up
3
+ #We create the table from the one defined in the application.yml file
4
+ create_table "echi_vdns", :force => true do |t|
5
+ @@echi_schema["echi_vdns"].each do | field |
6
+ case field["type"]
7
+ when 'int'
8
+ t.column field["name"], :integer, :limit => field["length"], :precision => field["length"], :scale => 0
9
+ when 'str'
10
+ t.column field["name"], :string, :limit => field["length"]
11
+ when 'datetime'
12
+ t.column field["name"], :datetime
13
+ when 'bool'
14
+ t.column field["name"], :string, :limit => 1
15
+ when 'bool_int'
16
+ t.column field["name"], :string, :limit => 1
17
+ end
18
+ end
19
+ end
20
+ add_index "echi_vdns", "vdn"
21
+ end
22
+
23
+ def self.down
24
+ remove_index "echi_vdns", "vdn"
25
+ drop_table "echi_vdns"
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ #A test script that allows one to do a quick database connection test
2
+ #to ensure their database connectivity is configured properly
3
+ #require AR
4
+ require 'rubygems'
5
+ require 'active_record'
6
+
7
+ # connect to the Database
8
+ ActiveRecord:: Base.establish_connection(
9
+ :adapter => "oracle",
10
+ :database => "192.168.10.3/orapr1",
11
+ :username => "myname",
12
+ :password => "mypass"
13
+ )
14
+
15
+ #define a simple model
16
+ class EchiRecord < ActiveRecord::Base
17
+ set_table_name "PCO_ECHIRECORD" # comment out if not using oracle
18
+ end
19
+
20
+ begin
21
+ record=EchiRecord.find(:first)
22
+ puts record.inspect
23
+ rescue => err
24
+ puts err
25
+ end
data/lib/database.rb CHANGED
@@ -4,6 +4,15 @@ end
4
4
  class EchiLog < ActiveRecord::Base
5
5
  end
6
6
 
7
- #The EchiAgent database table may not always be present
7
+ #These database tables may not always be present
8
8
  class EchiAgent < ActiveRecord::Base
9
9
  end
10
+
11
+ class EchiAuxReason < ActiveRecord::Base
12
+ end
13
+
14
+ class EchiCwc < ActiveRecord::Base
15
+ end
16
+
17
+ class EchiVdn < ActiveRecord::Base
18
+ end
@@ -5,6 +5,8 @@ require 'net/ftp'
5
5
  require 'net/smtp'
6
6
  require 'fileutils'
7
7
  require 'uuidtools'
8
+ require 'thread'
9
+ require $workingdir + '/ftp_fetcher.rb'
8
10
 
9
11
  class Logger
10
12
  #Change the logging format to include a timestamp
@@ -32,7 +34,7 @@ module EchiConverter
32
34
  end
33
35
  begin
34
36
  ActiveRecord::Base.establish_connection(YAML::load(File.open(databaseconfig)))
35
- @log.info "Successfully connected to the database"
37
+ @log.info "Initialized the database"
36
38
  rescue => err
37
39
  @log.fatal "Could not connect to the database - " + err
38
40
  send_email_alert "DATABASE"
@@ -97,6 +99,70 @@ module EchiConverter
97
99
  return directory_month
98
100
  end
99
101
 
102
+ #Method to get FTP files
103
+ def get_ftp_files
104
+ filelist_fetcher = FtpFetcher.new
105
+ filequeue = filelist_fetcher.fetch_list @log
106
+
107
+ if filequeue == nil
108
+ return -1
109
+ end
110
+
111
+ if $config["max_ftp_sessions"] > 1 && filequeue.length > 4
112
+ if $config["max_ftp_sessions"] > filequeue.length
113
+ @log.info "Using " + filequeue.length.to_s + " ftp sessions to fetch files"
114
+ my_threads = []
115
+ cnt = 0
116
+ while cnt < filequeue.length
117
+ my_threads << Thread.new do
118
+ fetcher = Fetcher.new
119
+ result = fetcher.fetch_ftp_files filequeue, @log
120
+ end
121
+ cnt += 1
122
+ end
123
+ my_threads.each { |aThread| aThread.join }
124
+ else
125
+ @log.info "Using " + $config["max_ftp_sessions"].to_s + " ftp sessions to fetch files"
126
+ my_threads = []
127
+ cnt = 0
128
+ while cnt < $config["max_ftp_sessions"]
129
+ my_threads << Thread.new do
130
+ fetcher = FtpFetcher.new
131
+ result = fetcher.fetch_ftp_files filequeue, @log
132
+ end
133
+ cnt += 1
134
+ end
135
+ my_threads.each { |aThread| aThread.join }
136
+ end
137
+ else
138
+ @log.info "Using a single ftp session to fetch the files"
139
+ fetcher = FtpFetcher.new
140
+ result = fetcher.fetch_ftp_files filequeue, @log
141
+ end
142
+ if result == false
143
+ send_email_alert "FTP"
144
+ end
145
+ end
146
+
147
+ #Method to write to the log table
148
+ def log_processed_file type, filedata
149
+ begin
150
+ echi_log = EchiLog.new
151
+ echi_log.filename = filedata["name"]
152
+ if type == 'BINARY'
153
+ echi_log.filenumber = filedata["number"]
154
+ echi_log.version = filedata["version"]
155
+ end
156
+ echi_log.records = filedata["cnt"]
157
+ echi_log.processedat = Time.now
158
+ echi_log.save
159
+ rescue => err
160
+ @log.info "Error creating ECHI_LOG entry - " + err
161
+ return -1
162
+ end
163
+ return 0
164
+ end
165
+
100
166
  #Method for parsing the various datatypes from the ECH file
101
167
  def dump_binary type, length
102
168
  case type
@@ -149,288 +215,233 @@ module EchiConverter
149
215
  @log.debug "File_number " + filenumber.to_s
150
216
  fileversion = dump_binary 'int', 4
151
217
  @log.debug "Version " + fileversion.to_s
152
-
153
- if $config["echi_process_log"] == "Y"
154
- #Log the file
155
- begin
156
- echi_log = EchiLog.new
157
- echi_log.filename = filename
158
- echi_log.filenumber = filenumber
159
- echi_log.version = fileversion
160
- rescue => err
161
- @log.info "Error creating ECHI_LOG entry - " + err
162
- end
163
- end
164
218
 
165
- #Perform a transaction for each file, including the log table
166
- #in order to commit as one atomic action upon success
167
- EchiRecord.transaction do
168
- bool_cnt = 0
169
- @record_cnt = 0
170
- while @binary_file.eof == FALSE do
171
- @log.debug '<====================START RECORD ' + @record_cnt.to_s + ' ====================>'
172
- echi_record = EchiRecord.new
173
- @echi_schema["fields"].each do | field |
174
- #We handle the 'boolean' fields differently, as they are all encoded as bits in a single 8-bit byte
175
- if field["type"] == 'bool'
176
- if bool_cnt == 0
177
- bytearray = dump_binary field["type"], field["length"]
178
- end
179
- #Ensure we parse the bytearray and set the appropriate flags
180
- #We need to make sure the entire array is not nil, in order to do Y/N
181
- #if Nil we then set all no
182
- if bytearray != nil
183
- if bytearray.slice(bool_cnt,1) == 1
184
- value = 'Y'
185
- else
219
+ begin
220
+ #Perform a transaction for each file, including the log table
221
+ #in order to commit as one atomic action upon success
222
+ EchiRecord.transaction do
223
+ bool_cnt = 0
224
+ @record_cnt = 0
225
+ while @binary_file.eof == FALSE do
226
+ @log.debug '<====================START RECORD ' + @record_cnt.to_s + ' ====================>'
227
+ echi_record = EchiRecord.new
228
+ @echi_schema["echi_records"].each do | field |
229
+ #We handle the 'boolean' fields differently, as they are all encoded as bits in a single 8-bit byte
230
+ if field["type"] == 'bool'
231
+ if bool_cnt == 0
232
+ bytearray = dump_binary field["type"], field["length"]
233
+ end
234
+ #Ensure we parse the bytearray and set the appropriate flags
235
+ #We need to make sure the entire array is not nil, in order to do Y/N
236
+ #if Nil we then set all no
237
+ if bytearray != nil
238
+ if bytearray.slice(bool_cnt,1) == 1
239
+ value = 'Y'
240
+ else
241
+ value = 'N'
242
+ end
243
+ else
186
244
  value = 'N'
187
245
  end
188
- else
189
- value = 'N'
190
- end
191
- bool_cnt += 1
192
- if bool_cnt == 8
193
- bool_cnt = 0
246
+ bool_cnt += 1
247
+ if bool_cnt == 8
248
+ bool_cnt = 0
249
+ end
250
+ else
251
+ #Process 'standard' fields
252
+ value = dump_binary field["type"], field["length"]
253
+ @log.debug field["name"] + " { type => #{field["type"]} & length => #{field["length"]} } value => " + value.to_s
194
254
  end
195
- else
196
- #Process 'standard' fields
197
- value = dump_binary field["type"], field["length"]
198
- @log.debug field["name"] + " { type => #{field["type"]} & length => #{field["length"]} } value => " + value.to_s
255
+ echi_record[field["name"]] = value
199
256
  end
200
- echi_record[field["name"]] = value
201
- end
202
- echi_record.save
257
+ echi_record.save
203
258
 
204
- #Scan past the end of line record
205
- @binary_file.read(1)
206
- @log.debug '<====================STOP RECORD ' + @record_cnt.to_s + ' ====================>'
207
- @record_cnt += 1
259
+ #Scan past the end of line record
260
+ @binary_file.read(1)
261
+ @log.debug '<====================STOP RECORD ' + @record_cnt.to_s + ' ====================>'
262
+ @record_cnt += 1
263
+ end
264
+ @binary_file.close
208
265
  end
209
- @binary_file.close
266
+ rescue => err
267
+ @log.info "Error processing ECHI file - " + err
210
268
  end
211
-
269
+
212
270
  #Move the file to the processed directory
213
271
  FileUtils.mv(echi_file, @processeddirectory)
214
272
 
215
273
  if $config["echi_process_log"] == "Y"
216
- #Finish logging the details on the file
217
- begin
218
- echi_log.records = @record_cnt
219
- echi_log.processedat = Time.now
220
- echi_log.save
221
- rescue => err
222
- @log.info "Error inserting ECHI_LOG entry - " + err
223
- end
274
+ log_processed_file "BINARY", { "name" => filename, "number" => filenumber, "version" => fileversion, "cnt" => @record_cnt }
224
275
  end
225
276
 
226
277
  return @record_cnt
227
278
  end
228
-
229
- def connect_ftpsession
230
- #Open ftp connection
231
- begin
232
- if $config["echi_connect_type"] == 'ftp'
233
- ftp_session = Net::FTP.new($config["echi_host"])
234
- ftp_session.login $config["echi_username"], $config["echi_password"]
235
- @log.info "Successfully connected to the ECHI FTP server"
236
- else
237
- #Stub for possible SSH support in the future
238
- #session = Net::SSH.start(config["echi_host"], config["echi_port"], config["echi_username"], config["echi_password"])
239
- @log.fatal "SSH currently not supported, please use FTP for accessing the ECHI server"
240
- exit
241
- end
242
- rescue => err
243
- @log.fatal "Could not connect with the FTP server - " + err
244
- send_email_alert "FTP"
245
- return -1
246
- end
247
- return ftp_session
248
- end
249
-
250
- #Connect to the ftp server and fetch the files each time
251
- def fetch_ftp_files
252
- attempts = 0
253
- ftp_session = -1
254
- while ftp_session == -1 do
255
- ftp_session = connect_ftpsession
256
- if ftp_session == -1
257
- sleep 5
258
- end
259
- attempts += 1
260
- if $config["echi_ftp_retry"] == attempts
261
- ftp_session = 0
262
- end
263
- end
264
- if ftp_session != 0
265
- begin
266
- if $config["echi_ftp_directory"] != nil
267
- ftp_session.chdir($config["echi_ftp_directory"])
268
- end
269
- files = ftp_session.list('chr*')
270
-
271
- #Also fetch the agname.dat file if it is configured to be processed
272
- if $config["echi_update_agent_data"] == "Y"
273
- files = files + ftp_session.list("agname.dat")
274
- end
275
-
276
- file_cnt = 0
277
- files.each do | file |
278
- file_data = file.split(' ')
279
-
280
- local_filename = $workingdir + '/../files/to_process/' + file_data[8]
281
- ftp_session.getbinaryfile(file_data[8], local_filename)
282
- if $config["echi_ftp_delete"] == 'Y'
283
- begin
284
- ftp_session.delete(file_data[8])
285
- rescue => err
286
- @log.fatal err
287
- end
288
- end
289
- file_cnt += 1
290
- end
291
- ftp_session.close
292
- rescue => err
293
- @log.fatal "Could not fetch from ftp server - " + err
294
- end
295
- end
296
- return
297
- end
298
279
 
299
280
  def process_ascii filename
300
281
  echi_file = $workingdir + "/../files/to_process/" + filename
301
282
 
302
- if $config["echi_process_log"] == "Y"
303
- #Log the file
304
- begin
305
- echi_log = EchiLog.new
306
- echi_log.filename = filename
307
- #echi_log.filenumber = filenumber
308
- #echi_log.version = fileversion
309
- rescue => err
310
- @log.info "Error creating ECHI_LOG entry - " + err
311
- end
312
- end
313
-
314
- #Perform a transaction for each file, including the log table
315
- #in order to commit as one atomic action upon success
316
- EchiRecord.transaction do
317
- @record_cnt = 0
318
- FasterCSV.foreach(echi_file) do |row|
319
- if row != nil
320
- @log.debug '<====================START RECORD ' + @record_cnt.to_s + ' ====================>'
321
- echi_record = EchiRecord.new
322
- cnt = 0
323
- @echi_schema["fields"].each do | field |
324
- if field["type"] == "bool" || field["type"] == "bool_int"
325
- case row[cnt]
326
- when "0"
327
- echi_record[field["name"]] = "N"
328
- when "1"
329
- echi_record[field["name"]] = "Y"
330
- end
331
- @log.debug field["name"] + ' == ' + row[cnt]
332
- else
333
- echi_record[field["name"]] = row[cnt]
334
- if row[cnt] != nil
283
+ begin
284
+ #Perform a transaction for each file, including the log table
285
+ #in order to commit as one atomic action upon success
286
+ EchiRecord.transaction do
287
+ @record_cnt = 0
288
+ FasterCSV.foreach(echi_file) do |row|
289
+ if row != nil
290
+ @log.debug '<====================START RECORD ' + @record_cnt.to_s + ' ====================>'
291
+ echi_record = EchiRecord.new
292
+ cnt = 0
293
+ @echi_schema["echi_records"].each do | field |
294
+ if field["type"] == "bool" || field["type"] == "bool_int"
295
+ case row[cnt]
296
+ when "0"
297
+ echi_record[field["name"]] = "N"
298
+ when "1"
299
+ echi_record[field["name"]] = "Y"
300
+ end
335
301
  @log.debug field["name"] + ' == ' + row[cnt]
302
+ else
303
+ echi_record[field["name"]] = row[cnt]
304
+ if row[cnt] != nil
305
+ @log.debug field["name"] + ' == ' + row[cnt]
306
+ end
336
307
  end
308
+ cnt += 1
337
309
  end
338
- cnt += 1
310
+ echi_record.save
311
+ @log.debug '<====================STOP RECORD ' + @record_cnt.to_s + ' ====================>'
312
+ @record_cnt += 1
339
313
  end
340
- echi_record.save
341
- @log.debug '<====================STOP RECORD ' + @record_cnt.to_s + ' ====================>'
342
- @record_cnt += 1
343
314
  end
344
315
  end
316
+ rescue => err
317
+ @log.info "Error processing ECHI file - " + err
345
318
  end
346
319
 
347
320
  #Move the file to the processed directory
348
321
  FileUtils.mv(echi_file, @processeddirectory)
349
322
 
350
323
  if $config["echi_process_log"] == "Y"
351
- #Finish logging the details on the file
352
- begin
353
- echi_log.records = @record_cnt
354
- echi_log.processedat = Time.now
355
- echi_log.save
356
- rescue => err
357
- @log.info "Error inserting ECHI_LOG entry - " + err
358
- end
324
+ log_processed_file nil, { "name" => filename, "cnt" => @record_cnt }
359
325
  end
360
326
 
361
327
  return @record_cnt
362
328
  end
363
329
 
364
- def insert_agent_data field
330
+ def insert_dat_data tablename, row
365
331
 
366
332
  begin
367
- echi_agent = EchiAgent.new
368
- echi_agent.group_id = field[0]
369
- echi_agent.login_id = field[1]
370
- echi_agent.name = field[2]
371
- echi_agent.save
333
+ case tablename
334
+ when "echi_agents"
335
+ echi_dat_record = EchiAgent.new
336
+ when "echi_aux_reasons"
337
+ echi_dat_record = EchiAuxReason.new
338
+ when "echi_cwcs"
339
+ echi_dat_record = EchiCwc.new
340
+ when "echi_vdns"
341
+ echi_dat_record = EchiVdn.new
342
+ end
343
+ cnt = 0
344
+ @echi_schema[tablename].each do | field |
345
+ echi_dat_record[field["name"]] = row[cnt]
346
+ cnt += 1
347
+ end
348
+ echi_dat_record.save
372
349
  rescue => err
373
- @log.info "Unable to insert agent record - " + err
350
+ @log.info "Unable to insert " + tablename + " file record - " + err
374
351
  end
375
352
 
376
353
  end
377
354
 
378
- #Method to insert data into 'echi_agents' based on agname.dat
379
- def process_agent_data
380
- agent_file = $workingdir + "/../files/to_process/agname.dat"
381
-
382
- if File.exists?(agent_file)
383
- EchiAgent.transaction do
384
- @record_cnt = 0
385
- File.open(agent_file).each do |row|
386
- if row != nil
387
- field = row.rstrip.split('|')
388
- @log.debug '<====================START AGENT RECORD ' + @record_cnt.to_s + ' ====================>'
389
- agent = EchiAgent.find(:first, :conditions => [ "login_id = ? AND group_id = ?", field[1], field[0]])
390
- if agent != nil
391
- if agent.name != field[2]
392
- agent.name = field[2]
393
- agent.update
394
- @record_cnt += 1
395
- @log.debug "Updated record - " + field.inspect
396
- else
397
- @log.debug "No update required for - " + field.inspect
398
- end
399
- else
400
- insert_agent_data field
401
- @record_cnt += 1
402
- @log.debug "Inserted new record - " + field.inspect
403
- end
404
- end
405
- @log.debug '<====================STOP AGENT RECORD ' + @record_cnt.to_s + ' ====================>'
406
- end
355
+ #Process the appropriate table name
356
+ def process_proper_table file
357
+ @record_cnt = 0
358
+ process_file = File.open(file["filename"])
359
+ process_file.each do |row|
360
+ if row != nil
361
+ field = row.rstrip.split('|')
362
+ @log.debug '<====================START ' + file["name"] + ' RECORD ' + @record_cnt.to_s + ' ====================>'
363
+ case file["name"]
364
+ when "echi_agents"
365
+ record = EchiAgent.find(:first, :conditions => [ "login_id = ? AND group_id = ?", field[1], field[0]])
366
+ when "echi_aux_reasons"
367
+ record = EchiAuxReason.find(:first, :conditions => [ "aux_reason = ? AND group_id = ?", field[1], field[0]])
368
+ when "echi_cwcs"
369
+ record = EchiCwc.find(:first, :conditions => [ "cwc = ? AND group_id = ?", field[1], field[0]])
370
+ when "echi_vdns"
371
+ record = EchiVdn.find(:first, :conditions => [ "vdn = ? AND group_id = ?", field[1], field[0]])
407
372
  end
408
- @agent_file_processed = Time.now
409
- #Move the file to the processed directory
410
- begin
411
- agname_new_filename = "agname_" + UUID.timestamp_create.to_s + ".dat"
412
- target_file = @processeddirectory + "/" + agname_new_filename
413
- FileUtils.mv(agent_file, target_file)
414
- rescue => err
415
- @log.info "Issue with agname_*.dat filename - " + err
373
+ if record != nil
374
+ if record.name != field[2]
375
+ record.name = field[2]
376
+ record.update
377
+ @record_cnt += 1
378
+ @log.debug "Updated record - " + field.inspect
379
+ else
380
+ @log.debug "No update required for - " + field.inspect
381
+ end
382
+ else
383
+ insert_dat_data file["name"], field
384
+ @record_cnt += 1
385
+ @log.debug "Inserted new record - " + field.inspect
416
386
  end
417
- if $config["echi_process_log"] == "Y"
418
- #Log the file
419
- begin
420
- echi_log = EchiLog.new
421
- echi_log.filename = agname_new_filename
422
- #echi_log.filenumber = filenumber
423
- #echi_log.version = fileversion
424
- #Finish logging the details on the file
425
- echi_log.records = @record_cnt
426
- echi_log.processedat = Time.now
427
- echi_log.save
428
- rescue => err
429
- @log.info "Error creating ECHI_LOGS entry - " + err
387
+ end
388
+ @log.debug '<====================STOP ' + file["name"] + ' RECORD ' + @record_cnt.to_s + ' ====================>'
389
+ end
390
+ process_file.close
391
+
392
+ case file["name"]
393
+ when "echi_agents"
394
+ filename_elements = $config["echi_agent_dat"].split(".")
395
+ when "echi_aux_reasons"
396
+ filename_elements = $config["echi_aux_rsn_dat"].split(".")
397
+ when "echi_cwcs"
398
+ filename_elements = $config["echi_cwc_dat"].split(".")
399
+ when "echi_vdns"
400
+ filename_elements = $config["echi_vdn_dat"].split(".")
401
+ end
402
+ new_filename = filename_elements[0] + "_" + UUID.timestamp_create.to_s + "." + filename_elements[1]
403
+ target_file = @processeddirectory + "/" + new_filename
404
+ begin
405
+ FileUtils.mv(file["filename"], target_file)
406
+ if $config["echi_process_log"] == "Y"
407
+ log_processed_file nil, { "name" => new_filename, "cnt" => @record_cnt }
408
+ end
409
+ rescue => err
410
+ @log.info "Unable to move processed file - " + err
411
+ end
412
+ end
413
+
414
+ #Method to insert data into 'echi_agents' based on agname.dat
415
+ def process_dat_files
416
+ dat_files = Array.new
417
+ dat_files[0] = { "name" => "echi_agents", "filename" => $workingdir + "/../files/to_process/" + $config["echi_agent_dat"] }
418
+ dat_files[1] = { "name" => "echi_aux_reasons", "filename" => $workingdir + "/../files/to_process/" + $config["echi_aux_rsn_dat"] }
419
+ dat_files[2] = { "name" =>"echi_cwcs", "filename" => $workingdir + "/../files/to_process/" + $config["echi_cwc_dat"] }
420
+ dat_files[3] = { "name" =>"echi_vdns", "filename" => $workingdir + "/../files/to_process/" + $config["echi_vdn_dat"] }
421
+
422
+ dat_files.each do |file|
423
+ if File.exists?(file["filename"])
424
+ case file["name"]
425
+ when "echi_agents"
426
+ EchiAgent.transaction do
427
+ process_proper_table file
428
+ end
429
+ when "echi_aux_reasons"
430
+ EchiAuxReason.transaction do
431
+ process_proper_table file
432
+ end
433
+ when "echi_cwcs"
434
+ EchiCwc.transaction do
435
+ process_proper_table file
436
+ end
437
+ when "echi_vdns"
438
+ EchiVdn.transaction do
439
+ process_proper_table file
430
440
  end
431
441
  end
432
442
  end
433
443
  end
444
+ end
434
445
 
435
446
  require $workingdir + '/echi-converter/version.rb'
436
447
  end