14 July 2010

A Hack solution Doesn't Mean Hacky Code

Today at work we ran into a little situation with a currently running process. The process is fine, but one of the parts of the business feeding data to our BizTalk orchestration needed a change. For whatever reason, the requirements for a file that gets sent through BizTalk had changed such that the file would be much, much bigger. The business unit responsible for that file said they couldn't supply the whole thing new every night (the current required process) because it would kill their other processes. What they proposed was to send one static file (old data that has to be sent every time) and then they would send the rest of the data (which changes) in the current daily process.

This left us with a bit of a quandary. Since the current Orchestration looks for two files (the one from this unit, and one from another) adding a new file would cause us to have to re-write the Orchestration (which would mean un-deploying it, then re-deploying it). This was a non-starter because this requirement should only be in place for a month or so, and then we'd have to go back to the old process.

So, the decision was made that we would take the static file, append the daily file to it each night, and then send it through the current process (now a single file) as normal.

I was tasked with creating the code that would do that. After a brief discussion with my team mates, it was decided we'd use a Console Application which would be called by the Windows Scheduler. We considered a Windows Service, but opted for the Console App because we can see the possible need to run it manually.

So, even though this is a hack process for a hack requirement, I decided that my code should be the highest possible standard- partially for personal and professional pride, and partially because no "temporary" requirement ever really goes away. So, with error checking removed (since that's a custom thing for my client), here are the basic guts. I, personally, think it's good, but please feel free to fire away with any problems you see...

   1:  public class FileMerge
   2:      {
   3:          public string StaticFilePath { get; set; }
   4:          public string DailyFilePath { get; set; }
   5:          public string MergedFilePath { get; private set; }
   6:          public string FinalFilePath { get; private set; }
   7:   
   8:          public FileMerge() { }
   9:          public FileMerge(string statFile, string dailyFile, string mergedFile, string finalFile)
  10:          {
  11:              StaticFilePath = statFile;
  12:              DailyFilePath = dailyFile;
  13:              MergedFilePath = mergedFile;
  14:              FinalFilePath = finalFile;
  15:          }
  16:   
  17:          public void MergeAndDrop()
  18:          {
  19:              FileInfo mergedFile = Merge();
  20:              if (mergedFile != null && mergedFile.Exists) Drop(mergedFile);
  21:          }
  22:   
  23:          private FileInfo Merge()
  24:          {
  25:              using (StreamWriter sw = new StreamWriter(MergedFilePath))
  26:              {
  27:                  if (File.Exists(MergedFilePath)) File.Delete(MergedFilePath);
  28:                  using(StreamReader staticReader = new StreamReader(StaticFilePath))
  29:                  {
  30:                      while (staticReader.Peek() != -1)
  31:                      {
  32:                          string line = staticReader.ReadLine();
  33:                          if (!string.IsNullOrEmpty(line.Trim())) sw.WriteLine(line);
  34:                      }
  35:                  }
  36:                  using (StreamReader dailyReader = new StreamReader(DailyFilePath))
  37:                  {
  38:                      while (dailyReader.Peek() != -1)
  39:                      {
  40:                          string line = dailyReader.ReadLine();
  41:                          if (!string.IsNullOrEmpty(line.Trim())) sw.WriteLine(line);
  42:                      }
  43:                  }
  44:              }
  45:              return new FileInfo(MergedFilePath);
  46:          }
  47:   
  48:          private void Drop(FileInfo fileToDrop)
  49:          {
  50:              fileToDrop.MoveTo(FinalFilePath);
  51:          }
  52:      }

No comments:

Post a Comment