Sunday, February 11, 2018

The Pragmatic Programmer - Review

The Pragmatic Programmer - from journeyman to master
By Andrew Hunt and David Thomas
Review By: Subhash Dike


Why are you here? Well, for now, it’s not a spiritual question as to why we all are ‘here’ (which should be a constant question in your mind anyways). Right now, the question is why you are here in this field of Software Development.


Are you here only because of the financial stability & better life this field has to offer? Or, are you here because you truly love what you do? If your answer is the latter, then this short article is for you. Not that there is something wrong with the former objective, in fact it’s always an important factor to be considered. But with that objective, this book would not relate a lot to you.


The Pragmatic Programmer by Andrew Hunt and David Thomas is a must-read book for everyone who love what they do and want to get better at it every single day. This book does not get you a fancy certification title, neither does get you quick tips about a certain technology to put on your resume. Rather it helps you set up a right mindset, helps you pay attention to what you do and then guides you with the way to make it better. In short, this book helps you become a better programmer. Even though, the title of the book says “programmer” it’s for everyone that’s in this field i.e. developers, testers and even managers.


Through a series of “tips”, the authors take you through this process of transformations. When I started reading this book first time, about 6 years before, the very first tip itself caught my attention. “Care About Your Craft”, it said. Imagine you are looking at any artist, say A. R. Rehman or Lata Mangeshkar (Indian Music Industry Masters) doing their daily “riyaaz” (practice). What you would see? You would see an individual focused on what they are doing, being their own self critic and correcting themselves unless they achieve perfection by their own set standards. You would see this going on day after day and for hours in a row. Why does that happen? Because they care for their craft. The authors of this book give most emphasis on this aspect, you must care for your craft. Once you get into role of craftsman and you really want to produce the greatest craft ever, you would not need any external factors to get best at it.


And this is just the beginning, authors then take us through all of software developer’s daily problems and provide us a way to approach those with a pragmatic mindset. What is a pragmatic programmer anyways? This book defines it nicely as someone who thinks beyond the immediate problem, always trying to think about bigger picture, one who takes full responsibility of his/her own work.


The beauty of this book is that it’s written by programmers after having themselves gone through all of the day to day problems faced by programmers. So, it doesn’t just offer a typical management advice, but serious practical tips and tools to help solve problems. Like me, I am pretty sure you would stop at many places and think that yes, this is how exactly it happens. My favorite tip in this book is “Don’t Program by Coincidence”. It happened to me so many times that there is a bug, and somebody says they fixed it, but when asked what was the problem, the answer you would get is, not sure, but it’s fixed. This is programming by co-incidence in real life. Unless you know what the problem was, and under which circumstances it appeared, how would you guarantee that it would not come back. Another important thing you would notice that the language of the book is so simple that you would feel someone is taking you throughout all of the tips. And that too with humor and fun. And yes, there is code, challenges and exercises to keep you engaged. It introduces you to variety of tools as a starting point with regards to some of the tips.
You may be thinking in your mind that you know what, all of that sounds good in theory but doesn’t work in practice. When my boss/client is shouting at me, none of that helps. I don’t blame you, that’s how most of us are used to think about most of the books and advices out there. But as I said in the beginning, if you really love what you would do, you would automatically get into the habits suggested by the book.


With that, I will leave you with the few of the tips this book has to offer to get you a taste of this (You can get the full list here - TIPS ). Just by reading these tips (which are explained in greater details in the book), you would see how this is different than any other programming book you have ever read.


Do read the book and share your views with me.

  • Care About Your Craft
    • Why spend your life developing software unless you care about doing it well?
  • Provide Options, Don’t Make Lame Excuses
    • Instead of excuses, provide options. Don’t say it can’t be done; explain what can be done.
  • Be a Catalyst for Change
    • You can’t force change on people. Instead, show them how the future might be and help them participate in creating it.
  • Critically Analyze What You Read and Hear
    • Don’t be swayed by vendors, media hype, or dogma. Analyze information in terms of you and your project.
  • Don’t Panic When Debugging
    • Take a deep breath and THINK! about what could be causing the bug.
  • Don’t Think Outside the Box—Find the Box
    • When faced with an impossible problem, identify the real constraints. Ask yourself: “Does it have to be done this way? Does it have to be done at all?”
  • English is Just a Programming Language
    • Write documents as you would write code: honor the DRY principle, use metadata, MVC, automatic generation, and so on.
  • Invest Regularly in Your Knowledge Portfolio
    • Make learning a habit.
  • Fix the Problem, Not the Blame
    • It doesn’t really matter whether the bug is your fault or someone else’s—it is still your problem, and it still needs to be fixed.
  • Don’t Program by Coincidence
    • Rely only on reliable things. Beware of accidental complexity, and don’t confuse a happy coincidence with a purposeful plan
  • Sign Your Work
    • Craftsmen of an earlier age were proud to sign their work. You should be, too.



Pragmatic Programmer
By Andrew Hunt and Dave Thomas
Pearson
Amazon US
Amazon India

Saturday, November 5, 2016

Resolved - SVN Authentication error on Windows 10


Lately I got my windows 10 updates and after that to my surprise, the SVN stopped working for some reason. Everything else was looking good on the server, I was able to see the URL contents fine in the browser, but anytime I used Tortoise SVN it was failing. I thought it could be related to tortoise svn's incompatibility in Windows 10, so I downloaded command line svn, but still the same error is also seen as below.

svn: E170013: Unable to connect to a repository at URL - YOUR URL
svn: E120190: Error running context: An error occurred during authentication

This was happening for a laptop which is not connected to the main domain and the network where the SVN resides. Looking at wireshark responses, I could see that there is an HTTP 403 error from server, but unable to understand why the client is not able to pass on the appropriate credentials. After long hours of searching finally came across a solution, through a Google Group conversation. Apparently this seems to be happening due to this Windows 10 update. As you can see there are several options suggested there, but the the solution which worked for me was to run below command in command prompt

runas /netonly /user:domain\username cmd

Enter the password for domain\username:

This basically opens another command prompt but this time with the context of that domain user. (Note - The machine does not have to be part of the domain or network where svn is running).

Once the new command prompt opens, you should be able to run command line commands to checkout etc.

Friday, October 14, 2016

Resolved - HTTPS with HttpWebRequest results in exception "An existing connection was forcibly closed by the remote host"


So you are all set to call an external URL to grab some data. You setup your code with something like this
private string GetServiceData()
        {
            string serviceResponse = string.Empty;
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(YOUR_HTTPS_URL);
            var response = request.GetResponse() as HttpWebResponse;

            using (Stream receiveStream = response.GetResponseStream())
            {
                StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
                serviceResponse = readStream.ReadToEnd();
            }
            return serviceResponse;
        }


And then you run this code expecting everything to work fine. Unfortunately you meet with the last thing you expected i.e. an exception as below

[SocketException (0x2746): An existing connection was forcibly closed by the remote host]
   System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) +106
   System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) +130

[IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.]
   System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) +291
   System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count) +32
   System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) +156
   System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) +59
   System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) +49
   System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) +162
   System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) +523
   System.Net.TlsStream.CallProcessAuthentication(Object state) +42
   System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) +193
   System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) +21
   System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) +64
   System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result) +795
   System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size) +52
   System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size) +21
   System.Net.ConnectStream.WriteHeaders(Boolean async) +388


At this point if you are looking for one line answer, scroll down, copy the last piece of code and use it! :).. OR continue reading further for some details

What's going on here. Looking at the code, you figure out that you had never seen this even when you used HttpWebRequest earlier, most likely the method is also being reused from somewhere it worked. Quickly you find out, that the only delta here is the requested url being HTTPS and not HTTP. Off course, you validate first that the https end point in question is accessible and it indeed is.

The error in the stack trace indicates that the connection was attempted but was denied. You have figured this out already, that it has something to do with https. And yes you are right, this is most likely because of HTTPS.

So what's exactly happening here. To understand that, we need to understand how exactly client and server process HTTPS request. There are a good number of articles and videos on this, so you can read in details but the one I referred to is here and one of the specifications is here . In a nutshell, it is actually a multi-step process which happens behind the scene, not seen by the consumer, whether you are using browser or a client library. Most of the exchanges between client and server are one/first time exchanges which is sort of negotiated contract between a law firm and it's client, where both parties are laying down basic rules of how they would take forward the interactions.

In this case, first step is called HandShake (again lot of articles on this specific topic), and in the handshake client begins by sending a hello message with variety of parameters such as ProtocolVersion, CipherSuite, SessionID etc. With this message, client is basically saying I am ready to talk to you but these are a few constraints and properties which I am capable of supporting. Now when this reaches to the server, server has to agree on what it's going to support and then accept this request by sending a response back. If, for any reason, server does not accept any of the parameters being provided, then it results into failure from server and ends up closing the connection since the communication can't continue without agreed parameters by both the parties. As you may have noticed, one of such parameters is ProtocolVersion which refers to SSL/TLS protocol version. Server has to agree on what version of SSL/TLS it wants to support. Generally browsers/clients present a range that they can support, and server can decide the highest which it wants to work with.

Back to our problem, if you see the error says that "existing connection was forcibly closed by the remote host" which means client started a connection which was established, and during this handshake procedure server denied to work with this client and hence closed connection from server side. Now we have to find out, if there is a difference. To do that, you would need to identify which TLS version server is looking for and which one client is supporting. Let's start with the client. To find out which SSL/TLS version one client is using, run your code with a break point just before the HttpWebRequest creation. Once you are on the breakpoint, open the immediate window, and look for the value of ServicePointManager.SecurityProtocol, which may show something like this.

ServicePointManager.SecurityProtocol
Ssl3 | Tls

This means the client in question is capable of work with server supporting any of these two versions i.e SSL3, Tls (which happens to be the Default for .Net framework). Now let's find out now what version server is supporting. And if they mismatch, there is our problem. To find out version that server supports is little tricky. You can find through browser (using these various ways) or through OpenSSL command line. I tried opening my website in question in IE and then right click into empty space and look at properties, and there I found "TLS 1.1, AES with 256 bit encryption (High); DH with 1024 bit exchange". (Why I say tricky because, as you might have read by now in specifications that the server will agree on the highest possible TLS version, so the one shown in browser is not necessarily the only one it supports, it is probably the highest one).

Now as you can see, the client is supporting only SSL3 and Tls where but the server seems to expect TLS1.1 and above. There we take to our solution as below. The good part here is that though you don't know the minimum, you can still specify the range and make the server happy

private string GetServiceData()
        {
            string serviceResponse = string.Empty;            
            ServicePointManager.SecurityProtocol = ServicePointManager.SecurityProtocol | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(YOUR_HTTPS_URL);
            var response = request.GetResponse() as HttpWebResponse;

            using (Stream receiveStream = response.GetResponseStream())
            {
                StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
                serviceResponse = readStream.ReadToEnd();
            }
            return serviceResponse;
        }


There you are, you should now be able to run your code and see that the server is happy to respond with the response.

I hope you liked this article, feel free to leave a comment if you have any suggestions/thoughts or facing the problem and I would be happy to help.

Saturday, September 19, 2015

Unit Testing with NDBUnit and Identity Column

NDBUnit offers a great way to test your database related functionalities. While performing automated unit testing with databases, libraries like NDBUnit are very handy and they do an amazing job.

If you would like to learn more about them and get started, do visit their GitHub page here - https://github.com/NDbUnit/NDbUnit


In this article, I am specifically talking about a common use case where we need to test the database functionality for a table having identity set to true. In that case, you will need to turn it on in your setup method like this

INDbUnitTest dbUnitTest = new NDbUnit.Core.SqlClient.SqlDbUnitTest(connectionString);
_mySqlDatabase.ReadXmlSchema(TestUtil.ESMSDBXsd.GetCompletePath());
dbUnitTest.PerformDbOperation(DbOperationFlag.InsertIdentity);
In my case, even after doing this, it wasn't inserting identity and was always inserting -1 in the primary key column. After doing a lot of research, I realized that I had to explicitly set it up once again in the XSD as well. If you open your XSD in visual studio, locate the particular table and hit F4 (i.e. go to properties window), you should see all of the properties of that field. We are mainly interested in AutoIncrementSeed And AutoIncrementStep properties which should be set to same value as that of your database (typically 1). Ideally this value should get set automatically when you generate XSD, but it appears that in one of my table that wasn't happening which caused me to spend some time to get around this and finally found the solution as mentioned above.