echi-converter 0.3.3 → 0.3.4

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.
@@ -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