Results for category "Projekte"

9 Articles

Entwickeln mit Scrum/Agilo

Wegen eines privaten Projekts habe ich in den letzten paar Tagen eine kleine Entwicklungsumgebung aufgebaut. Dazu dient mir auf meinem Notebook eine VirtualBox (Ubuntu 10.04, Tomcat, MySQL 5.2, Apache 2, Trac + Agilo, SVN) als Deployment- und Entwicklungsplattform. Die Installation des ganzen Environments erledigte ich recht schnell anhand von http://wiki.ubuntuusers.de/Trac und http://www.agile42.com/cms/pages/download-install/

Nachdem ich mich mit Agilo ein bißchen auseinandersetzte, stellte ich fest, dass das Anlagen von Teams nicht funktionierte, die Fehlermeldung

 An error occurred while getting None from the database: no such table: agilo_sprint

war mehr als eindeutig: bei der Installation von Agilo wurden in meiner Version drei Tabellen schlichtweg nicht erstellt.
Nach kurzer Suche wurde ich fündig und legte mit sqlite3 trac.db die fehlenden Tabellen für die Benutzer manuell an:

CREATE TABLE agilo_team (
  name text,
  description text,
  UNIQUE (name)
);
CREATE TABLE agilo_team_member (
  name text,
  team text,
  description text,
  ts_mon real,
  ts_tue real,
  ts_wed real,
  ts_thu real,
  ts_fri real,
  ts_sat real,
  ts_sun real,
  UNIQUE (name)
);
CREATE TABLE agilo_calendar_entry (
  date integer,
  teammember text,
  hours real,
  UNIQUE (date,teammember)
);

agilo_calendar_entry wurde ebenfalls nicht angelegt, wie ich später feststellte.

Weiterhin stellte ich fest, dass beim Erstellen eines Sprints der Fehler

AttributeError: 'NoneType' object has no attribute 'toordinal'

auftrat. Google sei dank fixte ich das Problem, indem ich bei den Sprint-Daten Start- und Endzeitpunkt manuell eintrug. Anscheinend funktioniert das Feld Duration in days in der Sprint-Administration noch nicht so ganz.

Soweit dazu, eventuell gibt es ja die ein oder andere Person, die ebenfalls über diese beiden Fehler stolpert.

Für mich als Scrum-Neuling – produktiv hatte ich diese Entwicklungsmethode noch nicht eingesetzt – wurde ich beim näheren Betrachten der Optionen von Agilo erst einmal erschlagen. Deshalb folgt hier eine grobe Auflistung der Begrifflichkeiten und Funktionalitäten, wie sie in der Standard-Installation definiert sind.

  • Ticket-Typen
    • Requirement sind Tickets, die auf die Fragen Welches Problem zu lösen ist und warum es zum Problem wird. Requirements sollen SMART (Simple, Measurable, Achievable, Realistic and Traceable) sein. Nachdem ein Requirement angelegt wurde, kann über “Edit” 0..n User Stories zugewiesen werden.
    • User Story ist ein Ticket, das beschreibt was der Benutzer mit dem System erreichen will und warum (Nutzen dieser Funktionalität). Nachdem eine User-Story angelegt ist, kann über “Edit” auf einen neuen Task verwiesen werden. Eine User Story kann 0..n Tasks besitzen.
    • Tasks sind Tickets, die eine Aufgabe, die von einem Team Member zu erledigen ist, detailiert erklärt. Jeder Task soll ausführlich sein und sich auf eine Aufgabe beziehen.
  • Backlog
    • Das Product Backlog beinhaltet die User Stories und darunter jeweils die Requirements, die einer User Story zugeordnet sind.
    • Das Sprint Backlog beinhaltet die Requirements (und die User Story bzw. Tasks die dem Requirement zugewiesen worden sind) und offene Bugs. Es werden nur die Requirements/Tasks angezeigt, die dem Sprint zugewiesen worden sind.
    • Sprint bezeichnet den Zeitraum, in dem mehrere Tasks/Requirements gelöst werden. Im Administrations-Interface müssen jeweils neue Sprints mit Start- und End-Datum angelegt werden.
    • Milestone bezeichnet einen Zeitraum, der wiederum aus mehreren Sprints besteht

Die Frage nach dem “Wie gehe ich nun vor?” ist über oben die dargestellte Struktur eigentlich relativ klar:

  • Anlegen der User Stories (WELCHE Funktionalität wird benötigt um einen Business Value zu erreichen?)
  • Erstellen der Requirements (WELCHE Probleme einer User Story gilt es zu lösen?) und Zuweisen der Requirements an eine User Story
  • Erstellen der zugehörigen Tasks (WAS ist bei einer User Story technisch zu tun?), die einer User Story angehören
  • Erstellen eines Meilensteins. Requirements müssen dem Meilenstein zugewiesen werden
  • Erstellen von ein oder mehreren Sprints. Tasks, User Stories und Bugs müssen den Sprints zugewiesen werden

Eventuell werde ich die nächsten Tage noch den ein oder anderen Blog-Eintrag zu Agilo verfassen. Danke fürs Lesen,

CCC: 26c3 / Bluvert

Den zweiten Tag des CCCs in Berlin habe ich gemeinsam mit Flo besucht. Leider war das komplette BCC restlos überfüllt und man konnte nur schwerlich in den einzelnen Vortragsräumen einen Sitzplatz ergattern. Ich hatte den Eindruck, dass die gesamte Organisation hinter der Veranstaltung mehr als chaotisch ablief. Besonders nervig: das WLAN war – wenn es denn mal erreichbar war – mehr als inperformant.

Ich nutzte deshalb den Montag Abend und brachte Bluvert auf einen aktuellen Stand. Die Änderungen für Version 1.2 werde ich im Laufe der nächsten Tage auf sourceforge.net hochladen:

  • In der config.ini lässt sich nun $cwd als Variable für das aktuelle Arbeitsverzeichnisses verwenden. Damit entfallen einige kleinere Probleme.
  • Es muss nur noch einmalig execute-server.py gestartet werden. Das Script arbeitet nun als funktionierender Daemon.
  • Das Scanning der Geräte innerhalb der Bluetooth-Nachbarschaft geschieht nun ebenfalls über execute-server.py. Es besteht nicht mehr die Notwendigkeit, das Script set-active-bluetooth-devices.sh als Cron-Job auszuführen.
  • Versenden der noch nicht versendeten Nachrichten geschieht nun ebenfalls über einzelne Threads, was sich erheblich auf die Performance auswirkt.
  • Zeitintervall des Scannens nach neuen Geräten und Versenden der Nachrichten lässt sich in der config.ini frei definieren.
  • Script zum Scannen der aktiven Bluetooth-Geräte lässt sich in der config.ini frei definieren.

Let the ants feed the bird: ant-twitter, a Twitter task for Ant

I have learned the last 5 day for business studies and was so bored that I really got happy when I saw the article about a Twitter-Maven-Plugin on entwickler.com yesterday morning.
We still use Ant as building system in our development team so I searched for an Ant task which enables Twitter support. As I did not found any plugin I started to write my own simple task called ant-twitter.

Features

  • Support for URL shortening service bit.ly via bitlyj
  • Support for messages more than 140 characters – the message will be splitted into two or more messages. A small source snippet is taken  from jtwitter – thanks a lot guys!
  • Open source – Apache license
  • It is simple 🙂

Installation

I assume you have already installed Ant-1.70 (1.6x should work although) and configured your Ant working environment. I refer to $ANT_LIB$ which is a directory where your Ant installation can found further JARs (should be appended to your classpath).

  • Download needed packages and extract them to $ANT_LIB$:
  • Create a file twitter4j.properties in your classpath ($ANT_LIB$) and paste the following code into it:
    twitter4j.http.useSSL=true
    twitter4j.debug=false
    

Usage

After you have installed the needed dependencies and upset your configuration you have to edit your build.xml. Put the following taskdef in top of your build file:

<project name="TwitterTestTask" default="main" basedir=".">
  <taskdef name="twitter" classname="de.ecw.ant.twitter.AntTwitterTask"/>

You are now able to use the twitter task in form of

    <twitter message="Hello World from Ant!" username="twitter-username" password="twitter-password" bitlyUsername="bitly-username" bitlyApiKey="bitly-key" enableBitly="false" />

ant-twitter has the following options:

  • message (required, String): Your Twitter tweet
  • username (required, String): Your Twitter screenname
  • password (required, String): Your Twitter password
  • bitlyUsername (optional, required if enableBitly=true, String): Your bit.ly username
  • bitlyApiKey (optional, required if enableBitly=true, String): Your bit.ly API key
  • enableBitly (optional, true|false): Enable bit.ly support

Rautiges 2009-06-07

  • In der letzten Woche habe ich den Adobe AIR Twitter-Client “Spaz” so aufgemöbelt, dass ich damit meine Twicker-Ergebnisse direkt übermitteln kann. Die Sourcen dazu habe ich Funkatron, dem Maintainer von Spaz, zukommen lassen. Damit lässt sich recht einfach demonstrieren, wie sich der Twitter-Client erweitern lässt. Hat bis dato wohl noch keiner gemacht. Vielleicht werde ich in der nächsten Woche noch ein kleines Tutorial dazu schreiben.
  • Mittwoch habe ich im BibaBlog die ganzen alten Artikel überflogen und den vorhandenen Quellcode vernünftig formatiert. Durch verschiedene Syntax-Highlighting-Plugins gab es gewisse Divergenzen in der Darstellung 😉 Außerdem werden die youtube-Videos wieder korrekt dargestellt.
  • Florian hat im Rahmen eines kleines Projekts ein Installationsscript für EFA (Elektronisches Fahrtenbuch für Ruderer) gebaut. Damit wird – ausgehend von einem Ubuntu-Alternate-Install – ein System aufgesetzt, das nur die nötigsten Tools enthält. Besonders cool dabei: Flo hat ein Script geschrieben, dass per udev automatisch erkennt, ob ein USB-Stick angesteckt wurde und wenn dem so ist, wird die Datenbank von EFA über eine Python-GUI gesichert. Lob und Anerkennung, cooles Projekt!
  • Freitag waren die Jungs und ich in Termintor 4. Der Film war an sich ganz cool, auch wenn es einige logische Unstimmigkeiten gab 😉 Die visuellen Effekte waren aber top. Danach machten wir einen kurzen Abstecher im Sausalitos und nisteten uns dann auf der Geburtstagsfeier von Maike ein.
  • Samstag habe ich die Onlineklausur für Mathematisch-logische Grundlagen abgelegt. Die ersten 5 Minuten war ich etwas neben der Spur, konnte mich dann aber fangen und die Aufgaben relativ gut abarbeiten. Als Themen kamen vor: Bestimmung einer Gruppe/Abelsche Gruppe; Beweis des Absorptionsgesetz von Junktoren anhand Wahrheitstabelle (das war easy, ich hoffe, ich hab die Frage auch richtig verstanden 🙂 ); Bestimmen der Endmenge von Mengenoperationen; Entscheiden, ob eine Funktion surjektiv, injektiv oder total ist; Induktiver Beweis einer Formel. An dieser Stelle möchte ich mich noch einmal bei Timo bedanken, der mich in den letzten Wochen tatkräftig bei LaTeX- und Mathe-Fragen unterstützte.
  • Die letzten Tage über habe ich an zwei Songtexten für die Band gearbeitet. Einer der beiden Texte ist bereits fertig, der andere geht dem Ende entgegen. Bei einer der nächsten Bandproben wird es der Öffentlichkeit präsentiert.

Zugriff auf sourceforge.net per SFTP

Heute versuchte ich, mein Bonesim (Boolean Network Simulator) – Projekt auf sourceforge.net hochzuladen. In Ubuntu 9.04 ist leider der WebDAV-Support defekt, so dass der Upload per HTTPS bzw. DAVS nicht funktioniert. Glücklicherweise bietet sourceforge.net auch den Zugriff per SFTP an, so dass mit der URL sftp://frs.sourceforge.net/incoming/u/us/username/uploads die Dateien verschlüsselt übertragen werden können.

oracleDiff – a schema differential tool for Oracle

On friday last week I got a requirement from a co-worker. He asked me for a simple Java based application which compares two different revisions of Oracle database schemas. After some discussion about the sense of this tool, we made a quick requirement and workflow analysis.

  1. User extracts target database schema information with oracleDiff. Only column names and types are required. There is no need for exporting Stored Procedures, Functions, References and so on. Schema information should be stored as XML.
  2. User exports full table data with oracleDiff. The extracted data should be stored as binary or flat file – XML export for large data is too memory intensive.
  3. User does a manual upgrade of the changes with help of Oracle Enterprise Manager Console or other 3rd party tools.
  4. User imports exported data on upgraded database, oracleDiff asks for remapping of columns and informs about column type changes.

Yesterday I started the project and stumbled over two Oracle specific facts:

  1. DESC $TABLENAME does not work in PreparedStatements. You will receive ORA-00900 from Oracle JDBC driver. For retrieving table information you have to use SELECT * FROM user_tab_columns WHERE table_name = ?.
  2. As a long time MySQL programmer I used SHOW TABLES for retrieving all tables of a schema. This will also not work. You have to to use SELECT table_name FROM user_tables.

The current development status extracts the database schema information and compares two schemas. I hope that I will finish the tool within the next two weeks.

h2benchw2csv released / Benutzerfreundlichkeit Teil 2

Wie gestern angekündigt, wurde noch heute Nacht das Projekt freigeschaltet. So eben habe ich die Build-Scripte angepasst und die Version 1.0 auf Sourceforge hochgeladen. h2benchw2csv ist nun unter http://h2benchw2csv.sourceforge.net verfügbar.

Während der Projekteinrichtung musste ich feststellen, dass die Entwickler hinter der GUI von sf.net mittlerweile einiges getan haben. Die Zuweisung der Projektkategorien läuft nun per AJAX. Allerdings konnte ich feststellen, dass man einem Projekt unter Umständen leere Kategorien zuweisen kann.

Weiterhin funktioniert nun die Aktivierung / Deaktivierung von Projekt-Features (Mailing List, Tracker u.s.w.) ebenfalls per AJAX.

Neues sf.net-Projekt: h2benchw2csv / Ergebnis der iSCSI Performance-Tests

Die letzten beiden Tage habe ich unser SAN und das dahinter liegende iSCSI-Geraffel ausführlich mit h2benchw von Heise / c’t getestet. Da ich absolut keine Lust hatte, alle Ergebnisse in den Text-Dateien (waren knapp 20 Files) per Hand in Excel einzutippen, frickelte ich mir kurzerhand ein PHP-Script zusammen, dass mir aus den .txt-Dateien von h2benchw eine große CSV-Datei baut. Diese kann dann wiederum in Excel oder irgendeinem anderen Tabellen eingelesen werden.

Weiterhin unterstützt h2benchw2csv – so der Name des kleinen Scripts – die automatische Umwandlung der .ps-Dateien nach .pdf. Dies geschieht mit Hilfe des PDFCreators, der in der %PATH%-Variable verfügbar sein muss. Gegenwärtig ist h2benchw2csv noch im sf.net Approval State, sollte aber morgen oder übermorgen freigeschaltet werden.

Features:

  • Umwandeln von h2benchw .txt-Ergebnissen in eine CSV-Datei
  • Komplette Inhalte von Verzeichnissen können in der CSV-Datei gespeichert werden
  • Deutsch/Englisch
  • Umwandlung der h2benchw .ps-Dateien mit Hilfe des PDFCreators nach PDF
  • 100% Open Source und Kommandozeile
  • Benötigt wird nur PHP – es wird keine zusätzliche Bibliothek benötigt

Zu den Ergebnissen meiner iSCSI-Performance-Messung ist folgendes zu schreiben:

  1. Round-Robin oder Weighted Path in einem Verbund von 4 Netzwerkkarten auf Client und Server bringen rein gar nichts, wenn sie gemeinsam auf ein Target zugreifen. Die maximale Leserate betrug 75 MByte/s, die maximale Schreibrate 60 MByte/s. Wir gingen eigentlich davon aus, dass mit jeder (Gigabit)-Netzwerkkarte die Performance mitskaliert – also eine NIC: 70 MByte/s, zwei NICs 140 MByte/s u.s.w. Dem ist aber eindeutig nicht so.
  2. Interessant war hingegen, dass bei 4 Targets und Fail Over der Gesamtdurchsatz auf ca. 200 MByte/s beim Lesen und 170 MByte/s beim Schreiben anstieg.
  3. Für mich schaut das nach einem Problem im iSCSI Initiator oder -Treiber aus.
  4. Bonding und Multipath gemeinsam benutzt bringen nichts.
  5. Die Firmware 1.46 des Areca 1231 kann nun vernünftig mit NTP-Servern umgehen – bringt aber keine bessere Performance
  6. FileIO ist beim Schreiben geringfügig schneller als BlockIO (2 MByte/s)
  7. Jumboframes (MTU 9000 auf Windows Server 2003 und 9014 auf DSS) brachten bei uns keinen Performance-Unterschied
  8. Fail Over ist schneller als Weighted Path, Weighted Path ist schneller als Round Robin
  9. Keine der vier Intel-Netzwerkkarten wurde unter Windows Server 2003 zu mehr als 50% ausgelastet. Hier gibt es eventuell auch Treiber-Probleme.
  10. Trotz allem ist unser iSCSI-SAN fix 😉

Vom Zwittern … äh Twittern und sinnlosen Anwendungen – Twitter als semantische Datenbank

Heute habe ich die Messlatte für den Geekfaktor in unserem Büro doch relativ hoch gelegt: Seit einigen Wochen besitze ich einen Twitter-Account um meine Profilneurose und meinen Netzhibitionismus -welch schöner Neologismus- zu befriedigen. Der ursprüngliche Grund war, dass mein Cousin und die Entwickler von QuakeLive twittern. Außerdem kam Marc vor einigen Tagen hinzu.

Wie dem auch sei – bis heute war ich der Meinung, Twitter ist schrott. Was interessiert mich, dass bklynplayboy gerade über das Next Top Model lacht? Die rhetorische Frage beantworte ich mal nicht…

Nach unserem heutigen Kickerspiel im Büro kam mir eine Idee: Warum nicht Twitter als Datenbank nutzen?
Eine konkrete Anwendung hatte ich dafür auch schon. Seit einiger Zeit überlegt das Kicker-Team aus der Firma, ob wir über unsere Spiele Statistik führen. Bisher habe ich mich immer davor gescheut, extra eine Datenbank dafür anzulegen und irgendetwas mit PHP oder Java zusammenzufrickeln. Das ist schließlich 0815 und auf solchen Krams habe ich keine Lust mehr.
Kommen wir zuerst zur Analyse-Phase: Ein Kickerspiel besteht aus mehreren Sätzen und hat immer zwei Teams mit je maximal zwei Spielern. Ein Spiel wird immer mit einem Sieg beendet – unentschieden gibt es nicht. Zu einem Spiel kann man noch ein kurzes Statement abgeben und außerdem muss der Tweet gehasht werden und das war es. In einem Twitter-Post kurz zusammengefasst würde das so aussehen:

CKL:CST 5:4 – Prokuristen können nicht kickern #büro #kickern

CKL und CST sind die Benutzerkürzel der Spieler, Zwei Spieler werden mit Komma getrennt (CKL,MBI:CST,FWE).
An sich ist das Datenformat völlig egal. Theoretisch könnte man für so etwas auch JSON benutzen. Aber egal.

In der nächsten Iteration – ja, mein Nachmittag hatte etwas von Agiler Entwicklung – ging es daran, die richtigen Einträge zu finden. Die API von Twitter beschreibt das recht gut und somit erledigt sich die Suchanfrage nach den Ergebnissen mit dem Aufruf von http://search.twitter.com/search.json?q=from%3Aschakko+%23kickern+%23büro wie von alleine. Zur Info: Es wird nach den Hash #kickern und #büro vom Benutzer “schakko” gesucht. Die Datensätze werden im JSON-Format zurückgegeben.

Damit hatte ich zwei meiner drei Fragen geklärt: Wie sind die Daten zu speichern, wie finde ich die Daten, die ich brauche. Nun folgte für mich der interessanteste Part: Wie verbinde ich mich mit der API von Twitter? Wie schon oben geschrieben, hatte ich auf PHP/Java-Gefrickel keine Lust. Meine Anwendung sollte schließlich nur die Matches der vergangenen Wochen anzeigen und für jeden Spieler und jede Team-Kombination die Statistik anzeigen (gewonne Matches, verlorene Matches, Erfolgsquote). Eine Proxy-Klasse (Service bildet die End-API nach und liegt auf dem selben Server) oder lokaler Routing-Service (Service tunnelt die Anfragen an die End-API) in einer serverseitigen Programmiersprache zu erstellen, wäre Overkill gewesen. Nun wusste ich aber, dass jQuery seit einiger Zeit Cross Domain AJAX beherrscht. Damit ist es über JSONP möglich, AJAX-Anfragen an Hosts zu stellen, die nicht auf dem Server liegen, von wo die JavaScript-Applikation ausgeführt wird. Mit Cross Domain Requests werden Proxy-Klassen oder Routing-Services also unnötig.

Gesagt getan, meine Zutaten für meine Kicker-Applikatin waren gefunden: Twitter durch die Hashtags als semantische Datenbank, jQuery als Framework und somit JavaScript als Programmiersprache und HTML als Ausgabeformat.

An der gesamten Anwendung – inklusive Analyse – programmierte ich knappe 3 Stunden. Mein eigenes Format wandelte ich über eine kurze Regular Expression in die passenden JavaScript-Objekte um.

Der momentane Stand ist, dass die Statistiken in tabellarischer Form mit den obigen Vorgaben pro Spieler oder pro Team dargestellt werden. Wünschenswerte Sachen sind noch:

  • Eintragen der Ergebnisse über ein Formular in der Applikation
  • Sortierung der Tabellen – sollte relativ einfach funktionieren
  • Grafische Auswertung der Statistik anhand von Charts

Diese kleine Anwendung war seit einiger Zeit das agilste und pragmatischste Vorgehen, dass ich an den Tag gelegt habe – weg von alten und zig-mal durchgekauten Pfaden und einfach mal etwas Neues ausprobieren.