Monday, January 25, 2010

Cruisecontrol and default contexts

Any programmer knows about Cruisecontrol and more in general about the concepts of Continuous Integration. Or at least they should.

The latest release of Cruisecontrol opens up the Jetty configuration completely, which is awesome, since you get a free complete webserver with it, which can handle publushing of files on HTTP. Awesome.

There are some issues, sure. Like for an example the standard Cruisecontrol deployment (binary form) doesn't define any default contexts in the jetty configuration. Which means once you start Cruisecontr0l, you won't have a default homepage setup (by default).

Well, there is an easy fix for that.

First, in the Cruisecontrol home (for example C:\cruisecontrol) create a directory "contexts".

Second, follow this snippet (just highlight & copy):



<?xml version="1.0"
encoding="ISO-8859-1"?>

<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure class="org.mortbay.jetty.webapp.WebAppContext">
<Set name="contextPath"><Property name="foo"/></Set>

<Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/test</Set>
</Configure>



Restart your Cruisecontrol, open up a webbrowser and navigate to http://localhost:80 and voilá.

Tuesday, September 22, 2009

Some more thinking about the three concepts of programming

Consider the last of the three principles of programming:
Endurance recalls the fact that coding is not only "pressing a button to compile", but also making sure that thet code you have been writing works as it is supposed to.
Debugging is a tedious process. Basically, it consists in checking the functionality that has been added within the coding phase. The (stupid) machine is not able to go through it by itself AND at the same time evaluate the correctness of it. Sure enough, the activity can be automated through some testing code, but that again translates in (as the name says) more coding.
Now, without diving into the details of testing - how much of this process can we automate without writing any additional code?
Consider this situation : the perfect solution would be the machine itself knows what she has to test out of the box. That would mean the machine knows the behaviour of our software artifact already before it would had been written (possibly), which in turn would get you to think that hey, the machine could write that piece of functionality by itself! if it already knows the nature of the functionality, correct?
This already sounds hidious, doesn't it? You realize where it is heading, or? Exactly, it tastes alot like the good old "dog biting tail" paradox.

...and there came the day the Linux stood still.

Damn you Linux!
And it gets worser..
Damn you Ubuntu!
Half a day lost - for what? Don't know. I know what happened. A machine running Ubuntu 64 bit Server (that had worked fine for over 8 months) suddently stopped booting into gdm.
On login to any user, it woulds state "/dev/null no permissions". WTF?
See, this is exactly why linux (written with a lower case L on purpose, didn't deserve the capital one today!) sucks. When something goes wrong - it NEVER does, really, but when it happens - its almost a total disaster. Mainly for two reasons.
  1. The system usually is totally or partially unusable
  2. Finding out what happened takes half a time of your life
  3. 20 years of development and noone cared doing a proper, centralized log viewer interface - you know what, f*ck you.
Well the third reason came out of my hearth, just had to log it. Sorry dudes.
So what happened? Apparently, some "obscure" thing mixed up the /lib/lbs/init-functions file, which ended up being empty. This in turn caused the (all) services to exit with log_daemon_msg messages, causing services who invoked them to think they failed.
Which translates in a clean boot in the most proper way, as in no services started. Not even ifconfig for configuring the network interfaces for an example.

Well, luckily that "obscure" thing was kind enough to take a backup of the init-functions before erasing the contents. Which btw excludes Hard Disk crashes (and shuts the mouth to all of you I-know-better out there) who are not even as half as nice to make a backup before taking action.
Once restored, the system seems to work fine (so far).
But what caused that problem? No one knows, not even Google....

Monday, September 7, 2009

Three basic foundation principles of programming

Making software (aka "programming") comprises itself of three separate principles:

a) Writing
b) Logic
c) Endurance

Writing is specifically important from the understandability point of view. Complicated code written in a complicated way doesn't really help the reader to understand it better.

Logic is, well, the basics of informatics in general, your morning star. Whichever problem you want to solve, logic is the way to do it (and mathematics).

Endurance recalls the fact that coding is not only "pressing a button to compile", but also making sure that thet code you have been writing works as it is supposed to.
This last part is usually also called "debugging".

Tuesday, January 20, 2009

Wednesday, December 17, 2008

Agilefant : Is it SPRING or what?

Suppose you have a web page.
Suppose the web page is a SCRUM management web application.
Suppose it's called Agilefant, made by the guys over at TKK, Helsinki's Technical Highschool / University. Here is the project page
http://www.agilefant.org/wiki/display/AEF/Agilefant+Home.

Now suppose we would like to integrate the most important information of this very usefull application into our Information Radiator. How would we do it?
We would have to handle a few minor issues first, like access for an example. We don't want to just "remind" the host that would connect to our Agilefant server with the available option. We want to create a new session every time we need to access it.
Agilefant is based on Spring(http://www.springframework.org). Spring is an application framework. Google it if you want more information, I am surely not crazy enough to dive into it's deepness - and trust me, it's HUGE.
But anyway. Back on track.
Spring, in return, bases its authentication mechanism on Acegi (http://www.acegisecurity.org), Spring's standard authentication sub-framework. Now, Acegi supports various methods of authentication (Form, BASIC, NTLM being the most important ones, but it offers WAY more), but Agilefant provides you only with form-based access, which in cases like ours where you need to leave the door open for automated crawling can be a bit restrictive.

How do we overcome this restriction? Well, Spring handles the authentication through the use of filters, which basically redirect you depending if you supply correct or incorrect credentials. In case the authentication is successfull, the response will contain a JSESSION id in form of a cookie, which hast to be used for later accesses. Which means that we first need to perform a login, fetch the cookie and then fetch our Agilefant informative pages (by providing the cookie) - for example a burndown graph. Since (as mentioned) Agilefant supports only form-based authentication, we have to handle the whole issue at HTTP level.
And here is where the php_http extension for php proofs to be extremely handy. In fact, this library gives you full control on HTTP requests / responses, providing functionality for HTTP requesting / receiving / marshalling and unmarshalling. Wow. You could build a browser in PHP with those functions (has anyone ever been crazy enough to think of that anyway?).

So now the steps to perform (at HTTP level through PHP) are as follows :

a) Supply to the authentication target of Agilefant a valid username/password pair
b) fetch the cookie from the response
c) fetch our desired Agilefant data with the previously obtained cookie
Which, translated to PHP, comes down to a very simple script that looks like this:

header('Content-type: image/png');
$params = array ("j_username" => "yourusername", "j_password" => "yourpassword");
$response = http_post_fields("http://agilefant/agilefant/j_spring_security_check", $params);
$rHeader = http_parse_headers ($response);
$cookies = http_parse_cookie ($rHeader['Set-Cookie']);
$options = Array ('cookies' => $cookies->cookies);
$response = http_get("http://agilefant/agilefant/drawChart.action?iterationId=38", $options);
$rBody = http_parse_message ($response);
echo $rBody->body;

Thursday, December 11, 2008

HTTP Header faking - OR: how to login to a page with PHP

How do I login to a (secured) login page via PHP? It's possible, apparently. What we need is to set up the correct HTTP request, by setting the header and field values.

function do_post_request($url, $data, $optional_headers = null)
{
$params = array('http' => array(
'method' => 'POST',
'content' => $data
));
if (
$optional_headers !== null) {
$params['http']['header'] = $optional_headers;
}
$ctx = stream_context_create($params);
$fp = @fopen($url, 'rb', false, $ctx);
if (!
$fp) {
throw new
Exception("Problem with $url, $php_errormsg");
}
$response = @stream_get_contents($fp);
if (
$response === false) {
throw new
Exception("Problem reading data from $url, $php_errormsg");
}
return
$response;
}

This function (found at
http://netevil.org/blog/2006/nov/http-post-from-php-without-curl)
gives me a PHP entry point. But how do we actually setup the header - what do we need to fake the Session to believe a User inputted some stuff in the login page?