Thursday, September 27, 2012

Presentation - Kanban Case Study

Here are slides on a Kanban Case Study that I presented at agileLUNCHBOX today.  I basically recapped my experience using Kanban at Hugsmiðjan (maker of Eplica CMS), and showed how our Kanban board evolved over time.  I went over basic Kanban theory and covered a few advanced topics like associated metrics.  I also talked about how we integrated Kanban and Scrum.  The talk was well received and afterwards we had some good agile discussions.  

Friday, September 14, 2012

Web Service Development - Best Practices

As a software developer I have had to deal with a fair amount of Web Services, both as the consumer and provider of services.  Below is a list of best practice guidelines that I have gradually assembled and try to follow when developing Web Services.  I also usually send this list to people that are writing Web Services that I am to consume.  I have found that it saves me considerable headache when it comes time to integrate with the service.  Most of my guidelines are written with XML over SOAP in mind, but some are common sense tips that should apply to other types of Web Services, like JSON over REST.

The Guidelines

  1. A Web Service should be defined with a WSDL (or WADL in case of REST) and all responses returned by the Web Service should comply with the advertised WSDL.
    1. This can for example be tested with tools like SoapUI (see my blog entry Web Service Testing with soapUI) or XMLSpy, which validate SOAP responses against a WSDL.
  2. Use XML Schema to define the input and output of your Web Service operations.
    1. Make sure to define return types for all returned data, preferably as XSD ComplexTypes.
    2. Do not use the AnyType tag, as it makes it impossible (or non-beneficial) to use XML binding libraries to auto-generate code to construct request/response objects.
    3. For ComplexTypes, make sure the occurrence indicators (minOccurs and maxOccurs) are correctly defined, so that it is clear to the consumer which fields are required and which are optional and the frequency of each field.
    4. Make sure your namespaces are well defined (not some default like "org.tempuri")
  3. Do not use a proprietary authentication protocol for your Web Service.  Rather use common standards like HttpAuth or Kerberos.  Or define username/password as part of your XML payload and expose your Web Service via SSL.
  4. Keep it simple  
    1. Write a Web Service with many simple methods rather than one large method (with numerous arguments) that tries to be everything to everyone.
    2. Adhere to the OO principles of maximizing cohesion and minimizing coupling when designing your Web Services.
  5. Make sure your Web Service returns error messages that are useful for debugging/tracking problems.  For example, include an error code and a human readable error description.
  6. Make sure to offer a development environment for your service, which preferably runs the same Web Service version as production, but off of a test database rather than production data.
  7. Thoroughly test your Web Service, in a technology-agnostic manner, before having others integrate with it.

Consequences of Breaking These Guidelines


Why all these rules?  Because I have found it to significantly increase development time for the consumer when they are broken.  Here are some of the offenders I frequently come across, and the resulting consequences:
  • Web Services that don't define a WSDL and are poorly documented.
    • This usually leaves the consumer shooting in the dark as to how to communicate with the service and what to expect as a response.  This results in a lot of trial-and-error and having to manually write code to marshall & unmarshall the XML data.
  • Web Services that define a WSDL but don't conform to it.
    • This can be extremely frustrating for the Web Service consumer who usually ends up getting some sort of a cryptic error message from his generated XML bindings code.  That leads to a lot of head scratching and eventually writing the XML marshalling code from scratch.  I would say this is a worse offense than not defining a WSDL at all. 
  • Web Services that are hidden behind some proprietary authentication protocol.  
    • A good example that comes to mind is the NTLM v2 protocol that IIS supports and is a proprietary Microsoft protocol.  Integrating with this protocol from other technologies than .Net is usually not straight forward.  Last time I had to do it from Java we ended up having to purchase a proprietary library to be able to authenticate against the service, as no reliable open source implementation existed (which took us way to long to discover).
  • Web Services that define poor or no error messages.
    • These are the type of services that blow up with some XML parsing error, showing a stack trace that is specific to the Web Service implementation technology.  They basically provide no useful feedback to the consumer about what may have gone wrong and whether the issue is on the client or server side.  Furthermore, it leaves no way for the consumer to gracefully handle the error by choosing actions based on error type.
  • Web Services that don't work unless consumed in the authoring technology.
    • I have often I had to consume Web Services that were incorrectly autogenerated by some tool/framework (Siebel and .Net come to mind), and really don't conform to Web Service standards.  I therefore urge developers to test their own service with soapUI, JMeter or other standalone Web Service clients, before they publish it to others. That way you also get to chew your own dog food, so to speak, meaning you see what the XML for your service looks like.
That's my two cents on the issue.  If you have more guidelines to share, or don't agree with mine, I'd love to hear from you.


Friday, August 31, 2012

Run Jenkins on Tomcat with SSL

At work I recently got the task of getting Jenkins up and running on Tomcat and set it up in such a way that requests were exclusively served via SSL. Since it took a bit of googling to get this done I decided to document the instructions should anyone need to do the same. Here they are:

  • Download and install the latest version of Tomcat.  
  • Download the latest Jenkins WAR file and extract it to [Tomcat home]/webapps/ROOT.
    • Note: this is assuming the only web application you will be running on Tomcat is Jenkins.  If you are planning to use Tomcat to run multiple web applications you will need to create server.xml host configurations for each one.
  • If you haven't already, download and install the latest version of Java
  • If you are not planning to run SSL, all you should have to do at this point is start Tomcat (via [Tomcat home]/bin/Tomcat7w.exe or the service menu on Windows, or [Tomcat home]/bin/startup.sh on Linux/Unix)
  • To get SSL working you will need an SSL certificate.  You can get an official certificate through Verisign or Thawty.  In this example we will be using a free self-signed certificate, generated with the keytool that comes with Java.
  • Run: [Java home]/bin/keytool genkey -alias tomcat -keyalg RSA -keystore [tomcat home]/.keystore -validity [desired number days the certificate should be valid for]
    E.g.: "C:\Program Files\Java\jdk1.7.0_05\bin\keytool" -genkey -alias tomcat -keyalg RSA -keystore C:\Tomcat\.keystore -validity 365
  • Provide a password for the keystore and answer questions about your organization.  When asked for key password just hit enter.  This should create one certificate in the keystore located at  C:\Tomcat\.keystore.
  • Edit [Tomcat home]/conf/server.xml and html-uncomment the following text:
  • <!--     <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
                   maxThreads="150" scheme="https" secure="true"
                   clientAuth="false" sslProtocol="TLS" />
    -->
  • Furthermore add to it the following two attributes:  keystoreFile="C:\Tomcat\.keystore" keystorePass="YourPassword"  (inputing values that match your setup) and change the port value to 443.
  • To redirect all http traffic to https change the line:
  • <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
    over to:
    <Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="443" />
  • That's it.  You should now be able to start Tomcat (seet bullet #4) and view Jenkins on http://localhost (which should autoredirect you to https://localhost) or use your actual hostname.

Sunday, June 17, 2012

Agile Tips from Remote Seminar with Henrik Kniberg

Last week Agile netið organized a remote seminar with Henrik Kniberg, award-winning keynote speaker and author of multiple Agile and Lean books.  The seminar was held at the Grand Hotel in Reykjavík, where around 10 Icelandic Agile enthusiasts gathered to remote connect to Henrik via Skype and Google Hangout.  We listened to Henrik talk about lessons learned at one of his recent projects and then had a long Q&A session, where we got to ask him all sorts of Agile and Lean related questions.  Despite an initial technical hiccup with poor sound quality the event was very enjoyable and informative.  Here are some of my take-aways. Basically random tips from the discussions that I found useful.
  • If you need to explain to someone the benefits of limiting work in progress when running Kanban, use a traffic jam analogy: When there are not that many cars on a given highway, everything runs smoothly and we have a lot of cars running through the highway. But as we add more cars on the highway, basically everything starts slowing down to a jam and we have fewer and fewer cars that are able to drive the highway to the end.  The same thing happens in Kanban if we don't put WIP limits on our queues. Starting more tasks actually causes us to end up finishing fewer.
  • If you ever need to sell to management the need to pay off a technical debt and refactor some legacy code: print out the longest class, tape the pages together and bring it with you to a meeting!  When you show up with a 5 meter long paper strip, showing some monstrosity of a class, people have an easier time visualizing the problem.
  • When running a Scrum team, think about establishing a rule that each team member that completes a user story needs to ask the team if he can help out with a story that is already in progress before he is allowed to start work on a new one.  That encourages cooperation and limits work in progress, increasing the likelihood that we have fully completed stories at the end of the sprint, as opposed to stories that are partially done.  If our sprint backlog is 10 stories we would much rather have 8 fully completed stories at the end of the sprint than 6 completed stories and 4 partially done.
  • According to Henrik, research has shown that incorporating QA into your agile development teams (testing continuously) saves on overall time spent in testing and bug fixing.  Meaning that if you test and bug fix as part of each sprint, as opposed to doing a large round of testing at the end of the project followed by a lot of bug fixes, you save time.  One reason for this is that when it comes time to fix a bug the code is still fresh in the developer's mind.  Also the continuous QA feedback encourages developers to deliver higher quality code.  This is visualized in the following illustration from Henrik's slides:
  • Size doesn't matter.  According to Henrik having the team categorize user stories into small, medium and large before implementation is not very useful.  At the end of his project he calculated actual times spent on user stories and found out that it actually took about the same time on average to implement a story that had been categorized as small as it took to implement a story that had been categorized as medium.
  • When you are on a large project that comprises multiple teams, try doing finger voting to assess the overall confidence that the project will get delivered on time.   Basically, in weekly meetings ask team leads to hold up fingers on one hand representing their confidence that their team will get the required work done on time.  Where 5 fingers mean "definitely", 4 fingers mean "likely", 3 fingers "it's a gray line", two fingers "probably not" and one finger means "no way".  Track this on a weekly basis.  If you get few fingers in the air, you know you have a problem that needs to be addressed.
  • Try to make your development teams cross functional.  Each team should comprise all the skills required to fully deliver a feature (e.g. graphics designer, front-end developer, back-end developer, DBA, tester).  If a resource is needed at least 50% of the time put him on the team.  Make sure everyone has a home team, even though they might be outsourced to other teams from time to time.
  • To check the health of a Scrum team use the Scrum check-list.

Tuesday, January 17, 2012

Ský Development Conference (Links in Icelandic)

Last week I had the pleasure of presenting at the annual Ský Development Conference (Hugbúnaðarrástefna Ský) in Reykjavík, Iceland.  This year's conference theme was "The Work Environment of Software Developers".   The conference offered presentations on the following topics: Programming Languages, Quality Assurance, Issue Tracking, User Interfaces, Project Management, Databases and Data Warehousing.  My presentation was under the Project Management topic, titled "Practical Tips for Software Development Leads".  In it I tried to provide some practical tips to team leads and software development managers.  Suggestions on such things as how to get the most out of your team, how to manage your time, how to use programming to help with your managerial duties, how to achieve continuous improvement and how to motivate developers.  The conference was all in Icleandic, so unfortunately so are the slides.  They are available on the conference web site and on Slideshare (mine).

I especially liked Ólafur Gauti Guðmundsson's presentation on the Play framework, which I have been playing with a bit and Stefán Baxter's presentation on NoSQL databases.  Margrét Dóra also had a great talk on user interfaces, reminding us that "stupid users" are really our own fault, a result of poor user interface design.  And Birna Íris Jónsdóttir had a good QA talk titled "It works on my machine!" where she took some shots at us programmers for all the lame excuses we provide when our stuff breaks! :)  All in all a fun day and an enjoyable conference.

Sunday, January 15, 2012

Quickly Launch Remote Desktop Connections on Mac OS X

At work and at home I have a few PC servers that I frequently need to remote connect to. My Mac launcher application of choice is Alfred. I wanted to be able to use it to instantly launch connections to those servers without needing to type in anything but the first few letters of the server name. Getting this setup on Mac OS X is a bit of a hassle, but here is basically what I do:
  • I use the Remote Desktop Connection Client for Mac to connect to the PC servers.
  • After installing the client and typing in the name of the server I want to connect to I go to preferences and customize the connection:
    • Under the Login tab I enter account information
    • Under the Display tab I specify my preferred remote desktop size
    • Sometimes I tweak some of the other settings, but those two are of main importance
  • Then I go to File and Save As... and save this connection as a .rdp file on my Mac
  • Now I can double-click on the file to be instantly connected to the remote server
  • Problem is that application launchers don't really know how to run .rdp files, so I want to take it a step further and create a runnable Mac Application for each .rdp file.  To do this I use an open source program called Platypus, that a coworker of mine told me about.  
  • Unfortunately Platypus does not know how to run .rdp files, but it does know how create Applications that launch shell scripts.  Hence, I create a simple shell script to launch my remote desktop connection.  E.g. if I want to launch SteiniServer.rdp, then my script would look like this:

    open "/Applications/Remote Desktop Connection.app" ~/Documents/RDC/SteiniServer.rdp

  • Then I save the script on my computer in a file called rdcSteiniServer.sh
  • Now I open Platypus and use it to create a Mac Application with the following settings:
(If you want to add a custom icon for your application you can right-click the image and choose Select Image File...)
        
The only thing that really matters is selecting Script Type Shell and the path to your script.
  • Then I hit Create and select:


  • Now I am ready to launch my remote connection with Alfred, which I do like this:
  • Basically, I activate Alfred (Ctrl-A for me) and as soon as I have typed in RDC it finds the RDC Steini Server Application and when I hit enter I am automatically logged into the remote PC server without having to type in anything else.

    If you have a simpler way of achieving the same I am eager to hear :-)