So I created the Database batching code that I spoke about recently and the way I went about doing it was to create the unit tests first.  And then get the code to work.   My goal from the beginning was 100% code coverage of all my unit tests.  So using NCover and NUnit and NMock I was able to achieve that.  Then when I replaced the existing database access code with my new code.   ALL the preexisting DB access unit tests passed (we have some unit tests that work with the database) in one try!  WOOOTT!!!  And at the same time a coworker of mine changed some of his code, didn’t even run the existing unit tests and checked his code in and he broke the build for 5 hrs.  I had to wait that 5 hours before I could check my code in.

Here are my unit tests, the class in question that I am testing is the database executor class (called Database in this version). If you are interested in seeing the DB execution implementation post here and I’ll put it up in my next post. (I’d like to see if people are actually interested in this series of articles :) )

[TestFixture]
public class DatabaseAccessingTestFixture
{
    private List myConnectionStrings;
    [SetUp]
    protected virtual void SetUp()
    {
        myConnectionStrings = new List();
        myConnectionStrings.Add("Blah!");

    }

    [Test]
    public void SingletonAccessShouldReturnDatabaseObject()
    {
        Single.Instance = null;
        Assert.IsInstanceOfType(typeof(Database), Database.Instance);
    }

    [Test]
    public void ExecuteSingleCommandShouldOpenANewConnectionAndExecuteTheCommand()
    {
        Mockery mocks = new Mockery();
        IDbCommand cmd = mocks.NewMock();
        IDbConnection con = mocks.NewMock();
        IDataReader rdr = mocks.NewMock();

        Database db = new Database();
        int workCalled = 0;
        DataReaderConsumer work = delegate(IDataReader reader) { workCalled++;
                                                                   reader.Read(); };
        Expect.Once.On(con).GetProperty("State").Will(Return.Value(ConnectionState.Closed));
        Expect.Once.On(con).Method("Open");
        Expect.Once.On(cmd).Method("ExecuteReader").WithNoArguments().Will(Return.Value(rdr));
        Expect.Once.On(rdr).Method("Close");
        Expect.Once.On(cmd).SetProperty("Connection");
        Expect.Once.On(con).Method("Dispose");
        Expect.Once.On(rdr).Method("Read").Will(Return.Value(true));

        using (CreatorScope scope = new CreatorScope(delegate { return con;}))
        {
            db.ExecuteSingleCommand(cmd, work, myConnectionStrings, IsolationLevel.ReadCommitted, null);
        }
        Assert.IsTrue(workCalled==1);
        mocks.VerifyAllExpectationsHaveBeenMet();
    }

    [Test]
    public void ExecutingABatchShouldInvokeWork2Times()
    {
        Mockery mocks = new Mockery();
        IDbCommand cmd = mocks.NewMock();
        IDbConnection con = mocks.NewMock();
        IDataReader rdr = mocks.NewMock();

        Database db = new Database();
        int workCalled = 0;
        DataReaderConsumer work = delegate(IDataReader reader)
        {
            workCalled++;
            reader.Read();
        };

        using (mocks.Ordered)
        {
            Expect.Exactly(1).On(con).GetProperty("State").Will(Return.Value(ConnectionState.Closed));
            //Open connection once.
            Expect.Once.On(con).Method("Open");
            Expect.Exactly(1).On(cmd).SetProperty("Connection");
            //ExecuteReader for every "singlecommand" in the batch
            Expect.Exactly(1).On(cmd).Method("ExecuteReader").WithNoArguments().Will(Return.Value(rdr));
            Expect.Exactly(1).On(rdr).Method("Read").Will(Return.Value(true));
            //Close reader when done
            Expect.Exactly(1).On(rdr).Method("Close");
            Expect.Exactly(1).On(con).GetProperty("State").Will(Return.Value(ConnectionState.Open));
            Expect.Exactly(1).On(cmd).SetProperty("Connection");
            //ExecuteReader for every "singlecommand" in the batch
            Expect.Exactly(1).On(cmd).Method("ExecuteReader").WithNoArguments().Will(Return.Value(rdr));
            Expect.Exactly(1).On(rdr).Method("Read").Will(Return.Value(true));
            //Close reader when done
            Expect.Exactly(1).On(rdr).Method("Close");
            Expect.Once.On(con).Method("Dispose");
        }
        using (CreatorScope scope = new CreatorScope(delegate { return con; }))
        {
            db.Execute(IsolationLevel.ReadCommitted, null, myConnectionStrings,
                       delegate
                           {
                               db.ExecuteSingleCommand(cmd, work, myConnectionStrings, IsolationLevel.ReadCommitted, null);
                               db.ExecuteSingleCommand(cmd, work, myConnectionStrings, IsolationLevel.ReadCommitted, null);
                           });
        }
        Assert.IsTrue(workCalled == 2);
        mocks.VerifyAllExpectationsHaveBeenMet();

    }

    [Test]
    [ExpectedException(typeof(OurException))]
    public void AttemptingABatchWithIsolationOfNoneShouldThrowOurException()
    {

        Database db = new Database();
        db.Execute(IsolationLevel.None, null, myConnectionStrings, null);
    }

    [Test]
    [ExpectedException(typeof (OurException))]
    public void AttemptingABatchWithNullWorkParameterShouldThrowOurException()
    {
        Database db = new Database();

        db.Execute(IsolationLevel.ReadCommitted, null, myConnectionStrings, null);
    }

    [Test]
    public void IfStatementRequiresNewTransactionDuringABatchWeShouldThrowOurException()
    {
        Mockery mocks = new Mockery();
        IDbCommand cmd = mocks.NewMock();
        IDbConnection con = mocks.NewMock();
        IDataReader rdr = mocks.NewMock();

        Database db = new Database();
        int workCalled = 0;
        DataReaderConsumer work = delegate(IDataReader reader)
        {
            workCalled++;
            reader.Read();
        };

        using (mocks.Ordered)
        {
            Expect.Exactly(1).On(con).GetProperty("State").Will(Return.Value(ConnectionState.Closed));
            //Open connection once.
            Expect.Once.On(con).Method("Open");
            Expect.Exactly(1).On(cmd).SetProperty("Connection");
            //ExecuteReader for every "singlecommand" in the batch
            Expect.Exactly(1).On(cmd).Method("ExecuteReader").WithNoArguments().Will(Return.Value(rdr));
            Expect.Exactly(1).On(rdr).Method("Read").Will(Return.Value(true));
            //Close reader when done
            Expect.Exactly(1).On(rdr).Method("Close");
            //clean up connection on the way out.
            Expect.Once.On(con).Method("Dispose");
        }
        bool caughtException = false;
        try
        {
            using (CreatorScope scope = new CreatorScope(delegate { return con; }))
            {
                db.Execute(IsolationLevel.ReadCommitted, null, myConnectionStrings,
                           delegate
                               {
                                   db.ExecuteSingleCommand(cmd, work, myConnectionStrings, IsolationLevel.ReadCommitted, null);
                                   db.ExecuteSingleCommand(cmd, work, myConnectionStrings, IsolationLevel.ReadCommitted, null);
                               });
            }
        }
        catch (OurException e)
        {
            caughtException = true;
        }
        Assert.IsTrue(caughtException);
        mocks.VerifyAllExpectationsHaveBeenMet();
    }

    [Test]
    public void IfStatementHasIncompatibleIsolationTypeDuringABatchWeShouldThrowOurException()
    {
        Mockery mocks = new Mockery();
        IDbCommand cmd = mocks.NewMock();
        IDbConnection con = mocks.NewMock();
        IDataReader rdr = mocks.NewMock();

        Database db = new Database();
        int workCalled = 0;
        DataReaderConsumer work = delegate(IDataReader reader)
        {
            workCalled++;
            reader.Read();
        };

        using (mocks.Ordered)
        {
            Expect.Exactly(1).On(con).GetProperty("State").Will(Return.Value(ConnectionState.Closed));
            //Open connection once.
            Expect.Once.On(con).Method("Open");
            Expect.Exactly(1).On(cmd).SetProperty("Connection");
            //ExecuteReader for every "singlecommand" in the batch
            Expect.Exactly(1).On(cmd).Method("ExecuteReader").WithNoArguments().Will(Return.Value(rdr));
            Expect.Exactly(1).On(rdr).Method("Read").Will(Return.Value(true));
            //Close reader when done
            Expect.Exactly(1).On(rdr).Method("Close");
            //clean up connection on the way out.
            Expect.Once.On(con).Method("Dispose");
        }
        bool caughtException = false;
        try
        {
            using (CreatorScope scope = new CreatorScope(delegate { return con; }))
            {
                db.Execute(IsolationLevel.ReadCommitted, null, myConnectionStrings,
                           delegate
                           {
                               db.ExecuteSingleCommand(cmd, work, myConnectionStrings,IsolationLevel.ReadCommitted, null);
                               db.ExecuteSingleCommand(cmd, work, myConnectionStrings,IsolationLevel.Snapshot, null);
                           });
            }
        }
        catch (OurException e)
        {
            caughtException = true;
        }
        Assert.IsTrue(caughtException);
        mocks.VerifyAllExpectationsHaveBeenMet();
    }

    [Test]
    public void ExecuteSingleCommandWithSnapshotIsolationShouldExecuteUnderSnapshotIsolation()
    {
        Mockery mocks = new Mockery();
        IDbCommand cmd = mocks.NewMock();
        IDbConnection con = mocks.NewMock();
        IDataReader rdr = mocks.NewMock();

        Database db = new Database();
        int workCalled = 0;
        DataReaderConsumer work = delegate(IDataReader reader)
        {
            workCalled++;
            reader.Read();
        };

        Expect.Exactly(1).On(con).GetProperty("State").Will(Return.Value(ConnectionState.Closed));
        Expect.Once.On(con).Method("Open");
        Expect.Once.On(cmd).Method("ExecuteReader").WithNoArguments().Will(Return.Value(rdr));
        Expect.Once.On(rdr).Method("Close");
        Expect.Once.On(cmd).SetProperty("Connection");
        Expect.Once.On(con).Method("Dispose");
        Expect.Once.On(rdr).Method("Read").Will(Return.Value(true));

        using (CreatorScope scope = new CreatorScope(delegate { return con; }))
        {
            db.ExecuteSingleCommand(cmd, work, myConnectionStrings, IsolationLevel.Snapshot, new TimeSpan(20000));
        }
        Assert.IsTrue(workCalled == 1);
        mocks.VerifyAllExpectationsHaveBeenMet();
    }

    [Test]
    public void StatementFailsIfMirroringServerFailsOverwithSQLAndTransactionException()
    {
        Mockery mocks = new Mockery();
        IDbCommand cmd = mocks.NewMock();
        IDbConnection con = mocks.NewMock();
        IDataReader rdr = mocks.NewMock();

        Database db = new Database(2, 50);
        int workCalled = 0;
        DataReaderConsumer work = delegate(IDataReader reader)
        {
            workCalled++;
            reader.Read();
        };

        using (mocks.Ordered)
        {
            Expect.Exactly(1).On(con).GetProperty("State").Will(Return.Value(ConnectionState.Closed));
            //Open connection once.
            Expect.Once.On(con).Method("Open");
            Expect.Exactly(1).On(cmd).SetProperty("Connection");
            //retry command for each retry.
            Expect.Exactly(1).On(cmd).Method("ExecuteReader").WithNoArguments().Will(
                Throw.Exception(SqlExceptionCreator.CreateSqlException("Blah", 8506,20)));

            Expect.Exactly(1).On(con).GetProperty("State").Will(Return.Value(ConnectionState.Closed));
            Expect.Once.On(con).Method("Open");
            Expect.Exactly(1).On(cmd).SetProperty("Connection");
            //retry command for each retry.
            Expect.Exactly(1).On(cmd).Method("ExecuteReader").WithNoArguments().Will(
                Throw.Exception(new TransactionInDoubtException("Transaction ambiguous")));

            Expect.Exactly(1).On(con).GetProperty("State").Will(Return.Value(ConnectionState.Closed));
            Expect.Once.On(con).Method("Open");
            Expect.Exactly(1).On(cmd).SetProperty("Connection");
            //retry command for each retry.
            Expect.Exactly(1).On(cmd).Method("ExecuteReader").WithNoArguments().Will(
                Throw.Exception(SqlExceptionCreator.CreateSqlException("Blah", 8506,20)));
            Expect.Once.On(con).Method("Dispose");
        }
        bool exceptionThrown = false;
        try
        {
            using (CreatorScope scope = new CreatorScope(delegate { return con; }))
            {
                db.ExecuteSingleCommand(cmd, work, myConnectionStrings, IsolationLevel.ReadCommitted, null);
            }
        }
        catch (OurException e)
        {
            Assert.AreEqual(8506, ((SqlException)e.InnerException).Number);
            exceptionThrown = true;
        }
        Assert.IsTrue(exceptionThrown);
        Assert.IsTrue(workCalled == 0);
        mocks.VerifyAllExpectationsHaveBeenMet();
    }

    [Test]
    public void StatementShouldThrowExceptionIfExecuteReaderThrowsExceptionWithErrorClassLessThan20()
    {
        Mockery mocks = new Mockery();
        IDbCommand cmd = mocks.NewMock();
        IDbConnection con = mocks.NewMock();
        IDataReader rdr = mocks.NewMock();

        Database db = new Database(2, 50);
        int workCalled = 0;
        DataReaderConsumer work = delegate(IDataReader reader)
        {
            workCalled++;
            reader.Read();
        };

        using (mocks.Ordered)
        {
            Expect.Exactly(1).On(con).GetProperty("State").Will(Return.Value(ConnectionState.Closed));
            //Open connection once.
            Expect.Once.On(con).Method("Open");
            Expect.Exactly(1).On(cmd).SetProperty("Connection");
            //retry command for each retry.
            Expect.Exactly(1).On(cmd).Method("ExecuteReader").WithNoArguments().Will(
                Throw.Exception(SqlExceptionCreator.CreateSqlException("Blah", 22, 10)));
            Expect.Once.On(con).Method("Dispose");
        }
        bool exceptionThrown = false;
        try
        {
            using (CreatorScope scope = new CreatorScope(delegate { return con; }))
            {
                db.ExecuteSingleCommand(cmd, work, myConnectionStrings,IsolationLevel.ReadCommitted, null);
            }
        }
        catch (OurException e)
        {
            Assert.AreEqual(22, ((SqlException)e.InnerException).Number);
            exceptionThrown = true;
        }
        Assert.IsTrue(exceptionThrown);
        Assert.IsTrue(workCalled == 0);
        mocks.VerifyAllExpectationsHaveBeenMet();
    }

    [Test]
    public void SingleStatementShouldSucceedOnDualRailFailover()
    {
        Mockery mocks = new Mockery();
        IDbCommand cmd = mocks.NewMock();
        IDbConnection con = mocks.NewMock();
        IDataReader rdr = mocks.NewMock();

        Database db = new Database(2, 50);
        int workCalled = 0;
        DataReaderConsumer work = delegate(IDataReader reader)
        {
            workCalled++;
            reader.Read();
        };

        myConnectionStrings.Add("dualRail");

        using (mocks.Ordered)
        {
            Expect.Exactly(1).On(con).GetProperty("State").Will(Return.Value(ConnectionState.Closed));
            //Open connection once.
            Expect.Once.On(con).Method("Open");
            Expect.Exactly(1).On(cmd).SetProperty("Connection");
            //retry command for each retry.
            Expect.Exactly(1).On(cmd).Method("ExecuteReader").WithNoArguments().Will(
                Throw.Exception(SqlExceptionCreator.CreateSqlException("Blah", 8506, 20)));

            Expect.Exactly(1).On(con).GetProperty("State").Will(Return.Value(ConnectionState.Closed));
            Expect.Once.On(con).Method("Open");
            Expect.Exactly(1).On(cmd).SetProperty("Connection");
            //retry command for each retry.
            Expect.Exactly(1).On(cmd).Method("ExecuteReader").WithNoArguments().Will(
                Throw.Exception(SqlExceptionCreator.CreateSqlException("Blah", 8506, 20)));

            Expect.Exactly(1).On(con).GetProperty("State").Will(Return.Value(ConnectionState.Closed));
            Expect.Once.On(con).Method("Open");
            Expect.Exactly(1).On(cmd).SetProperty("Connection");
            //retry command for each retry.
            Expect.Exactly(1).On(cmd).Method("ExecuteReader").WithNoArguments().Will(
                Throw.Exception(SqlExceptionCreator.CreateSqlException("Blah", 8506, 20)));
            Expect.Once.On(con).Method("Dispose");

            Expect.Exactly(1).On(con).GetProperty("State").Will(Return.Value(ConnectionState.Closed));
            //Open connection once.
            Expect.Once.On(con).Method("Open");
            Expect.Exactly(1).On(cmd).SetProperty("Connection");
            //retry command for each retry.
            Expect.Exactly(1).On(cmd).Method("ExecuteReader").WithNoArguments().Will(Return.Value(rdr));
            Expect.Once.On(rdr).Method("Read").Will(Return.Value(true));
            Expect.Once.On(rdr).Method("Close");
            Expect.Once.On(con).Method("Dispose");
        }
        bool exceptionThrown = false;
        try
        {
            using (CreatorScope scope = new CreatorScope(delegate { return con; }))
            {
                db.ExecuteSingleCommand(cmd, work, myConnectionStrings, IsolationLevel.ReadCommitted, null);
            }
        }
        catch (OurException e)
        {
            Assert.AreEqual(8506, ((SqlException)e.InnerException).Number);
            exceptionThrown = true;
        }
        Assert.IsFalse(exceptionThrown);
        Assert.IsTrue(workCalled == 1);
        mocks.VerifyAllExpectationsHaveBeenMet();
    }
}

So it’s been a while since I posted about the “cool problem” … Largely it has to do with time.  However before I present the solution let me talk a little more about what we are doing.

Each time we execute a stored procedure from within our data access code we do it under it’s own transaction (if a transaction is needed).  Here are some examples of what we do:

UserProxy uProx = new UserProxy(connectionstrings);
uProx.UpdateUser(userInformation);
uProx.LookupUser(userinformation, delegate (IDataReader) {  /*do datareader stuff */});

Each of these statements executes under it’s own connection logic to the database.    What we would like to do is be able to wrap these connections under a transaction.  We could use a TransactionScope:

using (TransactionScope scope = new TransactionScope(options))
{
   //Do our database stuff
}

This is all fine and good but there are a few caveats.  Most of the time we use the transaction scope around our code we end up using the DTC. (and in our case we are hitting the same DB so we’d like to avoid that if possible).  Our code starts to become cluttered with Using transactionScope statements, And if we have to extend (which we do in this case) the access to the database to include error handling logic due to mirroring failovers then we’d have to affect every piece of code that accesses the database in a transaction scope to handle an Exception, and then retry the sequence of statements within the scope, once we’ve determined that the failure is of the type that a failover retry might succeed.Enter our particular solution.

Using the concept of a batch we realized that an anonymous delegate could represent the work we needed to do and then we could submit that delegate to our Command execution engine and it could handle the retries due to errors.  Since we wanted to use the same engine for single statements as well as batches we had to figure that into the equation.  So now our usage model looks something like this:

DatabaseExecutor.Execute(IsolationLevel.Snapshot,connectionstrings, delegate (){ UserProxy.CreateUser(info); UserProxy.UpdateUser(info); UserProxy.ReadInfo(info, delegate(IDataReader reader) {/*read the data*/})});

The next post will share the unit tests and code for the DatabaseExecutor.

So I’ve been thinking a lot lately about other operating systems (I’m running Vista and XP at home) it seems that XP over the last few years has been requiring MORE and MORE pc resources.  (must be all the security updates) AND Vista is just a resource pig in general.  So I took a pc that I have and installed Etch (a debian version of Linux).  Man it was super easy.  And it runs like a top on the pc whereas with XP it was gasping along. 

What next?  well I’m thinking of hosting my own blog on that computer.  (this blog is great and all but it’s not as customizeable as I would like). 

Now the question is what blog software should I run :)  

I hope the screen writers get the resolution that they are looking for.   I fully support your striking! (as long at the celtics and patriots are still on tv :) )

GO PATS!

I wanna give a shout out to my good friend Jay.  I’ve known him since 3rd grade.

 Have a great day my friend!

Got my first ever flu shot today.  My arm is a little sore… Here’s hoping it works!

Also did you notice in my last post that I managed to figure out how to incorporate source code into a post?

the keyword is sourcecode  with a space then language=”csharp”  then surround the whole thing with square brackets.

As I mentioned previously, we have an ORM layer on the project I am working on.  In this layer we have a DatabaseProxy for each table in our database.  So for example, if I have a User table, I have a UserProxy object that is responsible for basic (and more advanced) operations, such as Create, Read, Update, and Delete. 

Here is a snippet for how the UserProxy works to create a user:

public int Create(User user)
{
    int result;
    using (SqlCommand cmd = new SqlCommand("usp_userCreate"))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add(new SqlParameter("username", user.userName));
        cmd.Parameters.Add(new SqlParameter("email", user.email));
        cmd.Parameters.Add(new SqlParameter("password", user.password));
        cmd.Parameters.Add(new SqlParameter("salt", user.salt));
        SqlParameter userIdParam = new SqlParameter();
        userIdParam.ParameterName = "userId";
        userIdParam.Direction = ParameterDirection.Output;
        userIdParam.SqlDbType = SqlDbType.Int;
        cmd.Parameters.Add(userIdParam);
        DatabaseExecutor.Instance.ExecuteSingleCommand(cmd, null, ConnectionStrings,
            IsolationLevel.None, null);
        result = (int)userIdParam.Value;
        user.userId = result;
    }
}

the User object is just a lightweight data structure.
The DatabaseExecutor static instance is essentially an encapsulation of the mirroring/dual rail logic (and it supports batching too) and it executes the command with the supplied isolation levels.

Next on the UserProxy we have a a Read statement. Essentially you hand in a delegate (DataReaderConsumer) that takes an IDataReader as an interface.

public void FindAllUsers(DataReaderConsumer consumer)
{
    using(SqlCommand cmd = new SqlCommand("usp_userFindAll"))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        DatabaseExecutor.Instance.ExecuteSingleCommand(cmd, consumer,
                ConnectionStrings, IsolationLevel.None, null);
    }
}

The call to FindAll looks like this:

List users = new List();
userProxy.FindAllUsers(
delegate(IDataReader reader)
   {
     while (reader.Read())
     {
         User newUser = new User();
         newUser.userId = (int) reader["userid"];
         newUser.userName = (string) reader["username"];
         users.Add(newUser);
     }
});return users;

As an aside the objects that use the Proxies represent an interface into the database access components. So we have an IUserAccessor interface that also has something to a findAllUsers method and returns this list. The purpose of this was to supply an Interface to developers that didn’t have to touch any Database specific code (we also thought we might be sharing this code to other groups within the company).

So that’s roughly how our data access layer works. The IUserAccessor (which admittedly I glossed over here) is also the point at which we can separate the system from the database (for unit testing).

Anyway, next post I’ll get into the DatabaseExecutor and batch operations.

I don’t know about you but whenever I have to enter my SSN or Credit card into a website, I get downright paranoid and use tools like Fiddler to ensure that the sight is secure.  So just this morning I went to my benefits website for my FSA (flexible spending account) so that I could re-enroll for next year and I realized that I left the password at home (in an encrypted repository).  So I clicked the link titled “click here to get your login password if you forgot it” (or something like that).

The following window popped open:

Retrieve your password

Notice the URL just below the title bar.  It’s http  not Https!  I used fiddler to confirm that the page was indeed transmitting everything in clear text!   (for those that don’t know Fiddler is essentially a traffic sniffer that looks at HTTP)

So I called the company and let them know that they were compromizing people’s SSNs!

rrrr. 

The benefits company manages FSA and 401K benefits.  How freaky is that!?

So you know that cool problem I mentioned the other day.  Well before I present you with the complete solution I actually have to build up to it.  First off let me start off by saying that just like most Object oriented applications that use a database, ours has an ORM layer (ORM= Object to Relational Mapping).  Needless to say we rolled our own OR mapping, because at the time we felt we may not need a heavy weight one and didn’t have the time to analyze all the ORM frameworks out there.  Essentially we are using delegates to pass into our database execution engine.  The delegate uses IDataReader to read all the data out, because it’s a delegate the engine invokes the delegate AND gets to wrap it up in try catch logic to clean up should an exception occur.

http://www.pluralsight.com/blogs/keith/archive/2007/04/11/46711.aspx over at Pluralsight they call it enveloped abstractions.   Our code is similar to what they showing at this blog. 

This use of delegates is extremely cool, however it makes it a little difficult to support transactions and nested transactions (across multiple objects).  Also when you throw mirroring into the equation then dual rail support (2 connection strings) things start getting a little hairy.  So tomorrow I’ll be sharing some information about what I did to solve the problem

I’ve never given a ton of thought to Veteran’s Day, other than to say thanks to all the veterans that have served our country.  But with Iraq so firmly entrenched in our lives I can’t help but think a lot MORE about the men and women who serve our country in the armed forces.  

I first off want to say a heartfelt thanks to them for risking their lives for the freedoms that we enjoy in our country.  If it was not for you (past and present) we would not be here today.

I also wonder if I should be apologizing for the way our leaders run this country.  It’s them who decide to put our military into action and then when it’s time to come home our leaders make it difficult for lots of veterans to reassimilate back into society.

Regardless, I hope that Iraq ends soon and you all can come home safe and hail. 

« Previous PageNext Page »