AiS 41: Scrum Doesn’t Suck
Friday, March 28th, 2008Agile is Relative by Scott Ambler.
The Agile Manifesto.
Scrum on Wikipedia.
Archive for March, 2008AiS 41: Scrum Doesn’t SuckFriday, March 28th, 2008Agile is Relative by Scott Ambler. The WordPress plot thickensThursday, March 27th, 2008I've upgraded WordPress and I'm working on putting things back to normal. In the process, I've discovered a few more side effects of the hack. It appears that the hacker uploaded a new header.php and footer.php to my active theme. I only noticed this because I had changed the theme and placed some important markup in the header. Without this markup, the page doesn't render correctly. If you are viewing this site on the evening of the 27th, you might just well be seeing the old theme while I work on fixing the new one. The footer was modified to include hidden links to various link farm pages on a health and fitness podcast. The header was modified to include only one link, this to a blog run by someone by the name of Erik Kastner. I won't give you the links because ... well ... that's the point. I've posted a comments on these blogs asking for help in figuring out this connection. I'll let you know the response. Update So thanks, Erik. Let's hope that I get a quick response from the health and fitness podcast. Forensic analysis of WordPress version changeThursday, March 27th, 2008It happened again. The db_version was reset to 1 this morning, causing the error message "Your database is out-of-date". My forensic analysis turned up nothing. Whatever caused this also had the effect of disabling the Spam Karma plugin, so all of the comments posted thereafter were sitting in moderation. This gave me a good timestamp for the occurrence. Since the version change disables the spam filter, I suspected an attack. Perhaps someone takes advantage of a WordPress bug to turn off the filter and then post a bunch of comment spam. So I checked the server log for any suspicious entries around the time of the earliest comment in moderation. The earliest comment was at 22:56 GMT. My server is located in the -400 time zone, so I scanned the access log for 18:56. I can see a "POST /blog/wp-comments-post.php" at that time, so that is the first comment post with the spam filter turned off. Scrolling back to the previous post at 18:43, I have my window. The version change and disabling of Spam Karma occurred somewhere in there. At 18:45, there are several POSTs to various suspicious URLs.
Unfortunately, I cannot see the body of the HTTP POST from the access log, so I don't know exactly what was done. But it appears that someone used these entry points to change some options and upload a file called "ro8kfbsmag.txt". Googling this filename, I found that it is indeed an attack. It looks like this vulnerability has been fixed. So the solution is to upgrade to the latest version of WordPress. I know what I'll be doing tonight! Cheap Zyrtec Your database is out-of-dateMonday, March 24th, 2008For some reason, WordPress started throwing the error "Your database is out-of-date. Please upgrade." whenever I visited the admin console. I had not upgraded either the code or the database prior to getting this error. I have no clue what caused it. So naturally, I Googled the error message and found many other people with the same problem. Some of these people received replies to their cries for help. The replies included such helpful tidbits as "so upgrade, already", to "reboot the server". Naturally, I tried them and none worked for me. Since WordPress is written in PHP, the source code is entirely in the clear. This makes it possible for a typical software blogger like myself to debug the application and figure out what's wrong. I used PuTTY to log into my server and peruse the code and database to see what could be done. I thought this would make for gripping television, so I did it all while streaming. Here's my solution If you grep for the error message, you will find a comparison between get_option('db_version') and $wp_db_version. Further grepping will reveal that $wp_db_version is set in wp-includes/version.php and that get_option selects option_value from the wp_options table. Log into mysql and select * from wp_options where option_name='db_version' and you will find the culprit. This solution is not for the weak of heart. If you are not familiar with mysql, please take some time to get comfortable with it before messing around with your own blog. You run the risk of seriously messing things up, especially if you forget your where clause! If you are not familiar with PHP, however, not to worry. This fix does not require any changes to the WordPress PHP code. In fact, this exercise is a great way to learn. So if you found this post by Googling your error message, watch the video clip, get your PuTTY ready, and fix it! BTW, how did the value get changed? Not a clue. If it happens again, I'll investigate further. And I'll stream the process! Update Controls .NET released under LGPLTuesday, March 18th, 2008I have released Update Controls .NET as an open source project. Update Controls is a set of .NET Windows Forms controls that update themselves automatically. Instead of setting properties, you handle events. For example, the GetText event fires on an UpdateTextBox when it needs to update itself. The event returns the text string to display. Then, when any data that was used to calculate that string changes, the event fires again. Automatically. Think of how you use a spreadsheet. You enter a formula in a cell, with references to other cells. When those other cells change, the formula is recalculated. You don't have to tell it to update, it just figures out when to do so. I created the algorithm at the core of Update Controls almost ten years ago in C++. Since then, I've translated it first into Delphi, then Java, and finally C#. The Update Controls library is that core algorithm applied to the common Windows Forms controls. It also includes a handful of themed controls for better visual appeal. Not data binding But Update Controls is completely flexible. You can start with a simple event that returns one value, but then modify it to combine two or more values as your needs change. Since you are writing real code, you are in complete control. A data-bound control attaches directly to a column in the database, or a property of an object in the data model. It cannot call through more complex business logic. But an Update Control can call any business logic that you specify. Whatever data the business logic touches in order to do its work, that data affects the control's behavior. When any of it changes, the event fires and calls the business logic again. Not the observer pattern Update Controls, on the other hand, discovers those dependencies on its own. It can see through business logic, so you don't have to directly tie your user interface to your data model. And if that business logic switches to a new path, the dependencies are updated as well. The observer pattern also suffers from cascading redundant updates. If your observer depends upon two subjects and both are changed at the same time, the observer pattern will give you two updates. The problem gets even worse when you have indirect dependencies, as the redundancy rolls through the system like so many dominoes. But Update Controls queues the updates until the last possible moment, so they occur only once. Even indirect dependencies are calculated in the best possible order, with each update being invoked just once as the information bubbles to the surface. Please give it a try Once you write a Winforms app with Update Controls, you'll never want to code without them. Selecting an open source licenseSunday, March 16th, 2008I'm starting an open source project (details on which later this week). Part of the process is selecting a license. This is a library, so the intent is for it to be used by and within another application. In fact, this library is well suited to use by other libraries. As such, I didn't want a viral license like GPL that would prevent some legitimate business uses of my code. A non-viral GPL To answer this concern, in 1991 the Free Software Foundation created the LGPL. Originally the "Library GPL", it was intended for reusable code. An application could link to the code without being infected by the GPL. The FSF revised the LGPL in 1999, changing its name to the "Lesser GPL". They also released the article "Why you shouldn't use the Lesser GPL for your next library". The article reads very much like a call to arms. It says that they are seeking more libraries to release under the original GPL. "[F]ree software developers need to make advantages for each other". This article, and the somewhat derogatory name change, make it clear that they would prefer that we don't use the LGPL. Nevertheless, the license does exactly what I need it to do. It grants licensees the right to copy, modify, and redistribute my code. It also grants them the right to license any derivative works however they see fit. Even though I am not a card-carrying member of the open source movement, I believe that this is the best model for this particular library. Inventing something oldFriday, March 14th, 2008I'm back from the joint application design sessions, and happy with the progress we made. But one discussion stands out as having taken longer than it should have. We got to the point of deciding how our systems would physically talk to each other. They have some data to send to us, and we have some data for them. The usual requirements apply: the data has to be validated, the channel has to be secure, the transport has to be reliable, and the process has to be auditable. Still it took an hour to work through the details. What we agreed upon was delivering XML files over SFTP. Standard features apply: one folder for incoming and one for outgoing, acknowledgement files, XML schema for validation, and exception reports emailed to a distribution list. In particular, we spent several minutes talking about what to do on days on which no data is exchanged. Do we send an empty file or no file at all? This seems familiar I don't mind that the solution we agreed upon uses older technology. Sure, web services or REST would have been more in vogue. But even with these newer standards, you have to agree upon a pattern of use. What was so frustrating is that this is a pattern, and yet the group spent an hour rediscovering it. If you install any ESB solution, it will include components out-of-the-box that implement this pattern. You just configure them with a polling frequency, a transport protocol, a schema, and an email address. No code required. The value of patterns is that you can work at a higher level of abstraction. All the details have been solved for you in advance. This saves time and improves communication. And, BTW, the correct answer is to send an empty file. We finally agreed upon that, and congratulated ourselves for our brilliance. Joint application designThursday, March 13th, 2008Despite all expectations, today was incredibly productive. I've been meeting with the other partners in this large integration project to try to reach some consensus. The grand-client has scheduled these "joint application design sessions". Sounds suspiciously like design-by-committee. Off to a bad start Because of a delayed flight, I missed yesterday's session and ended up in a project planning meeting (see yesterday's post). I heard from others present that there was not much content that pertained to us. Then I heard from the PM that we would be "observers" in the sessions for the next two days. That did not set the stage well. Nevertheless, I decided to go in and make the most of it. Being the BA, I had with me a nice long list of open issues. I'm keeping these issues in an Access database tagged by functional area so I could quickly query for the questions I needed to ask at each point. Since the business requirements are not yet complete, most of these were business questions. Unexpected progress After closing many of my open issues, and assigning a few more to various people as action items, we were able to settle into more technical discussions. We agreed upon a high-level data interchange design and required data elements, with XML schemas to be provided within a week. We were not mere observers. We had answers that they needed, and they had answers that we needed. And this was not design-by-committee. Instead of a lukewarm mixture of everybody's ideas, we each identified our own unique place in the system. So don't underestimate the value of getting partners together. In just a few hours, you can accomplish what months worth of emails just can't get done. And even though design-by-committee yields mediocre results, integration of system requires some integration of teams. Visit with the grand-clientWednesday, March 12th, 2008I'm traveling again, but this time not for fun like the ODC. This is work. I'm traveling to represent one of SSG's clients to one of their clients. The "grand-client", if you will. SSG has asked that I don't blog company names, but you'd know them if I told you. A tale of two cultures My client, on the other hand, has been trying to define their process. Traditionally, they use RUP, but have had issues in the past with generating useful documentation from this process. They've evaluated agile, but could not get it to work within their corporate culture. Most recently, they've described their process as "agile RUP". I'm sure that such a combination could be achieved, but this seems more like a compromise than an actual plan. This is a large integration project. The grand-client has identified several partners that will work together to create a new product offering, my client being just one of them. The grand-client is running this project by tracking each of the partners with their own methodology. Instead of expecting deliverables from each provider at certain milestones, they are integrating the project plans. Project management tooling On the other hand, my client manages everything with Microsoft Project. Engineers enter time against milestones, not tasks. The project is manually updated at status meetings, not automatically based on the time entry system. The goal from the grand-client's point of view is to create a synergy of processes. They want to map all of the artifacts in the client's process into their own process. With that mapping, they can measure all partner's progress with their own tool, and identify each one's impact on other partner's schedules. This might be a brilliant way of managing a project of this scale. Or it might be a train-wreck in progress. Either way, I expect to learn quite a bit from this engagement. Raise the level of abstractionSunday, March 9th, 2008There's a long post by Jeff Moser entitled What Does It Take To Become A Grandmaster Developer? The post itself is interesting, but I'd like to call out one thing that I immediately reacted to.
I am all about raising the level of abstraction, so I thought he was calling me foolish. He seems to be saying that we cannot escape the details, even as we find the chunks that make them easier to remember. After calming down a bit, I realized that he was saying something much more intelligent. He's saying that it is not always possible to completely hide details behind an abstraction. Further, he's implying that it is not always desirable to do so. Two kinds of abstractions Examples of leaky abstractions are web application languages like JSP and ASP. These generate HTML for you. They are an abstraction over HTML that relates it to your application data model. But they do not completely hide HTML from you. In fact, both of these languages live inside what looks like an HTML file. Examples of complete abstractions are languages like C. It completely hides the underlying machine code. For an exceedingly large class of problems, you never have to write, look at, or think about machine code. At one point in history a knowledge of machine code was useful to C programming. But in this day, it's hard to argue that someone needs to have felt that pain in order to be a good C programmer. Because JSP and ASP are leaky abstractions, they can never be decoupled from HTML. But because C is a compete abstraction, it can be ported (with varying degrees of success) to other platforms. An exceedingly large class of problems To make a complete abstraction, you must first identify the class of problems that you intend to solve. All problems in this class can be solved using only the features of the abstraction. Problems outside this class will require features of the underlying idea. Necessary and sufficient Each of the features of the abstraction is necessary for solving at least one problem in the class. The sum of the features is sufficient for solving all problems in the class. This is also known as the Goldilocks principle. The abstraction is neither too big, nor too small. It's just right for the class of problems it solves. This is also known as composability and orthogonality. Each feature of the abstraction is orthogonal to the others because there is no combination of other features that can achieve the same effect. And the set of features can be composed to create a solution to any problem in the class. Benefits of a complete abstraction Not all abstractions demand this level of scrutiny and design, but those that do are often the most useful. They hide the details of the underlying idea for your own good. You never have to think about those details again. People new to the idea can focus on the abstraction and never even learn those details. And, those details can change without affecting artifacts created on top of the abstraction. |